mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Add initial support for API versioning (see #3836)
- Generated files are now created when running cef_create_projects or the new version_manager.py tool. These files are still created in the cef/ source tree (same location as before) but Git ignores them due to the generated .gitignore file. - API hashes are committed to Git as a new cef_api_versions.json file. This file is used for both code generation and CEF version calculation (replacing the previous usage of cef_api_hash.h for this purpose). It will be updated by the CEF admin before merging breaking API changes upstream. - As an added benefit to the above, contributor PRs will no longer contain generated code that is susceptible to frequent merge conflicts. - From a code generation perspective, the main difference is that we now use versioned structs (e.g. cef_browser_0_t instead of cef_browser_t) on the libcef (dll/framework) side. Most of the make_*.py tool changes are related to supporting this. - From the client perspective, you can now define CEF_API_VERSION in the project configuration (or get CEF_EXPERIMENTAL by default). This define will change the API exposed in CEF’s include/ and include/capi header files. All client-side targets including libcef_dll_wrapper will need be recompiled when changing this define. - Examples of the new API-related define usage are provided in cef_api_version_test.h, api_version_test_impl.cc and api_version_unittest.cc. To test: - Run `ceftests --gtest_filter=ApiVersionTest.*` - Add `cef_api_version=13300` to GN_DEFINES. Re-run configure, build and ceftests steps. - Repeat with 13301, 13302, 13303 (all supported test versions).
This commit is contained in:
55
.gitignore.in
Normal file
55
.gitignore.in
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
*.gypcmd
|
||||||
|
*.mk
|
||||||
|
*.ncb
|
||||||
|
*.opensdf
|
||||||
|
*.props
|
||||||
|
*.pyc
|
||||||
|
*.rules
|
||||||
|
*.sdf
|
||||||
|
*.sln
|
||||||
|
*.sublime-project
|
||||||
|
*.sublime-workspace
|
||||||
|
*.suo
|
||||||
|
*.targets
|
||||||
|
*.user
|
||||||
|
*.vcproj
|
||||||
|
*.vcxproj
|
||||||
|
*.vcxproj.filters
|
||||||
|
*.vpj
|
||||||
|
*.vpw
|
||||||
|
*.vpwhistu
|
||||||
|
*.vtg
|
||||||
|
*.xcodeproj
|
||||||
|
*.xcworkspace
|
||||||
|
*_proto.xml
|
||||||
|
*_proto_cpp.xml
|
||||||
|
*~
|
||||||
|
!Android.mk
|
||||||
|
.*.sw?
|
||||||
|
.DS_Store
|
||||||
|
.classpath
|
||||||
|
.cproject
|
||||||
|
.gdb_history
|
||||||
|
.gdbinit
|
||||||
|
.landmines
|
||||||
|
.metadata
|
||||||
|
.project
|
||||||
|
.pydevproject
|
||||||
|
.vscode
|
||||||
|
# Settings directory for eclipse
|
||||||
|
/.settings
|
||||||
|
.checkstyle
|
||||||
|
cscope.*
|
||||||
|
Session.vim
|
||||||
|
tags
|
||||||
|
Thumbs.db
|
||||||
|
# IDE's
|
||||||
|
.vs/
|
||||||
|
.kdev4/
|
||||||
|
*.kdev4
|
||||||
|
# CEF generated directories
|
||||||
|
/binary_distrib
|
||||||
|
/docs
|
||||||
|
# CEF generated files
|
||||||
|
.ccls-cache/
|
||||||
|
/cef_api_untracked.json
|
110
BUILD.gn
110
BUILD.gn
@ -360,6 +360,8 @@ if (is_win) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deps = [
|
deps = [
|
||||||
|
":make_version_header",
|
||||||
|
|
||||||
"//components/crash/core/common", # crash_keys
|
"//components/crash/core/common", # crash_keys
|
||||||
|
|
||||||
# Required by chrome_switches.cc
|
# Required by chrome_switches.cc
|
||||||
@ -441,6 +443,7 @@ source_set("libcef_test_support") {
|
|||||||
"libcef/browser/test/test_helpers_impl.cc",
|
"libcef/browser/test/test_helpers_impl.cc",
|
||||||
"libcef/browser/test/test_server_impl.cc",
|
"libcef/browser/test/test_server_impl.cc",
|
||||||
"libcef/browser/test/test_server_impl.h",
|
"libcef/browser/test/test_server_impl.h",
|
||||||
|
"libcef/common/test/api_version_test_impl.cc",
|
||||||
"libcef/common/test/translator_test_impl.cc",
|
"libcef/common/test/translator_test_impl.cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -451,6 +454,10 @@ source_set("libcef_test_support") {
|
|||||||
# Support for UI input events.
|
# Support for UI input events.
|
||||||
"//ui/views:test_support",
|
"//ui/views:test_support",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
configs += [
|
||||||
|
":libcef_includes_config",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -758,6 +765,7 @@ source_set("libcef_static") {
|
|||||||
"libcef/browser/xml_reader_impl.h",
|
"libcef/browser/xml_reader_impl.h",
|
||||||
"libcef/browser/zip_reader_impl.cc",
|
"libcef/browser/zip_reader_impl.cc",
|
||||||
"libcef/browser/zip_reader_impl.h",
|
"libcef/browser/zip_reader_impl.h",
|
||||||
|
"libcef/common/api_version_util.h",
|
||||||
"libcef/common/app_manager.cc",
|
"libcef/common/app_manager.cc",
|
||||||
"libcef/common/app_manager.h",
|
"libcef/common/app_manager.h",
|
||||||
"libcef/common/base_impl.cc",
|
"libcef/common/base_impl.cc",
|
||||||
@ -1159,6 +1167,10 @@ config("libcef_dll_wrapper_config") {
|
|||||||
if (is_mac) {
|
if (is_mac) {
|
||||||
cflags_objcc = [ "-std=c++17" ]
|
cflags_objcc = [ "-std=c++17" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cef_api_version != "") {
|
||||||
|
defines = [ "CEF_API_VERSION=$cef_api_version" ]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# libcef_dll_wrapper target.
|
# libcef_dll_wrapper target.
|
||||||
@ -1245,16 +1257,16 @@ grit("cef_resources") {
|
|||||||
# Helper for generating pack header files.
|
# Helper for generating pack header files.
|
||||||
template("make_pack_header") {
|
template("make_pack_header") {
|
||||||
assert(defined(invoker.header))
|
assert(defined(invoker.header))
|
||||||
|
assert(defined(invoker.inc))
|
||||||
assert(defined(invoker.inputs))
|
assert(defined(invoker.inputs))
|
||||||
|
|
||||||
action("make_pack_header_${target_name}") {
|
action("make_pack_header_${target_name}") {
|
||||||
script = "tools/make_pack_header.py"
|
script = "tools/make_pack_header.py"
|
||||||
|
|
||||||
inputs = invoker.inputs
|
inputs = invoker.inputs
|
||||||
outputs = [ invoker.header ]
|
outputs = [ invoker.header, invoker.inc ]
|
||||||
|
|
||||||
args = rebase_path(outputs, root_build_dir) +
|
args = rebase_path(outputs + inputs, root_build_dir)
|
||||||
rebase_path(inputs, root_build_dir)
|
|
||||||
|
|
||||||
if (defined(invoker.deps)) {
|
if (defined(invoker.deps)) {
|
||||||
deps = invoker.deps
|
deps = invoker.deps
|
||||||
@ -1265,6 +1277,7 @@ template("make_pack_header") {
|
|||||||
# Generate cef_pack_resources.h.
|
# Generate cef_pack_resources.h.
|
||||||
make_pack_header("resources") {
|
make_pack_header("resources") {
|
||||||
header = "$root_out_dir/includes/cef/include/cef_pack_resources.h"
|
header = "$root_out_dir/includes/cef/include/cef_pack_resources.h"
|
||||||
|
inc = "$root_gen_dir/cef/libcef_dll/cef_pack_resources.inc"
|
||||||
inputs = [
|
inputs = [
|
||||||
"$root_gen_dir/base/tracing/protos/grit/tracing_proto_resources.h",
|
"$root_gen_dir/base/tracing/protos/grit/tracing_proto_resources.h",
|
||||||
"$root_gen_dir/cef/grit/cef_resources.h",
|
"$root_gen_dir/cef/grit/cef_resources.h",
|
||||||
@ -1331,6 +1344,7 @@ make_pack_header("resources") {
|
|||||||
# Generate cef_pack_strings.h.
|
# Generate cef_pack_strings.h.
|
||||||
make_pack_header("strings") {
|
make_pack_header("strings") {
|
||||||
header = "$root_out_dir/includes/cef/include/cef_pack_strings.h"
|
header = "$root_out_dir/includes/cef/include/cef_pack_strings.h"
|
||||||
|
inc = "$root_gen_dir/cef/libcef_dll/cef_pack_strings.inc"
|
||||||
inputs = [
|
inputs = [
|
||||||
"$root_gen_dir/cef/grit/cef_strings.h",
|
"$root_gen_dir/cef/grit/cef_strings.h",
|
||||||
"$root_gen_dir/chrome/grit/branded_strings.h",
|
"$root_gen_dir/chrome/grit/branded_strings.h",
|
||||||
@ -1374,26 +1388,39 @@ make_pack_header("strings") {
|
|||||||
# Generate cef_command_ids.h.
|
# Generate cef_command_ids.h.
|
||||||
make_pack_header("command_ids") {
|
make_pack_header("command_ids") {
|
||||||
header = "$root_out_dir/includes/cef/include/cef_command_ids.h"
|
header = "$root_out_dir/includes/cef/include/cef_command_ids.h"
|
||||||
|
inc = "$root_gen_dir/cef/libcef_dll/cef_command_ids.inc"
|
||||||
inputs = [
|
inputs = [
|
||||||
"//chrome/app/chrome_command_ids.h",
|
"//chrome/app/chrome_command_ids.h",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
# Generate cef_api_hash.h.
|
# Generate cef_api_versions.h.
|
||||||
action("make_api_hash_header") {
|
action("make_api_versions_header") {
|
||||||
script = "tools/make_api_hash_header.py"
|
script = "tools/make_api_versions_header.py"
|
||||||
|
|
||||||
# List of all C API files that will be checked for changes by cef_api_hash.py.
|
inputs = [
|
||||||
inputs = gypi_paths2.includes_common_capi +
|
"cef_api_versions.json",
|
||||||
gypi_paths2.includes_linux_capi +
|
"cef_api_untracked.json",
|
||||||
gypi_paths2.includes_mac_capi +
|
]
|
||||||
gypi_paths2.includes_win_capi +
|
outputs = [
|
||||||
gypi_paths2.includes_capi +
|
"$root_out_dir/includes/cef/include/cef_api_versions.h",
|
||||||
gypi_paths.autogen_capi_includes
|
"$root_gen_dir/cef/libcef_dll/cef_api_versions.inc",
|
||||||
include_dir = [ "include" ]
|
]
|
||||||
outputs = [ "$root_out_dir/includes/cef/include/cef_api_hash.h" ]
|
|
||||||
|
|
||||||
args = rebase_path(outputs + include_dir, root_build_dir)
|
args = rebase_path(outputs + inputs, root_build_dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generate cef_version.h.
|
||||||
|
action("make_version_header") {
|
||||||
|
script = "tools/make_version_header.py"
|
||||||
|
|
||||||
|
inputs = [
|
||||||
|
"VERSION.stamp",
|
||||||
|
"//chrome/VERSION",
|
||||||
|
]
|
||||||
|
outputs = [ "$root_out_dir/includes/cef/include/cef_version.h" ]
|
||||||
|
|
||||||
|
args = rebase_path(outputs, root_build_dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
# This no-op action lists args.gn as an output, allowing it to be referenced as
|
# This no-op action lists args.gn as an output, allowing it to be referenced as
|
||||||
@ -1436,7 +1463,8 @@ group("cef_make_headers") {
|
|||||||
":make_pack_header_resources",
|
":make_pack_header_resources",
|
||||||
":make_pack_header_strings",
|
":make_pack_header_strings",
|
||||||
":make_pack_header_command_ids",
|
":make_pack_header_command_ids",
|
||||||
":make_api_hash_header",
|
":make_api_versions_header",
|
||||||
|
":make_version_header",
|
||||||
":make_config_header",
|
":make_config_header",
|
||||||
":make_colorids_header",
|
":make_colorids_header",
|
||||||
]
|
]
|
||||||
@ -1447,6 +1475,28 @@ group("cef_make_headers") {
|
|||||||
# libcef dll/framework target.
|
# libcef dll/framework target.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
libcef_sources_common = includes_common +
|
||||||
|
gypi_paths.autogen_cpp_includes +
|
||||||
|
gypi_paths2.includes_capi +
|
||||||
|
gypi_paths.autogen_capi_includes +
|
||||||
|
gypi_paths.autogen_capi_versions_includes +
|
||||||
|
gypi_paths2.libcef_sources_common +
|
||||||
|
gypi_paths.autogen_library_side + [
|
||||||
|
"$root_gen_dir/cef/libcef_dll/cef_pack_resources.inc",
|
||||||
|
"$root_gen_dir/cef/libcef_dll/cef_pack_strings.inc",
|
||||||
|
"$root_gen_dir/cef/libcef_dll/cef_command_ids.inc",
|
||||||
|
"$root_gen_dir/cef/libcef_dll/cef_api_versions.inc",
|
||||||
|
]
|
||||||
|
|
||||||
|
libcef_deps_common = [
|
||||||
|
":libcef_static",
|
||||||
|
":libcef_test_support",
|
||||||
|
":make_pack_header_resources",
|
||||||
|
":make_pack_header_strings",
|
||||||
|
":make_pack_header_command_ids",
|
||||||
|
":make_api_versions_header",
|
||||||
|
]
|
||||||
|
|
||||||
if (is_mac) {
|
if (is_mac) {
|
||||||
cef_framework_name = "Chromium Embedded Framework"
|
cef_framework_name = "Chromium Embedded Framework"
|
||||||
|
|
||||||
@ -1530,24 +1580,17 @@ if (is_mac) {
|
|||||||
"Resources",
|
"Resources",
|
||||||
]
|
]
|
||||||
|
|
||||||
sources = includes_common +
|
sources = libcef_sources_common + includes_mac
|
||||||
includes_mac +
|
|
||||||
gypi_paths.autogen_cpp_includes +
|
|
||||||
gypi_paths2.includes_capi +
|
|
||||||
gypi_paths.autogen_capi_includes +
|
|
||||||
gypi_paths2.libcef_sources_common +
|
|
||||||
gypi_paths.autogen_library_side
|
|
||||||
|
|
||||||
deps = [
|
deps = libcef_deps_common + [
|
||||||
":cef_framework_angle_binaries",
|
":cef_framework_angle_binaries",
|
||||||
":cef_framework_resources",
|
":cef_framework_resources",
|
||||||
":cef_framework_swiftshader_binaries",
|
":cef_framework_swiftshader_binaries",
|
||||||
":libcef_static",
|
|
||||||
":libcef_test_support",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
configs += [
|
configs += [
|
||||||
":libcef_autogen_config",
|
":libcef_autogen_config",
|
||||||
|
":libcef_includes_config",
|
||||||
]
|
]
|
||||||
|
|
||||||
# We don't link the framework so just use the path from the main executable.
|
# We don't link the framework so just use the path from the main executable.
|
||||||
@ -1586,20 +1629,13 @@ if (is_mac) {
|
|||||||
# Necessary because the libcef_test_support target is testonly.
|
# Necessary because the libcef_test_support target is testonly.
|
||||||
testonly = true
|
testonly = true
|
||||||
|
|
||||||
sources = includes_common +
|
sources = libcef_sources_common
|
||||||
gypi_paths.autogen_cpp_includes +
|
|
||||||
gypi_paths2.includes_capi +
|
|
||||||
gypi_paths.autogen_capi_includes +
|
|
||||||
gypi_paths2.libcef_sources_common +
|
|
||||||
gypi_paths.autogen_library_side
|
|
||||||
|
|
||||||
deps = [
|
deps = libcef_deps_common
|
||||||
":libcef_static",
|
|
||||||
":libcef_test_support",
|
|
||||||
]
|
|
||||||
|
|
||||||
configs += [
|
configs += [
|
||||||
":libcef_autogen_config",
|
":libcef_autogen_config",
|
||||||
|
":libcef_includes_config",
|
||||||
":pdb_larger_than_4gb",
|
":pdb_larger_than_4gb",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
34
cef_api_versions.json
Normal file
34
cef_api_versions.json
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"hashes": {
|
||||||
|
"13300": {
|
||||||
|
"comment": "Added January 07, 2025.",
|
||||||
|
"linux": "f0b073047a026b83e911ba60aa1a83f036d31b0e",
|
||||||
|
"mac": "39c1f7df430aeaf39911147032b266416658c11d",
|
||||||
|
"universal": "dd40c0c97ba3f4a1f4ec53ff64d19fea30217d3d",
|
||||||
|
"windows": "4d97ebe2ed64b448b23625c6bd3943797ac3e137"
|
||||||
|
},
|
||||||
|
"13301": {
|
||||||
|
"comment": "Added January 07, 2025.",
|
||||||
|
"linux": "41f72b80f8a2d00ea8301cda42d37b8fdf0240a5",
|
||||||
|
"mac": "e44f5eb6d634f3d4353f52ff383bf213f3894bbd",
|
||||||
|
"universal": "f7edff150ad480bc2f5cfc85fd6bfa23fbc4a73f",
|
||||||
|
"windows": "130d2eed0662c065a1cee3c782a6d855c63d67e8"
|
||||||
|
},
|
||||||
|
"13302": {
|
||||||
|
"comment": "Added January 07, 2025.",
|
||||||
|
"linux": "2ef9e3f071838f2d7705d144cf66e0f5ae69b32f",
|
||||||
|
"mac": "ec74fb1f9aff97f55882dbb35ba979934c8ab1a7",
|
||||||
|
"universal": "d9c1eedf985ddcd4e9df05f7664b111462d45626",
|
||||||
|
"windows": "f4d05b712907d8d64df80029d9e2e8edbee814ac"
|
||||||
|
},
|
||||||
|
"13303": {
|
||||||
|
"comment": "Added January 07, 2025.",
|
||||||
|
"linux": "397ad962a3049dad4b36b356c8d108f78603de60",
|
||||||
|
"mac": "f7a5c733b8c3cd6fa3a284ce9b307566c6aa5860",
|
||||||
|
"universal": "91d5546d2b3f601ab2453f218a7bd69d2fd39b1b",
|
||||||
|
"windows": "b24722530b6b77bd1a633af5d72088225468eee2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"last": "13303",
|
||||||
|
"min": "13300"
|
||||||
|
}
|
@ -36,7 +36,6 @@
|
|||||||
'include/base/internal/cef_thread_checker_impl.h',
|
'include/base/internal/cef_thread_checker_impl.h',
|
||||||
'include/cef_api_hash.h',
|
'include/cef_api_hash.h',
|
||||||
'include/cef_base.h',
|
'include/cef_base.h',
|
||||||
'include/cef_version.h',
|
|
||||||
'include/internal/cef_export.h',
|
'include/internal/cef_export.h',
|
||||||
'include/internal/cef_ptr.h',
|
'include/internal/cef_ptr.h',
|
||||||
'include/internal/cef_string_wrappers.h',
|
'include/internal/cef_string_wrappers.h',
|
||||||
@ -44,6 +43,8 @@
|
|||||||
'include/internal/cef_types_wrappers.h',
|
'include/internal/cef_types_wrappers.h',
|
||||||
],
|
],
|
||||||
'includes_common_capi': [
|
'includes_common_capi': [
|
||||||
|
'include/cef_id_mappers.h',
|
||||||
|
'include/cef_version_info.h',
|
||||||
'include/internal/cef_dump_without_crashing_internal.h',
|
'include/internal/cef_dump_without_crashing_internal.h',
|
||||||
'include/internal/cef_logging_internal.h',
|
'include/internal/cef_logging_internal.h',
|
||||||
'include/internal/cef_string.h',
|
'include/internal/cef_string.h',
|
||||||
@ -483,6 +484,7 @@
|
|||||||
'tests/ceftests/resources/net/data/ssl/certificates/root_ca_cert.pem',
|
'tests/ceftests/resources/net/data/ssl/certificates/root_ca_cert.pem',
|
||||||
],
|
],
|
||||||
'ceftests_sources_common': [
|
'ceftests_sources_common': [
|
||||||
|
'tests/ceftests/api_version_unittest.cc',
|
||||||
'tests/ceftests/audio_output_unittest.cc',
|
'tests/ceftests/audio_output_unittest.cc',
|
||||||
'tests/ceftests/browser_info_map_unittest.cc',
|
'tests/ceftests/browser_info_map_unittest.cc',
|
||||||
'tests/ceftests/certificate_error_unittest.cc',
|
'tests/ceftests/certificate_error_unittest.cc',
|
||||||
|
@ -69,6 +69,20 @@ list(APPEND CEF_COMPILER_DEFINES
|
|||||||
option(USE_SANDBOX "Enable or disable use of the sandbox." ON)
|
option(USE_SANDBOX "Enable or disable use of the sandbox." ON)
|
||||||
|
|
||||||
|
|
||||||
|
# Optionally configure the CEF API version by adding `-D api_version=XXXXX` to the
|
||||||
|
# cmake command-line where XXXXX is the desired version number. For background see
|
||||||
|
# https://bitbucket.org/chromiumembedded/cef/wiki/ApiVersioning.md
|
||||||
|
if(DEFINED api_version)
|
||||||
|
string(LENGTH "${api_version}" length)
|
||||||
|
if (NOT length EQUAL 5 OR NOT api_version MATCHES "^[0-9]+$")
|
||||||
|
message(FATAL_ERROR "Expected a 5 digit number for api_version, got '${api_version}'")
|
||||||
|
endif()
|
||||||
|
list(APPEND CEF_COMPILER_DEFINES
|
||||||
|
CEF_API_VERSION=${api_version}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Linux configuration.
|
# Linux configuration.
|
||||||
#
|
#
|
||||||
|
@ -85,7 +85,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else // !USING_CHROMIUM_INCLUDES
|
#else // !USING_CHROMIUM_INCLUDES
|
||||||
|
|
||||||
|
#if !defined(GENERATING_CEF_API_HASH)
|
||||||
#include "include/cef_config.h"
|
#include "include/cef_config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// The following is substantially similar to the Chromium implementation.
|
// The following is substantially similar to the Chromium implementation.
|
||||||
// If the Chromium implementation diverges the below implementation should be
|
// If the Chromium implementation diverges the below implementation should be
|
||||||
|
@ -44,62 +44,54 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
///
|
///
|
||||||
// All ref-counted framework structures must include this structure first.
|
/// All ref-counted framework structures must include this structure first.
|
||||||
///
|
///
|
||||||
typedef struct _cef_base_ref_counted_t {
|
typedef struct _cef_base_ref_counted_t {
|
||||||
///
|
///
|
||||||
// Size of the data structure.
|
/// Size of the data structure.
|
||||||
///
|
///
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
///
|
///
|
||||||
// Called to increment the reference count for the object. Should be called
|
/// Called to increment the reference count for the object. Should be called
|
||||||
// for every new copy of a pointer to a given object.
|
/// for every new copy of a pointer to a given object.
|
||||||
///
|
///
|
||||||
void(CEF_CALLBACK* add_ref)(struct _cef_base_ref_counted_t* self);
|
void(CEF_CALLBACK* add_ref)(struct _cef_base_ref_counted_t* self);
|
||||||
|
|
||||||
///
|
///
|
||||||
// Called to decrement the reference count for the object. If the reference
|
/// Called to decrement the reference count for the object. If the reference
|
||||||
// count falls to 0 the object should self-delete. Returns true (1) if the
|
/// count falls to 0 the object should self-delete. Returns true (1) if the
|
||||||
// resulting reference count is 0.
|
/// resulting reference count is 0.
|
||||||
///
|
///
|
||||||
int(CEF_CALLBACK* release)(struct _cef_base_ref_counted_t* self);
|
int(CEF_CALLBACK* release)(struct _cef_base_ref_counted_t* self);
|
||||||
|
|
||||||
///
|
///
|
||||||
// Returns true (1) if the current reference count is 1.
|
/// Returns true (1) if the current reference count is 1.
|
||||||
///
|
///
|
||||||
int(CEF_CALLBACK* has_one_ref)(struct _cef_base_ref_counted_t* self);
|
int(CEF_CALLBACK* has_one_ref)(struct _cef_base_ref_counted_t* self);
|
||||||
|
|
||||||
///
|
///
|
||||||
// Returns true (1) if the current reference count is at least 1.
|
/// Returns true (1) if the current reference count is at least 1.
|
||||||
///
|
///
|
||||||
int(CEF_CALLBACK* has_at_least_one_ref)(struct _cef_base_ref_counted_t* self);
|
int(CEF_CALLBACK* has_at_least_one_ref)(struct _cef_base_ref_counted_t* self);
|
||||||
} cef_base_ref_counted_t;
|
} cef_base_ref_counted_t;
|
||||||
|
|
||||||
///
|
///
|
||||||
// All scoped framework structures must include this structure first.
|
/// All scoped framework structures must include this structure first.
|
||||||
///
|
///
|
||||||
typedef struct _cef_base_scoped_t {
|
typedef struct _cef_base_scoped_t {
|
||||||
///
|
///
|
||||||
// Size of the data structure.
|
/// Size of the data structure.
|
||||||
///
|
///
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
///
|
///
|
||||||
// Called to delete this object. May be NULL if the object is not owned.
|
/// Called to delete this object. May be NULL if the object is not owned.
|
||||||
///
|
///
|
||||||
void(CEF_CALLBACK* del)(struct _cef_base_scoped_t* self);
|
void(CEF_CALLBACK* del)(struct _cef_base_scoped_t* self);
|
||||||
|
|
||||||
} cef_base_scoped_t;
|
} cef_base_scoped_t;
|
||||||
|
|
||||||
// Check that the structure |s|, which is defined with a size_t member at the
|
|
||||||
// top, is large enough to contain the specified member |f|.
|
|
||||||
#define CEF_MEMBER_EXISTS(s, f) \
|
|
||||||
((intptr_t) & \
|
|
||||||
((s)->f) - (intptr_t)(s) + sizeof((s)->f) <= *reinterpret_cast<size_t*>(s))
|
|
||||||
|
|
||||||
#define CEF_MEMBER_MISSING(s, f) (!CEF_MEMBER_EXISTS(s, f) || !((s)->f))
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -27,45 +27,124 @@
|
|||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
// ---------------------------------------------------------------------------
|
// Versions are managed using the version_manager.py tool. For usage details
|
||||||
//
|
// see https://bitbucket.org/chromiumembedded/cef/wiki/ApiVersioning.md
|
||||||
// This file was generated by the make_api_hash_header.py tool.
|
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef CEF_INCLUDE_API_HASH_H_
|
#ifndef CEF_INCLUDE_CEF_API_HASH_H_
|
||||||
#define CEF_INCLUDE_API_HASH_H_
|
#define CEF_INCLUDE_CEF_API_HASH_H_
|
||||||
|
|
||||||
#include "include/internal/cef_export.h"
|
#include "include/internal/cef_export.h"
|
||||||
|
|
||||||
// The API hash is created by analyzing CEF header files for C API type
|
#if !defined(GENERATING_CEF_API_HASH)
|
||||||
// definitions. The hash value will change when header files are modified in a
|
#include "include/cef_api_versions.h"
|
||||||
// way that may cause binary incompatibility with other builds. The universal
|
|
||||||
// hash value will change if any platform is affected whereas the platform hash
|
|
||||||
// values will change only if that particular platform is affected.
|
|
||||||
#define CEF_API_HASH_UNIVERSAL "e52a54bfb4cfc13366fe52766756180fc7d3d1b2"
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
#define CEF_API_HASH_PLATFORM "ce7bfedc905e90407eb975eebf2f419a347b27cd"
|
|
||||||
#elif defined(OS_MAC)
|
|
||||||
#define CEF_API_HASH_PLATFORM "8bb21c09270905fe64b8c31f744e0cbf7bc39ff5"
|
|
||||||
#elif defined(OS_LINUX)
|
|
||||||
#define CEF_API_HASH_PLATFORM "a8198f66f731c8ac91bba1e45847807bffca7b01"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Experimental CEF API. Experimental API is unversioned, meaning that it is
|
||||||
|
// excluded (compiled out) when clients explicitly set the CEF_API_VERSION
|
||||||
|
// value in their project configuration. Experimental API is not back/forward
|
||||||
|
// compatible with different CEF versions.
|
||||||
|
#define CEF_API_VERSION_EXPERIMENTAL 999999
|
||||||
|
|
||||||
|
// Placeholder for the next CEF version currently under development. This is a
|
||||||
|
// temporary value that must be replaced with the actual next version number
|
||||||
|
// (output of running `version_manager.py -n`) prior to upstream merge. As an
|
||||||
|
// added reminder, use of this value will cause version_manager.py to fail when
|
||||||
|
// computing hashes for explicit API versions. When adding new API consider
|
||||||
|
// using CEF_API_VERSION_EXPERIMENTAL instead.
|
||||||
|
#if !defined(CEF_API_VERSION_NEXT)
|
||||||
|
#define CEF_API_VERSION_NEXT 999998
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Shorter versions of the above for convenience use in comparison macros.
|
||||||
|
#define CEF_NEXT CEF_API_VERSION_NEXT
|
||||||
|
#define CEF_EXPERIMENTAL CEF_API_VERSION_EXPERIMENTAL
|
||||||
|
|
||||||
|
// API version that will be compiled client-side. The experimental (unversioned)
|
||||||
|
// API is selected by default. Clients can set the CEF_API_VERSION value in
|
||||||
|
// their project configuration to configure an explicit API version. Unlike
|
||||||
|
// the experimental API, explicit API versions are back/forward compatible with
|
||||||
|
// a specific range of CEF versions.
|
||||||
|
#if !defined(CEF_API_VERSION)
|
||||||
|
#define CEF_API_VERSION CEF_API_VERSION_EXPERIMENTAL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(GENERATING_CEF_API_HASH)
|
||||||
|
#if CEF_API_VERSION < CEF_API_VERSION_MIN || \
|
||||||
|
(CEF_API_VERSION > CEF_API_VERSION_LAST && CEF_API_VERSION != CEF_NEXT && \
|
||||||
|
CEF_API_VERSION != CEF_EXPERIMENTAL)
|
||||||
|
#error Building with unsupported CEF_API_VERSION value
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _CEF_AH_PASTE(a, b, c) a##_##b##_##c
|
||||||
|
#define _CEF_AH_EVAL(a, b, c) _CEF_AH_PASTE(a, b, c)
|
||||||
|
#define _CEF_AH_DECLARE(version, suffix) \
|
||||||
|
_CEF_AH_EVAL(CEF_API_HASH, version, suffix)
|
||||||
|
|
||||||
|
// API hashes for the selected CEF_API_VERSION. API hashes are created for
|
||||||
|
// each version by analyzing CEF header files for C API type definitions. The
|
||||||
|
// hash value will change when header files are modified in a way that may
|
||||||
|
// cause binary incompatibility with other builds. The universal hash value
|
||||||
|
// will change if any platform is affected whereas the platform hash values
|
||||||
|
// will change only if that particular platform is affected.
|
||||||
|
#define CEF_API_HASH_UNIVERSAL _CEF_AH_DECLARE(CEF_API_VERSION, UNIVERSAL)
|
||||||
|
#define CEF_API_HASH_PLATFORM _CEF_AH_DECLARE(CEF_API_VERSION, PLATFORM)
|
||||||
|
|
||||||
|
#if defined(BUILDING_CEF_SHARED)
|
||||||
|
|
||||||
|
#define _CEF_AV_LT(v) 1
|
||||||
|
#define _CEF_AV_GE(v) 1
|
||||||
|
|
||||||
|
#else // !defined(BUILDING_CEF_SHARED)
|
||||||
|
|
||||||
|
#define _CEF_AV_CMP(v, op) (CEF_API_VERSION op v)
|
||||||
|
|
||||||
|
#define _CEF_AV_LT(v) _CEF_AV_CMP(v, <)
|
||||||
|
#define _CEF_AV_GE(v) _CEF_AV_CMP(v, >=)
|
||||||
|
|
||||||
|
#endif // !defined(BUILDING_CEF_SHARED)
|
||||||
|
|
||||||
|
///
|
||||||
|
/// API was added in the specified version.
|
||||||
|
///
|
||||||
|
#define CEF_API_ADDED(v) _CEF_AV_GE(v)
|
||||||
|
|
||||||
|
///
|
||||||
|
/// API was removed in the specified version.
|
||||||
|
///
|
||||||
|
#define CEF_API_REMOVED(v) _CEF_AV_LT(v)
|
||||||
|
|
||||||
|
///
|
||||||
|
/// API exists only in the specified version range.
|
||||||
|
///
|
||||||
|
#define CEF_API_RANGE(va, vr) (_CEF_AV_GE(va) && _CEF_AV_LT(vr))
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
///
|
///
|
||||||
// Returns CEF API hashes for the libcef library. The returned string is owned
|
/// Configures the CEF API version and returns API hashes for the libcef
|
||||||
// by the library and should not be freed. The |entry| parameter describes which
|
/// library. The returned string is owned by the library and should not be
|
||||||
// hash value will be returned:
|
/// freed. The |version| parameter should be CEF_API_VERSION and any changes to
|
||||||
// 0 - CEF_API_HASH_PLATFORM
|
/// this value will be ignored after the first call to this method. The |entry|
|
||||||
// 1 - CEF_API_HASH_UNIVERSAL
|
/// parameter describes which hash value will be returned:
|
||||||
// 2 - CEF_COMMIT_HASH (from cef_version.h)
|
|
||||||
///
|
///
|
||||||
CEF_EXPORT const char* cef_api_hash(int entry);
|
/// 0 - CEF_API_HASH_PLATFORM
|
||||||
|
/// 1 - CEF_API_HASH_UNIVERSAL
|
||||||
|
/// 2 - CEF_COMMIT_HASH (from cef_version.h)
|
||||||
|
///
|
||||||
|
CEF_EXPORT const char* cef_api_hash(int version, int entry);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns the CEF API version that was configured by the first call to
|
||||||
|
/// cef_api_hash().
|
||||||
|
///
|
||||||
|
CEF_EXPORT int cef_api_version();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif // CEF_INCLUDE_API_HASH_H_
|
|
||||||
|
#endif // CEF_INCLUDE_CEF_API_HASH_H_
|
||||||
|
@ -1022,17 +1022,21 @@ class CefBrowserHost : public virtual CefBaseRefCounted {
|
|||||||
virtual void ExitFullscreen(bool will_cause_resize) = 0;
|
virtual void ExitFullscreen(bool will_cause_resize) = 0;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns true if a Chrome command is supported and enabled. Values for
|
/// Returns true if a Chrome command is supported and enabled. Use the
|
||||||
/// |command_id| can be found in the cef_command_ids.h file. This method can
|
/// cef_id_for_command_id_name() function for version-safe mapping of command
|
||||||
/// only be called on the UI thread. Only used with Chrome style.
|
/// IDC names from cef_command_ids.h to version-specific numerical
|
||||||
|
/// |command_id| values. This method can only be called on the UI thread. Only
|
||||||
|
/// used with Chrome style.
|
||||||
///
|
///
|
||||||
/*--cef()--*/
|
/*--cef()--*/
|
||||||
virtual bool CanExecuteChromeCommand(int command_id) = 0;
|
virtual bool CanExecuteChromeCommand(int command_id) = 0;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Execute a Chrome command. Values for |command_id| can be found in the
|
/// Execute a Chrome command. Use the cef_id_for_command_id_name()
|
||||||
/// cef_command_ids.h file. |disposition| provides information about the
|
/// function for version-safe mapping of command IDC names from
|
||||||
/// intended command target. Only used with Chrome style.
|
/// cef_command_ids.h to version-specific numerical |command_id| values.
|
||||||
|
/// |disposition| provides information about the intended command target. Only
|
||||||
|
/// used with Chrome style.
|
||||||
///
|
///
|
||||||
/*--cef()--*/
|
/*--cef()--*/
|
||||||
virtual void ExecuteChromeCommand(
|
virtual void ExecuteChromeCommand(
|
||||||
|
@ -50,12 +50,13 @@ class CefCommandHandler : public virtual CefBaseRefCounted {
|
|||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
/// Called to execute a Chrome command triggered via menu selection or
|
/// Called to execute a Chrome command triggered via menu selection or
|
||||||
/// keyboard shortcut. Values for |command_id| can be found in the
|
/// keyboard shortcut. Use the cef_id_for_command_id_name()
|
||||||
/// cef_command_ids.h file. |disposition| provides information about the
|
/// function for version-safe mapping of command IDC names from
|
||||||
/// intended command target. Return true if the command was handled or false
|
/// cef_command_ids.h to version-specific numerical |command_id| values.
|
||||||
/// for the default implementation. For context menu commands this will be
|
/// |disposition| provides information about the intended command target.
|
||||||
/// called after CefContextMenuHandler::OnContextMenuCommand. Only used with
|
/// Return true if the command was handled or false for the default
|
||||||
/// Chrome style.
|
/// implementation. For context menu commands this will be called after
|
||||||
|
/// CefContextMenuHandler::OnContextMenuCommand. Only used with Chrome style.
|
||||||
///
|
///
|
||||||
/*--cef()--*/
|
/*--cef()--*/
|
||||||
virtual bool OnChromeCommand(CefRefPtr<CefBrowser> browser,
|
virtual bool OnChromeCommand(CefRefPtr<CefBrowser> browser,
|
||||||
@ -65,9 +66,11 @@ class CefCommandHandler : public virtual CefBaseRefCounted {
|
|||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Called to check if a Chrome app menu item should be visible. Values for
|
/// Called to check if a Chrome app menu item should be visible. Use the
|
||||||
/// |command_id| can be found in the cef_command_ids.h file. Only called for
|
/// cef_id_for_command_id_name() function for version-safe mapping of command
|
||||||
/// menu items that would be visible by default. Only used with Chrome style.
|
/// IDC names from cef_command_ids.h to version-specific numerical
|
||||||
|
/// |command_id| values. Only called for menu items that would be visible by
|
||||||
|
/// default. Only used with Chrome style.
|
||||||
///
|
///
|
||||||
/*--cef()--*/
|
/*--cef()--*/
|
||||||
virtual bool IsChromeAppMenuItemVisible(CefRefPtr<CefBrowser> browser,
|
virtual bool IsChromeAppMenuItemVisible(CefRefPtr<CefBrowser> browser,
|
||||||
@ -76,9 +79,11 @@ class CefCommandHandler : public virtual CefBaseRefCounted {
|
|||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Called to check if a Chrome app menu item should be enabled. Values for
|
/// Called to check if a Chrome app menu item should be enabled. Use the
|
||||||
/// |command_id| can be found in the cef_command_ids.h file. Only called for
|
/// cef_id_for_command_id_name() function for version-safe mapping of command
|
||||||
/// menu items that would be enabled by default. Only used with Chrome style.
|
/// IDC names from cef_command_ids.h to version-specific numerical
|
||||||
|
/// |command_id| values. Only called for menu items that would be enabled by
|
||||||
|
/// default. Only used with Chrome style.
|
||||||
///
|
///
|
||||||
/*--cef()--*/
|
/*--cef()--*/
|
||||||
virtual bool IsChromeAppMenuItemEnabled(CefRefPtr<CefBrowser> browser,
|
virtual bool IsChromeAppMenuItemEnabled(CefRefPtr<CefBrowser> browser,
|
||||||
|
89
include/cef_id_mappers.h
Normal file
89
include/cef_id_mappers.h
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
// Copyright (c) 2025 Marshall A. Greenblatt. All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the name Chromium Embedded
|
||||||
|
// Framework nor the names of its contributors may be used to endorse
|
||||||
|
// or promote products derived from this software without specific prior
|
||||||
|
// written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#ifndef CEF_INCLUDE_CEF_ID_MAPPERS_H_
|
||||||
|
#define CEF_INCLUDE_CEF_ID_MAPPERS_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Helper for declaring a static IDR variable.
|
||||||
|
///
|
||||||
|
#define CEF_DECLARE_PACK_RESOURCE_ID(name) \
|
||||||
|
static const int name = cef_id_for_pack_resource_name(#name)
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Helper for declaring a static IDS variable.
|
||||||
|
///
|
||||||
|
#define CEF_DECLARE_PACK_STRING_ID(name) \
|
||||||
|
static const int name = cef_id_for_pack_string_name(#name)
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Helper for declaring a static IDC variable.
|
||||||
|
///
|
||||||
|
#define CEF_DECLARE_COMMAND_ID(name) \
|
||||||
|
static const int name = cef_id_for_command_id_name(#name)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "include/internal/cef_export.h"
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns the numeric ID value for an IDR |name| from cef_pack_resources.h or
|
||||||
|
/// -1 if |name| is unrecognized by the current CEF/Chromium build. This
|
||||||
|
/// function provides version-safe mapping of resource IDR names to
|
||||||
|
/// version-specific numeric ID values. Numeric ID values are likely to change
|
||||||
|
/// across CEF/Chromium versions but names generally remain the same.
|
||||||
|
///
|
||||||
|
CEF_EXPORT int cef_id_for_pack_resource_name(const char* name);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns the numeric ID value for an IDS |name| from cef_pack_strings.h or -1
|
||||||
|
/// if |name| is unrecognized by the current CEF/Chromium build. This function
|
||||||
|
/// provides version-safe mapping of string IDS names to version-specific
|
||||||
|
/// numeric ID values. Numeric ID values are likely to change across
|
||||||
|
/// CEF/Chromium versions but names generally remain the same.
|
||||||
|
///
|
||||||
|
CEF_EXPORT int cef_id_for_pack_string_name(const char* name);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns the numeric ID value for an IDC |name| from cef_command_ids.h or -1
|
||||||
|
/// if |name| is unrecognized by the current CEF/Chromium build. This function
|
||||||
|
/// provides version-safe mapping of command IDC names to version-specific
|
||||||
|
/// numeric ID values. Numeric ID values are likely to change across
|
||||||
|
/// CEF/Chromium versions but names generally remain the same.
|
||||||
|
///
|
||||||
|
CEF_EXPORT int cef_id_for_command_id_name(const char* name);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // CEF_INCLUDE_CEF_ID_MAPPERS_H_
|
@ -61,16 +61,19 @@ class CefResourceBundle : public virtual CefBaseRefCounted {
|
|||||||
|
|
||||||
///
|
///
|
||||||
/// Returns the localized string for the specified |string_id| or an empty
|
/// Returns the localized string for the specified |string_id| or an empty
|
||||||
/// string if the value is not found. Include cef_pack_strings.h for a listing
|
/// string if the value is not found. Use the cef_id_for_pack_string_name()
|
||||||
/// of valid string ID values.
|
/// function for version-safe mapping of string IDS names from
|
||||||
|
/// cef_pack_strings.h to version-specific numerical |string_id| values.
|
||||||
///
|
///
|
||||||
/*--cef()--*/
|
/*--cef()--*/
|
||||||
virtual CefString GetLocalizedString(int string_id) = 0;
|
virtual CefString GetLocalizedString(int string_id) = 0;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns a CefBinaryValue containing the decompressed contents of the
|
/// Returns a CefBinaryValue containing the decompressed contents of the
|
||||||
/// specified scale independent |resource_id| or NULL if not found. Include
|
/// specified scale independent |resource_id| or NULL if not found. Use the
|
||||||
/// cef_pack_resources.h for a listing of valid resource ID values.
|
/// cef_id_for_pack_resource_name() function for version-safe mapping of
|
||||||
|
/// resource IDR names from cef_pack_resources.h to version-specific numerical
|
||||||
|
/// |resource_id| values.
|
||||||
///
|
///
|
||||||
/*--cef()--*/
|
/*--cef()--*/
|
||||||
virtual CefRefPtr<CefBinaryValue> GetDataResource(int resource_id) = 0;
|
virtual CefRefPtr<CefBinaryValue> GetDataResource(int resource_id) = 0;
|
||||||
@ -79,8 +82,10 @@ class CefResourceBundle : public virtual CefBaseRefCounted {
|
|||||||
/// Returns a CefBinaryValue containing the decompressed contents of the
|
/// Returns a CefBinaryValue containing the decompressed contents of the
|
||||||
/// specified |resource_id| nearest the scale factor |scale_factor| or NULL if
|
/// specified |resource_id| nearest the scale factor |scale_factor| or NULL if
|
||||||
/// not found. Use a |scale_factor| value of SCALE_FACTOR_NONE for scale
|
/// not found. Use a |scale_factor| value of SCALE_FACTOR_NONE for scale
|
||||||
/// independent resources or call GetDataResource instead.Include
|
/// independent resources or call GetDataResource instead. Use the
|
||||||
/// cef_pack_resources.h for a listing of valid resource ID values.
|
/// cef_id_for_pack_resource_name() function for version-safe mapping of
|
||||||
|
/// resource IDR names from cef_pack_resources.h to version-specific numerical
|
||||||
|
/// |resource_id| values.
|
||||||
///
|
///
|
||||||
/*--cef()--*/
|
/*--cef()--*/
|
||||||
virtual CefRefPtr<CefBinaryValue> GetDataResourceForScale(
|
virtual CefRefPtr<CefBinaryValue> GetDataResourceForScale(
|
||||||
|
@ -53,8 +53,10 @@ class CefResourceBundleHandler : public virtual CefBaseRefCounted {
|
|||||||
///
|
///
|
||||||
/// Called to retrieve a localized translation for the specified |string_id|.
|
/// Called to retrieve a localized translation for the specified |string_id|.
|
||||||
/// To provide the translation set |string| to the translation string and
|
/// To provide the translation set |string| to the translation string and
|
||||||
/// return true. To use the default translation return false. Include
|
/// return true. To use the default translation return false. Use the
|
||||||
/// cef_pack_strings.h for a listing of valid string ID values.
|
/// cef_id_for_pack_string_name() function for version-safe mapping of string
|
||||||
|
/// IDS names from cef_pack_strings.h to version-specific numerical
|
||||||
|
/// |string_id| values.
|
||||||
///
|
///
|
||||||
/*--cef()--*/
|
/*--cef()--*/
|
||||||
virtual bool GetLocalizedString(int string_id, CefString& string) = 0;
|
virtual bool GetLocalizedString(int string_id, CefString& string) = 0;
|
||||||
@ -64,8 +66,9 @@ class CefResourceBundleHandler : public virtual CefBaseRefCounted {
|
|||||||
/// To provide the resource data set |data| and |data_size| to the data
|
/// To provide the resource data set |data| and |data_size| to the data
|
||||||
/// pointer and size respectively and return true. To use the default resource
|
/// pointer and size respectively and return true. To use the default resource
|
||||||
/// data return false. The resource data will not be copied and must remain
|
/// data return false. The resource data will not be copied and must remain
|
||||||
/// resident in memory. Include cef_pack_resources.h for a listing of valid
|
/// resident in memory. Use the cef_id_for_pack_resource_name() function for
|
||||||
/// resource ID values.
|
/// version-safe mapping of resource IDR names from cef_pack_resources.h to
|
||||||
|
/// version-specific numerical |resource_id| values.
|
||||||
///
|
///
|
||||||
/*--cef()--*/
|
/*--cef()--*/
|
||||||
virtual bool GetDataResource(int resource_id,
|
virtual bool GetDataResource(int resource_id,
|
||||||
@ -77,8 +80,10 @@ class CefResourceBundleHandler : public virtual CefBaseRefCounted {
|
|||||||
/// factor |scale_factor|. To provide the resource data set |data| and
|
/// factor |scale_factor|. To provide the resource data set |data| and
|
||||||
/// |data_size| to the data pointer and size respectively and return true. To
|
/// |data_size| to the data pointer and size respectively and return true. To
|
||||||
/// use the default resource data return false. The resource data will not be
|
/// use the default resource data return false. The resource data will not be
|
||||||
/// copied and must remain resident in memory. Include cef_pack_resources.h
|
/// copied and must remain resident in memory. Use the
|
||||||
/// for a listing of valid resource ID values.
|
/// cef_id_for_pack_resource_name() function for version-safe mapping of
|
||||||
|
/// resource IDR names from cef_pack_resources.h to version-specific numerical
|
||||||
|
/// |resource_id| values.
|
||||||
///
|
///
|
||||||
/*--cef()--*/
|
/*--cef()--*/
|
||||||
virtual bool GetDataResourceForScale(int resource_id,
|
virtual bool GetDataResourceForScale(int resource_id,
|
||||||
|
62
include/cef_version_info.h
Normal file
62
include/cef_version_info.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
// Copyright (c) 2024 Marshall A. Greenblatt. All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the name Chromium Embedded
|
||||||
|
// Framework nor the names of its contributors may be used to endorse
|
||||||
|
// or promote products derived from this software without specific prior
|
||||||
|
// written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#ifndef CEF_INCLUDE_CEF_VERSION_INFO_H_
|
||||||
|
#define CEF_INCLUDE_CEF_VERSION_INFO_H_
|
||||||
|
|
||||||
|
#include "include/internal/cef_export.h"
|
||||||
|
|
||||||
|
#if !defined(GENERATING_CEF_API_HASH)
|
||||||
|
#include "include/cef_version.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns CEF version information for the libcef library. The |entry|
|
||||||
|
/// parameter describes which version component will be returned:
|
||||||
|
///
|
||||||
|
/// 0 - CEF_VERSION_MAJOR
|
||||||
|
/// 1 - CEF_VERSION_MINOR
|
||||||
|
/// 2 - CEF_VERSION_PATCH
|
||||||
|
/// 3 - CEF_COMMIT_NUMBER
|
||||||
|
/// 4 - CHROME_VERSION_MAJOR
|
||||||
|
/// 5 - CHROME_VERSION_MINOR
|
||||||
|
/// 6 - CHROME_VERSION_BUILD
|
||||||
|
/// 7 - CHROME_VERSION_PATCH
|
||||||
|
///
|
||||||
|
CEF_EXPORT int cef_version_info(int entry);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // CEF_INCLUDE_CEF_VERSION_INFO_H_
|
@ -36,9 +36,9 @@
|
|||||||
|
|
||||||
#if defined(COMPILER_MSVC)
|
#if defined(COMPILER_MSVC)
|
||||||
|
|
||||||
#ifdef BUILDING_CEF_SHARED
|
#if defined(BUILDING_CEF_SHARED)
|
||||||
#define CEF_EXPORT __declspec(dllexport)
|
#define CEF_EXPORT __declspec(dllexport)
|
||||||
#elif USING_CEF_SHARED
|
#elif defined(USING_CEF_SHARED)
|
||||||
#define CEF_EXPORT __declspec(dllimport)
|
#define CEF_EXPORT __declspec(dllimport)
|
||||||
#else
|
#else
|
||||||
#define CEF_EXPORT
|
#define CEF_EXPORT
|
||||||
|
1172
include/test/cef_api_version_test.h
Normal file
1172
include/test/cef_api_version_test.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -39,8 +39,8 @@
|
|||||||
// be included from unit test targets.
|
// be included from unit test targets.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef CEF_INCLUDE_TEST_CEF_TEST_H_
|
#ifndef CEF_INCLUDE_TEST_CEF_TRANSLATOR_TEST_H_
|
||||||
#define CEF_INCLUDE_TEST_CEF_TEST_H_
|
#define CEF_INCLUDE_TEST_CEF_TRANSLATOR_TEST_H_
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#if !defined(BUILDING_CEF_SHARED) && !defined(WRAPPING_CEF_SHARED) && \
|
#if !defined(BUILDING_CEF_SHARED) && !defined(WRAPPING_CEF_SHARED) && \
|
||||||
@ -805,4 +805,4 @@ class CefTranslatorTestScopedClientChild
|
|||||||
virtual int GetOtherValue() = 0;
|
virtual int GetOtherValue() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CEF_INCLUDE_TEST_CEF_TEST_H_
|
#endif // CEF_INCLUDE_TEST_CEF_TRANSLATOR_TEST_H_
|
||||||
|
54
libcef/common/api_version_util.h
Normal file
54
libcef/common/api_version_util.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
|
||||||
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef CEF_LIBCEF_COMMON_API_VERSION_UTIL_H_
|
||||||
|
#define CEF_LIBCEF_COMMON_API_VERSION_UTIL_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "base/logging.h"
|
||||||
|
#include "base/notreached.h"
|
||||||
|
#include "cef/include/cef_api_hash.h"
|
||||||
|
|
||||||
|
#define _CEF_RA_CMP(v, op) (cef_api_version() op v)
|
||||||
|
|
||||||
|
#define _CEF_RA_LT(v) _CEF_RA_CMP(v, <)
|
||||||
|
#define _CEF_RA_GE(v) _CEF_RA_CMP(v, >=)
|
||||||
|
|
||||||
|
#define _CEF_RA_CHECK(check) \
|
||||||
|
check << __func__ << " called for invalid API version " << cef_api_version()
|
||||||
|
|
||||||
|
// Helpers for fatally asserting (with [[noreturn]]) that the configured
|
||||||
|
// CEF API version matches expectations.
|
||||||
|
|
||||||
|
// Assert that the specified version-related condition is true.
|
||||||
|
#define CEF_API_ASSERT(condition) _CEF_RA_CHECK(LOG_IF(FATAL, (condition)))
|
||||||
|
|
||||||
|
// Annotate should-be unreachable version-related code.
|
||||||
|
#define CEF_API_NOTREACHED() _CEF_RA_CHECK(NOTREACHED())
|
||||||
|
|
||||||
|
// Assert that API was added in the specified version.
|
||||||
|
// Pair with CEF_API_ADDED usage in CEF header files.
|
||||||
|
#define CEF_API_REQUIRE_ADDED(v) CEF_API_ASSERT(_CEF_RA_LT(v))
|
||||||
|
|
||||||
|
// Assert that API was removed in the specified version.
|
||||||
|
// Pair with CEF_API_REMOVED usage in CEF header files.
|
||||||
|
#define CEF_API_REQUIRE_REMOVED(v) CEF_API_ASSERT(_CEF_RA_GE(v))
|
||||||
|
|
||||||
|
// Assert that API exists only in the specified version range.
|
||||||
|
// Pair with CEF_API_RANGE usage in CEF header files.
|
||||||
|
#define CEF_API_REQUIRE_RANGE(va, vr) \
|
||||||
|
CEF_API_ASSERT(_CEF_RA_LT(va) || _CEF_RA_GE(vr))
|
||||||
|
|
||||||
|
// Helpers for testing the configured CEF API version in conditionals.
|
||||||
|
|
||||||
|
// True if API was added in the specified version.
|
||||||
|
#define CEF_API_IS_ADDED(v) _CEF_RA_GE(v)
|
||||||
|
|
||||||
|
// True if API was removed in the specified version.
|
||||||
|
#define CEF_API_IS_REMOVED(v) _CEF_RA_LT(v)
|
||||||
|
|
||||||
|
// True if API exists only in the specified version range.
|
||||||
|
#define CEF_API_IS_RANGE(va, vr) (_CEF_RA_GE(va) && _CEF_RA_LT(vr))
|
||||||
|
|
||||||
|
#endif // CEF_LIBCEF_COMMON_API_VERSION_UTIL_H_
|
1136
libcef/common/test/api_version_test_impl.cc
Normal file
1136
libcef/common/test/api_version_test_impl.cc
Normal file
File diff suppressed because it is too large
Load Diff
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#include "cef/include/test/cef_translator_test.h"
|
#include "cef/include/test/cef_translator_test.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
class CefTranslatorTestRefPtrLibraryImpl
|
class CefTranslatorTestRefPtrLibraryImpl
|
||||||
: public CefTranslatorTestRefPtrLibrary {
|
: public CefTranslatorTestRefPtrLibrary {
|
||||||
public:
|
public:
|
||||||
@ -18,19 +20,22 @@ class CefTranslatorTestRefPtrLibraryImpl
|
|||||||
|
|
||||||
void SetValue(int value) override { value_ = value; }
|
void SetValue(int value) override { value_ = value; }
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
int value_;
|
int value_;
|
||||||
|
|
||||||
private:
|
|
||||||
IMPLEMENT_REFCOUNTING(CefTranslatorTestRefPtrLibraryImpl);
|
IMPLEMENT_REFCOUNTING(CefTranslatorTestRefPtrLibraryImpl);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// static
|
// static
|
||||||
CefRefPtr<CefTranslatorTestRefPtrLibrary>
|
CefRefPtr<CefTranslatorTestRefPtrLibrary>
|
||||||
CefTranslatorTestRefPtrLibrary::Create(int value) {
|
CefTranslatorTestRefPtrLibrary::Create(int value) {
|
||||||
return new CefTranslatorTestRefPtrLibraryImpl(value);
|
return new CefTranslatorTestRefPtrLibraryImpl(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
class CefTranslatorTestRefPtrLibraryChildImpl
|
class CefTranslatorTestRefPtrLibraryChildImpl
|
||||||
: public CefTranslatorTestRefPtrLibraryChild {
|
: public CefTranslatorTestRefPtrLibraryChild {
|
||||||
public:
|
public:
|
||||||
@ -50,20 +55,23 @@ class CefTranslatorTestRefPtrLibraryChildImpl
|
|||||||
|
|
||||||
void SetOtherValue(int value) override { other_value_ = value; }
|
void SetOtherValue(int value) override { other_value_ = value; }
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
int value_;
|
int value_;
|
||||||
int other_value_;
|
int other_value_;
|
||||||
|
|
||||||
private:
|
|
||||||
IMPLEMENT_REFCOUNTING(CefTranslatorTestRefPtrLibraryChildImpl);
|
IMPLEMENT_REFCOUNTING(CefTranslatorTestRefPtrLibraryChildImpl);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// static
|
// static
|
||||||
CefRefPtr<CefTranslatorTestRefPtrLibraryChild>
|
CefRefPtr<CefTranslatorTestRefPtrLibraryChild>
|
||||||
CefTranslatorTestRefPtrLibraryChild::Create(int value, int other_value) {
|
CefTranslatorTestRefPtrLibraryChild::Create(int value, int other_value) {
|
||||||
return new CefTranslatorTestRefPtrLibraryChildImpl(value, other_value);
|
return new CefTranslatorTestRefPtrLibraryChildImpl(value, other_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
class CefTranslatorTestRefPtrLibraryChildChildImpl
|
class CefTranslatorTestRefPtrLibraryChildChildImpl
|
||||||
: public CefTranslatorTestRefPtrLibraryChildChild {
|
: public CefTranslatorTestRefPtrLibraryChildChild {
|
||||||
public:
|
public:
|
||||||
@ -91,15 +99,16 @@ class CefTranslatorTestRefPtrLibraryChildChildImpl
|
|||||||
|
|
||||||
void SetOtherOtherValue(int value) override { other_other_value_ = value; }
|
void SetOtherOtherValue(int value) override { other_other_value_ = value; }
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
int value_;
|
int value_;
|
||||||
int other_value_;
|
int other_value_;
|
||||||
int other_other_value_;
|
int other_other_value_;
|
||||||
|
|
||||||
private:
|
|
||||||
IMPLEMENT_REFCOUNTING(CefTranslatorTestRefPtrLibraryChildChildImpl);
|
IMPLEMENT_REFCOUNTING(CefTranslatorTestRefPtrLibraryChildChildImpl);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// static
|
// static
|
||||||
CefRefPtr<CefTranslatorTestRefPtrLibraryChildChild>
|
CefRefPtr<CefTranslatorTestRefPtrLibraryChildChild>
|
||||||
CefTranslatorTestRefPtrLibraryChildChild::Create(int value,
|
CefTranslatorTestRefPtrLibraryChildChild::Create(int value,
|
||||||
@ -109,6 +118,8 @@ CefTranslatorTestRefPtrLibraryChildChild::Create(int value,
|
|||||||
other_other_value);
|
other_other_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
class CefTranslatorTestScopedLibraryImpl
|
class CefTranslatorTestScopedLibraryImpl
|
||||||
: public CefTranslatorTestScopedLibrary {
|
: public CefTranslatorTestScopedLibrary {
|
||||||
public:
|
public:
|
||||||
@ -123,10 +134,12 @@ class CefTranslatorTestScopedLibraryImpl
|
|||||||
|
|
||||||
void SetValue(int value) override { value_ = value; }
|
void SetValue(int value) override { value_ = value; }
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
int value_;
|
int value_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// static
|
// static
|
||||||
CefOwnPtr<CefTranslatorTestScopedLibrary>
|
CefOwnPtr<CefTranslatorTestScopedLibrary>
|
||||||
CefTranslatorTestScopedLibrary::Create(int value) {
|
CefTranslatorTestScopedLibrary::Create(int value) {
|
||||||
@ -134,6 +147,8 @@ CefTranslatorTestScopedLibrary::Create(int value) {
|
|||||||
new CefTranslatorTestScopedLibraryImpl(value));
|
new CefTranslatorTestScopedLibraryImpl(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
class CefTranslatorTestScopedLibraryChildImpl
|
class CefTranslatorTestScopedLibraryChildImpl
|
||||||
: public CefTranslatorTestScopedLibraryChild {
|
: public CefTranslatorTestScopedLibraryChild {
|
||||||
public:
|
public:
|
||||||
@ -153,11 +168,13 @@ class CefTranslatorTestScopedLibraryChildImpl
|
|||||||
|
|
||||||
void SetOtherValue(int value) override { other_value_ = value; }
|
void SetOtherValue(int value) override { other_value_ = value; }
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
int value_;
|
int value_;
|
||||||
int other_value_;
|
int other_value_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// static
|
// static
|
||||||
CefOwnPtr<CefTranslatorTestScopedLibraryChild>
|
CefOwnPtr<CefTranslatorTestScopedLibraryChild>
|
||||||
CefTranslatorTestScopedLibraryChild::Create(int value, int other_value) {
|
CefTranslatorTestScopedLibraryChild::Create(int value, int other_value) {
|
||||||
@ -165,6 +182,8 @@ CefTranslatorTestScopedLibraryChild::Create(int value, int other_value) {
|
|||||||
new CefTranslatorTestScopedLibraryChildImpl(value, other_value));
|
new CefTranslatorTestScopedLibraryChildImpl(value, other_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
class CefTranslatorTestScopedLibraryChildChildImpl
|
class CefTranslatorTestScopedLibraryChildChildImpl
|
||||||
: public CefTranslatorTestScopedLibraryChildChild {
|
: public CefTranslatorTestScopedLibraryChildChild {
|
||||||
public:
|
public:
|
||||||
@ -192,12 +211,14 @@ class CefTranslatorTestScopedLibraryChildChildImpl
|
|||||||
|
|
||||||
void SetOtherOtherValue(int value) override { other_other_value_ = value; }
|
void SetOtherOtherValue(int value) override { other_other_value_ = value; }
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
int value_;
|
int value_;
|
||||||
int other_value_;
|
int other_value_;
|
||||||
int other_other_value_;
|
int other_other_value_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// static
|
// static
|
||||||
CefOwnPtr<CefTranslatorTestScopedLibraryChildChild>
|
CefOwnPtr<CefTranslatorTestScopedLibraryChildChild>
|
||||||
CefTranslatorTestScopedLibraryChildChild::Create(int value,
|
CefTranslatorTestScopedLibraryChildChild::Create(int value,
|
||||||
@ -208,6 +229,8 @@ CefTranslatorTestScopedLibraryChildChild::Create(int value,
|
|||||||
other_other_value));
|
other_other_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
class CefTranslatorTestImpl : public CefTranslatorTest {
|
class CefTranslatorTestImpl : public CefTranslatorTest {
|
||||||
public:
|
public:
|
||||||
CefTranslatorTestImpl() = default;
|
CefTranslatorTestImpl() = default;
|
||||||
@ -595,6 +618,8 @@ class CefTranslatorTestImpl : public CefTranslatorTest {
|
|||||||
IMPLEMENT_REFCOUNTING(CefTranslatorTestImpl);
|
IMPLEMENT_REFCOUNTING(CefTranslatorTestImpl);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// static
|
// static
|
||||||
CefRefPtr<CefTranslatorTest> CefTranslatorTest::Create() {
|
CefRefPtr<CefTranslatorTest> CefTranslatorTest::Create() {
|
||||||
return new CefTranslatorTestImpl();
|
return new CefTranslatorTestImpl();
|
||||||
|
@ -11,4 +11,7 @@ declare_args() {
|
|||||||
# FOR OTHER CHROMIUM/CEF BUILD CONFIGURATIONS AS ITS USE MAY HAVE SIGNIFICANT
|
# FOR OTHER CHROMIUM/CEF BUILD CONFIGURATIONS AS ITS USE MAY HAVE SIGNIFICANT
|
||||||
# PERFORMANCE AND/OR SECURITY IMPLICATIONS.
|
# PERFORMANCE AND/OR SECURITY IMPLICATIONS.
|
||||||
is_cef_sandbox_build = false
|
is_cef_sandbox_build = false
|
||||||
|
|
||||||
|
# Optionally configure the CEF API version. This impacts wrapper-side only.
|
||||||
|
cef_api_version = ""
|
||||||
}
|
}
|
||||||
|
@ -23,4 +23,7 @@ class CefBaseRefCountedCppToC
|
|||||||
CefBaseRefCountedCppToC();
|
CefBaseRefCountedCppToC();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr auto CefBaseRefCountedCppToC_Wrap = CefBaseRefCountedCppToC::Wrap;
|
||||||
|
constexpr auto CefBaseRefCountedCppToC_Unwrap = CefBaseRefCountedCppToC::Unwrap;
|
||||||
|
|
||||||
#endif // CEF_LIBCEF_DLL_CPPTOC_BASE_REF_COUNTED_CPPTOC_H_
|
#endif // CEF_LIBCEF_DLL_CPPTOC_BASE_REF_COUNTED_CPPTOC_H_
|
||||||
|
@ -22,4 +22,17 @@ class CefBaseScopedCppToC : public CefCppToCScoped<CefBaseScopedCppToC,
|
|||||||
CefBaseScopedCppToC();
|
CefBaseScopedCppToC();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr auto CefBaseScopedCppToC_WrapOwn = CefBaseScopedCppToC::WrapOwn;
|
||||||
|
constexpr auto CefBaseScopedCppToC_WrapRaw = CefBaseScopedCppToC::WrapRaw;
|
||||||
|
constexpr auto CefBaseScopedCppToC_UnwrapOwn = CefBaseScopedCppToC::UnwrapOwn;
|
||||||
|
constexpr auto CefBaseScopedCppToC_UnwrapRaw = CefBaseScopedCppToC::UnwrapRaw;
|
||||||
|
constexpr auto CefBaseScopedCppToC_GetWrapper = CefBaseScopedCppToC::GetWrapper;
|
||||||
|
|
||||||
|
inline cef_base_scoped_t* CefBaseScopedCppToC_WrapRawAndRelease(
|
||||||
|
CefRawPtr<CefBaseScoped> c) {
|
||||||
|
auto [ownerPtr, structPtr] = CefBaseScopedCppToC_WrapRaw(c);
|
||||||
|
ownerPtr.release();
|
||||||
|
return structPtr;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // CEF_LIBCEF_DLL_CPPTOC_BASE_CPPTOC_H_
|
#endif // CEF_LIBCEF_DLL_CPPTOC_BASE_CPPTOC_H_
|
||||||
|
@ -45,7 +45,8 @@ class CefCppToCRefCounted : public CefBaseRefCounted {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cast our structure to the wrapper structure type.
|
// Cast our structure to the wrapper structure type.
|
||||||
WrapperStruct* wrapperStruct = GetWrapperStruct(s);
|
WrapperStruct* wrapperStruct =
|
||||||
|
GetWrapperStruct(s, /*require_exact_type=*/false);
|
||||||
|
|
||||||
// If the type does not match this object then we need to unwrap as the
|
// If the type does not match this object then we need to unwrap as the
|
||||||
// derived type.
|
// derived type.
|
||||||
@ -68,8 +69,6 @@ class CefCppToCRefCounted : public CefBaseRefCounted {
|
|||||||
static CefRefPtr<BaseName> Get(StructName* s) {
|
static CefRefPtr<BaseName> Get(StructName* s) {
|
||||||
DCHECK(s);
|
DCHECK(s);
|
||||||
WrapperStruct* wrapperStruct = GetWrapperStruct(s);
|
WrapperStruct* wrapperStruct = GetWrapperStruct(s);
|
||||||
// Verify that the wrapper offset was calculated correctly.
|
|
||||||
DCHECK_EQ(kWrapperType, wrapperStruct->type_);
|
|
||||||
return wrapperStruct->object_;
|
return wrapperStruct->object_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,13 +121,21 @@ class CefCppToCRefCounted : public CefBaseRefCounted {
|
|||||||
StructName struct_;
|
StructName struct_;
|
||||||
};
|
};
|
||||||
|
|
||||||
static WrapperStruct* GetWrapperStruct(StructName* s) {
|
static WrapperStruct* GetWrapperStruct(StructName* s,
|
||||||
|
bool require_exact_type = true) {
|
||||||
// Offset using the WrapperStruct size instead of individual member sizes
|
// Offset using the WrapperStruct size instead of individual member sizes
|
||||||
// to avoid problems due to platform/compiler differences in structure
|
// to avoid problems due to platform/compiler differences in structure
|
||||||
// padding.
|
// padding.
|
||||||
return reinterpret_cast<WrapperStruct*>(
|
auto* wrapperStruct = reinterpret_cast<WrapperStruct*>(
|
||||||
reinterpret_cast<char*>(s) -
|
reinterpret_cast<char*>(s) -
|
||||||
(sizeof(WrapperStruct) - sizeof(StructName)));
|
(sizeof(WrapperStruct) - sizeof(StructName)));
|
||||||
|
|
||||||
|
if (require_exact_type) {
|
||||||
|
// Verify that the wrapper offset was calculated correctly.
|
||||||
|
CHECK_EQ(kWrapperType, wrapperStruct->type_);
|
||||||
|
}
|
||||||
|
|
||||||
|
return wrapperStruct;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unwrap as the derived type.
|
// Unwrap as the derived type.
|
||||||
@ -152,9 +159,6 @@ class CefCppToCRefCounted : public CefBaseRefCounted {
|
|||||||
|
|
||||||
WrapperStruct* wrapperStruct =
|
WrapperStruct* wrapperStruct =
|
||||||
GetWrapperStruct(reinterpret_cast<StructName*>(base));
|
GetWrapperStruct(reinterpret_cast<StructName*>(base));
|
||||||
// Verify that the wrapper offset was calculated correctly.
|
|
||||||
DCHECK_EQ(kWrapperType, wrapperStruct->type_);
|
|
||||||
|
|
||||||
wrapperStruct->wrapper_->AddRef();
|
wrapperStruct->wrapper_->AddRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,9 +170,6 @@ class CefCppToCRefCounted : public CefBaseRefCounted {
|
|||||||
|
|
||||||
WrapperStruct* wrapperStruct =
|
WrapperStruct* wrapperStruct =
|
||||||
GetWrapperStruct(reinterpret_cast<StructName*>(base));
|
GetWrapperStruct(reinterpret_cast<StructName*>(base));
|
||||||
// Verify that the wrapper offset was calculated correctly.
|
|
||||||
DCHECK_EQ(kWrapperType, wrapperStruct->type_);
|
|
||||||
|
|
||||||
return wrapperStruct->wrapper_->Release();
|
return wrapperStruct->wrapper_->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,9 +181,6 @@ class CefCppToCRefCounted : public CefBaseRefCounted {
|
|||||||
|
|
||||||
WrapperStruct* wrapperStruct =
|
WrapperStruct* wrapperStruct =
|
||||||
GetWrapperStruct(reinterpret_cast<StructName*>(base));
|
GetWrapperStruct(reinterpret_cast<StructName*>(base));
|
||||||
// Verify that the wrapper offset was calculated correctly.
|
|
||||||
DCHECK_EQ(kWrapperType, wrapperStruct->type_);
|
|
||||||
|
|
||||||
return wrapperStruct->wrapper_->HasOneRef();
|
return wrapperStruct->wrapper_->HasOneRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,9 +193,6 @@ class CefCppToCRefCounted : public CefBaseRefCounted {
|
|||||||
|
|
||||||
WrapperStruct* wrapperStruct =
|
WrapperStruct* wrapperStruct =
|
||||||
GetWrapperStruct(reinterpret_cast<StructName*>(base));
|
GetWrapperStruct(reinterpret_cast<StructName*>(base));
|
||||||
// Verify that the wrapper offset was calculated correctly.
|
|
||||||
DCHECK_EQ(kWrapperType, wrapperStruct->type_);
|
|
||||||
|
|
||||||
return wrapperStruct->wrapper_->HasAtLeastOneRef();
|
return wrapperStruct->wrapper_->HasAtLeastOneRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#define CEF_LIBCEF_DLL_CPPTOC_CPPTOC_SCOPED_H_
|
#define CEF_LIBCEF_DLL_CPPTOC_CPPTOC_SCOPED_H_
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "include/base/cef_logging.h"
|
#include "include/base/cef_logging.h"
|
||||||
#include "include/capi/cef_base_capi.h"
|
#include "include/capi/cef_base_capi.h"
|
||||||
#include "include/cef_base.h"
|
#include "include/cef_base.h"
|
||||||
@ -52,17 +54,18 @@ class CefCppToCScoped : public CefBaseScoped {
|
|||||||
// For example:
|
// For example:
|
||||||
//
|
//
|
||||||
// void MyMethod(MyType* obj) {
|
// void MyMethod(MyType* obj) {
|
||||||
// CefOwnPtr<MyTypeCppToC> MyTypeWrapper = MyTypeCppToC::WrapRaw(obj);
|
// [MyTypeWrapper, MyTypeStruct] = MyTypeCppToC::WrapRaw(obj);
|
||||||
// my_method(MyTypeWrapper->GetStruct());
|
// my_method(MyTypeStruct);
|
||||||
// // MyTypeWrapper is deleted when MyMethod() goes out of scope.
|
// // MyTypeWrapper is deleted when MyMethod() goes out of scope.
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// void my_method(my_type_t* struct) {
|
// void my_method(my_type_t* struct) {
|
||||||
// // Access |struct| here but you can't delete it.
|
// // Access |struct| here but you can't delete it.
|
||||||
// }
|
// }
|
||||||
static CefOwnPtr<ClassName> WrapRaw(CefRawPtr<BaseName> c) {
|
static std::pair<CefOwnPtr<CefBaseScoped>, StructName*> WrapRaw(
|
||||||
|
CefRawPtr<BaseName> c) {
|
||||||
if (!c) {
|
if (!c) {
|
||||||
return CefOwnPtr<ClassName>();
|
return std::make_pair(nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrap our object with the CefCppToC class.
|
// Wrap our object with the CefCppToC class.
|
||||||
@ -70,7 +73,9 @@ class CefCppToCScoped : public CefBaseScoped {
|
|||||||
wrapper->Initialize(c, false);
|
wrapper->Initialize(c, false);
|
||||||
|
|
||||||
// Return the owned wrapper object.
|
// Return the owned wrapper object.
|
||||||
return CefOwnPtr<ClassName>(wrapper);
|
CefOwnPtr<ClassName> wrapperPtr(wrapper);
|
||||||
|
auto* wrapperStruct = wrapperPtr->GetStruct();
|
||||||
|
return std::make_pair(std::move(wrapperPtr), wrapperStruct);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the underlying object instance for a structure reference passed
|
// Retrieve the underlying object instance for a structure reference passed
|
||||||
@ -87,7 +92,8 @@ class CefCppToCScoped : public CefBaseScoped {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cast our structure to the wrapper structure type.
|
// Cast our structure to the wrapper structure type.
|
||||||
WrapperStruct* wrapperStruct = GetWrapperStruct(s);
|
WrapperStruct* wrapperStruct =
|
||||||
|
GetWrapperStruct(s, /*require_exact_type=*/false);
|
||||||
|
|
||||||
// If the type does not match this object then we need to unwrap as the
|
// If the type does not match this object then we need to unwrap as the
|
||||||
// derived type.
|
// derived type.
|
||||||
@ -96,8 +102,8 @@ class CefCppToCScoped : public CefBaseScoped {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We should own the underlying object currently.
|
// We should own the underlying object currently.
|
||||||
DCHECK(wrapperStruct->wrapper_->owned_);
|
CHECK(wrapperStruct->wrapper_->owned_);
|
||||||
DCHECK(wrapperStruct->object_);
|
CHECK(wrapperStruct->object_);
|
||||||
|
|
||||||
// We're giving up ownership of the underlying object. Clear the pointer so
|
// We're giving up ownership of the underlying object. Clear the pointer so
|
||||||
// it doesn't get deleted.
|
// it doesn't get deleted.
|
||||||
@ -123,7 +129,8 @@ class CefCppToCScoped : public CefBaseScoped {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cast our structure to the wrapper structure type.
|
// Cast our structure to the wrapper structure type.
|
||||||
WrapperStruct* wrapperStruct = GetWrapperStruct(s);
|
WrapperStruct* wrapperStruct =
|
||||||
|
GetWrapperStruct(s, /*require_exact_type=*/false);
|
||||||
|
|
||||||
// If the type does not match this object then we need to unwrap as the
|
// If the type does not match this object then we need to unwrap as the
|
||||||
// derived type.
|
// derived type.
|
||||||
@ -137,12 +144,10 @@ class CefCppToCScoped : public CefBaseScoped {
|
|||||||
|
|
||||||
// Retrieve the same side wrapper associated with the structure. Ownership
|
// Retrieve the same side wrapper associated with the structure. Ownership
|
||||||
// does not change.
|
// does not change.
|
||||||
static ClassName* GetWrapper(StructName* s) {
|
static CefBaseScoped* GetWrapper(StructName* s) {
|
||||||
DCHECK(s);
|
DCHECK(s);
|
||||||
WrapperStruct* wrapperStruct = GetWrapperStruct(s);
|
WrapperStruct* wrapperStruct = GetWrapperStruct(s);
|
||||||
// Verify that the wrapper offset was calculated correctly.
|
return wrapperStruct->wrapper_;
|
||||||
DCHECK_EQ(kWrapperType, wrapperStruct->type_);
|
|
||||||
return static_cast<ClassName*>(wrapperStruct->wrapper_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the underlying object instance from our own structure reference
|
// Retrieve the underlying object instance from our own structure reference
|
||||||
@ -151,8 +156,6 @@ class CefCppToCScoped : public CefBaseScoped {
|
|||||||
static BaseName* Get(StructName* s) {
|
static BaseName* Get(StructName* s) {
|
||||||
DCHECK(s);
|
DCHECK(s);
|
||||||
WrapperStruct* wrapperStruct = GetWrapperStruct(s);
|
WrapperStruct* wrapperStruct = GetWrapperStruct(s);
|
||||||
// Verify that the wrapper offset was calculated correctly.
|
|
||||||
DCHECK_EQ(kWrapperType, wrapperStruct->type_);
|
|
||||||
return wrapperStruct->object_;
|
return wrapperStruct->object_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,13 +199,21 @@ class CefCppToCScoped : public CefBaseScoped {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static WrapperStruct* GetWrapperStruct(StructName* s) {
|
static WrapperStruct* GetWrapperStruct(StructName* s,
|
||||||
|
bool require_exact_type = true) {
|
||||||
// Offset using the WrapperStruct size instead of individual member sizes
|
// Offset using the WrapperStruct size instead of individual member sizes
|
||||||
// to avoid problems due to platform/compiler differences in structure
|
// to avoid problems due to platform/compiler differences in structure
|
||||||
// padding.
|
// padding.
|
||||||
return reinterpret_cast<WrapperStruct*>(
|
auto* wrapperStruct = reinterpret_cast<WrapperStruct*>(
|
||||||
reinterpret_cast<char*>(s) -
|
reinterpret_cast<char*>(s) -
|
||||||
(sizeof(WrapperStruct) - sizeof(StructName)));
|
(sizeof(WrapperStruct) - sizeof(StructName)));
|
||||||
|
|
||||||
|
if (require_exact_type) {
|
||||||
|
// Verify that the wrapper offset was calculated correctly.
|
||||||
|
CHECK_EQ(kWrapperType, wrapperStruct->type_);
|
||||||
|
}
|
||||||
|
|
||||||
|
return wrapperStruct;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unwrap as the derived type.
|
// Unwrap as the derived type.
|
||||||
@ -219,11 +230,9 @@ class CefCppToCScoped : public CefBaseScoped {
|
|||||||
|
|
||||||
WrapperStruct* wrapperStruct =
|
WrapperStruct* wrapperStruct =
|
||||||
GetWrapperStruct(reinterpret_cast<StructName*>(base));
|
GetWrapperStruct(reinterpret_cast<StructName*>(base));
|
||||||
// Verify that the wrapper offset was calculated correctly.
|
|
||||||
DCHECK_EQ(kWrapperType, wrapperStruct->type_);
|
|
||||||
|
|
||||||
// Should only be deleting wrappers that own the underlying object.
|
// Should only be deleting wrappers that own the underlying object.
|
||||||
DCHECK(wrapperStruct->wrapper_->owned_);
|
CHECK(wrapperStruct->wrapper_->owned_);
|
||||||
delete wrapperStruct->wrapper_;
|
delete wrapperStruct->wrapper_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,4 +23,7 @@ class CefBaseRefCountedCToCpp
|
|||||||
CefBaseRefCountedCToCpp();
|
CefBaseRefCountedCToCpp();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr auto CefBaseRefCountedCToCpp_Wrap = CefBaseRefCountedCToCpp::Wrap;
|
||||||
|
constexpr auto CefBaseRefCountedCToCpp_Unwrap = CefBaseRefCountedCToCpp::Unwrap;
|
||||||
|
|
||||||
#endif // CEF_LIBCEF_DLL_CTOCPP_BASE_REF_COUNTED_CTOCPP_H_
|
#endif // CEF_LIBCEF_DLL_CTOCPP_BASE_REF_COUNTED_CTOCPP_H_
|
||||||
|
@ -22,4 +22,8 @@ class CefBaseScopedCToCpp : public CefCToCppScoped<CefBaseScopedCToCpp,
|
|||||||
CefBaseScopedCToCpp();
|
CefBaseScopedCToCpp();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr auto CefBaseScopedCToCpp_Wrap = CefBaseScopedCToCpp::Wrap;
|
||||||
|
constexpr auto CefBaseScopedCToCpp_UnwrapOwn = CefBaseScopedCToCpp::UnwrapOwn;
|
||||||
|
constexpr auto CefBaseScopedCToCpp_UnwrapRaw = CefBaseScopedCToCpp::UnwrapRaw;
|
||||||
|
|
||||||
#endif // CEF_LIBCEF_DLL_CTOCPP_BASE_SCOPED_CTOCPP_H_
|
#endif // CEF_LIBCEF_DLL_CTOCPP_BASE_SCOPED_CTOCPP_H_
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "include/base/cef_logging.h"
|
#include "include/base/cef_logging.h"
|
||||||
#include "include/capi/cef_base_capi.h"
|
#include "include/capi/cef_base_capi.h"
|
||||||
|
#include "include/cef_api_hash.h"
|
||||||
#include "include/cef_base.h"
|
#include "include/cef_base.h"
|
||||||
#include "libcef_dll/wrapper_types.h"
|
#include "libcef_dll/wrapper_types.h"
|
||||||
|
|
||||||
@ -45,8 +46,6 @@ class CefCToCppRefCounted : public BaseName {
|
|||||||
// If returning the structure across the DLL boundary use Unwrap() instead.
|
// If returning the structure across the DLL boundary use Unwrap() instead.
|
||||||
StructName* GetStruct() const {
|
StructName* GetStruct() const {
|
||||||
WrapperStruct* wrapperStruct = GetWrapperStruct(this);
|
WrapperStruct* wrapperStruct = GetWrapperStruct(this);
|
||||||
// Verify that the wrapper offset was calculated correctly.
|
|
||||||
DCHECK_EQ(kWrapperType, wrapperStruct->type_);
|
|
||||||
return wrapperStruct->struct_;
|
return wrapperStruct->struct_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +54,8 @@ class CefCToCppRefCounted : public BaseName {
|
|||||||
// from the other side.
|
// from the other side.
|
||||||
struct WrapperStruct;
|
struct WrapperStruct;
|
||||||
|
|
||||||
static WrapperStruct* GetWrapperStruct(const BaseName* obj);
|
static WrapperStruct* GetWrapperStruct(const BaseName* obj,
|
||||||
|
bool require_exact_type = true);
|
||||||
|
|
||||||
// Unwrap as the derived type.
|
// Unwrap as the derived type.
|
||||||
static StructName* UnwrapDerived(CefWrapperType type, BaseName* c);
|
static StructName* UnwrapDerived(CefWrapperType type, BaseName* c);
|
||||||
@ -119,6 +119,18 @@ CefRefPtr<BaseName> CefCToCppRefCounted<ClassName, BaseName, StructName>::Wrap(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto size = reinterpret_cast<cef_base_ref_counted_t*>(s)->size;
|
||||||
|
if (size != sizeof(StructName)) {
|
||||||
|
LOG(FATAL) << "Cannot wrap struct with invalid base.size value (got "
|
||||||
|
<< size << ", expected " << sizeof(StructName)
|
||||||
|
<< ") at API version "
|
||||||
|
#if defined(WRAPPING_CEF_SHARED)
|
||||||
|
<< CEF_API_VERSION;
|
||||||
|
#else
|
||||||
|
<< cef_api_version();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// Wrap their structure with the CefCToCppRefCounted object.
|
// Wrap their structure with the CefCToCppRefCounted object.
|
||||||
WrapperStruct* wrapperStruct = new WrapperStruct;
|
WrapperStruct* wrapperStruct = new WrapperStruct;
|
||||||
wrapperStruct->type_ = kWrapperType;
|
wrapperStruct->type_ = kWrapperType;
|
||||||
@ -140,7 +152,8 @@ StructName* CefCToCppRefCounted<ClassName, BaseName, StructName>::Unwrap(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
WrapperStruct* wrapperStruct = GetWrapperStruct(c.get());
|
WrapperStruct* wrapperStruct =
|
||||||
|
GetWrapperStruct(c.get(), /*require_exact_type=*/false);
|
||||||
|
|
||||||
// If the type does not match this object then we need to unwrap as the
|
// If the type does not match this object then we need to unwrap as the
|
||||||
// derived type.
|
// derived type.
|
||||||
@ -160,8 +173,6 @@ bool CefCToCppRefCounted<ClassName, BaseName, StructName>::Release() const {
|
|||||||
UnderlyingRelease();
|
UnderlyingRelease();
|
||||||
if (ref_count_.Release()) {
|
if (ref_count_.Release()) {
|
||||||
WrapperStruct* wrapperStruct = GetWrapperStruct(this);
|
WrapperStruct* wrapperStruct = GetWrapperStruct(this);
|
||||||
// Verify that the wrapper offset was calculated correctly.
|
|
||||||
DCHECK_EQ(kWrapperType, wrapperStruct->type_);
|
|
||||||
delete wrapperStruct;
|
delete wrapperStruct;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -171,12 +182,20 @@ bool CefCToCppRefCounted<ClassName, BaseName, StructName>::Release() const {
|
|||||||
template <class ClassName, class BaseName, class StructName>
|
template <class ClassName, class BaseName, class StructName>
|
||||||
typename CefCToCppRefCounted<ClassName, BaseName, StructName>::WrapperStruct*
|
typename CefCToCppRefCounted<ClassName, BaseName, StructName>::WrapperStruct*
|
||||||
CefCToCppRefCounted<ClassName, BaseName, StructName>::GetWrapperStruct(
|
CefCToCppRefCounted<ClassName, BaseName, StructName>::GetWrapperStruct(
|
||||||
const BaseName* obj) {
|
const BaseName* obj,
|
||||||
|
bool require_exact_type) {
|
||||||
// Offset using the WrapperStruct size instead of individual member sizes to
|
// Offset using the WrapperStruct size instead of individual member sizes to
|
||||||
// avoid problems due to platform/compiler differences in structure padding.
|
// avoid problems due to platform/compiler differences in structure padding.
|
||||||
return reinterpret_cast<WrapperStruct*>(
|
auto* wrapperStruct = reinterpret_cast<WrapperStruct*>(
|
||||||
reinterpret_cast<char*>(const_cast<BaseName*>(obj)) -
|
reinterpret_cast<char*>(const_cast<BaseName*>(obj)) -
|
||||||
(sizeof(WrapperStruct) - sizeof(ClassName)));
|
(sizeof(WrapperStruct) - sizeof(ClassName)));
|
||||||
|
|
||||||
|
if (require_exact_type) {
|
||||||
|
// Verify that the wrapper offset was calculated correctly.
|
||||||
|
CHECK_EQ(kWrapperType, wrapperStruct->type_);
|
||||||
|
}
|
||||||
|
|
||||||
|
return wrapperStruct;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // CEF_LIBCEF_DLL_CTOCPP_CTOCPP_REF_COUNTED_H_
|
#endif // CEF_LIBCEF_DLL_CTOCPP_CTOCPP_REF_COUNTED_H_
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "include/base/cef_logging.h"
|
#include "include/base/cef_logging.h"
|
||||||
#include "include/capi/cef_base_capi.h"
|
#include "include/capi/cef_base_capi.h"
|
||||||
|
#include "include/cef_api_hash.h"
|
||||||
#include "include/cef_base.h"
|
#include "include/cef_base.h"
|
||||||
#include "libcef_dll/wrapper_types.h"
|
#include "libcef_dll/wrapper_types.h"
|
||||||
|
|
||||||
@ -75,8 +76,6 @@ class CefCToCppScoped : public BaseName {
|
|||||||
// If returning the structure across the DLL boundary use Unwrap() instead.
|
// If returning the structure across the DLL boundary use Unwrap() instead.
|
||||||
StructName* GetStruct() const {
|
StructName* GetStruct() const {
|
||||||
WrapperStruct* wrapperStruct = GetWrapperStruct(this);
|
WrapperStruct* wrapperStruct = GetWrapperStruct(this);
|
||||||
// Verify that the wrapper offset was calculated correctly.
|
|
||||||
DCHECK_EQ(kWrapperType, wrapperStruct->type_);
|
|
||||||
return wrapperStruct->struct_;
|
return wrapperStruct->struct_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +84,8 @@ class CefCToCppScoped : public BaseName {
|
|||||||
// from the other side.
|
// from the other side.
|
||||||
struct WrapperStruct;
|
struct WrapperStruct;
|
||||||
|
|
||||||
static WrapperStruct* GetWrapperStruct(const BaseName* obj);
|
static WrapperStruct* GetWrapperStruct(const BaseName* obj,
|
||||||
|
bool require_exact_type = true);
|
||||||
|
|
||||||
// Unwrap as the derived type.
|
// Unwrap as the derived type.
|
||||||
static StructName* UnwrapDerivedOwn(CefWrapperType type,
|
static StructName* UnwrapDerivedOwn(CefWrapperType type,
|
||||||
@ -107,7 +107,19 @@ template <class ClassName, class BaseName, class StructName>
|
|||||||
CefOwnPtr<BaseName> CefCToCppScoped<ClassName, BaseName, StructName>::Wrap(
|
CefOwnPtr<BaseName> CefCToCppScoped<ClassName, BaseName, StructName>::Wrap(
|
||||||
StructName* s) {
|
StructName* s) {
|
||||||
if (!s) {
|
if (!s) {
|
||||||
return CefOwnPtr<BaseName>();
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto size = reinterpret_cast<cef_base_ref_counted_t*>(s)->size;
|
||||||
|
if (size != sizeof(StructName)) {
|
||||||
|
LOG(FATAL) << "Cannot wrap struct with invalid base.size value (got "
|
||||||
|
<< size << ", expected " << sizeof(StructName)
|
||||||
|
<< ") at API version "
|
||||||
|
#if defined(WRAPPING_CEF_SHARED)
|
||||||
|
<< CEF_API_VERSION;
|
||||||
|
#else
|
||||||
|
<< cef_api_version();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrap their structure with the CefCToCpp object.
|
// Wrap their structure with the CefCToCpp object.
|
||||||
@ -125,7 +137,8 @@ StructName* CefCToCppScoped<ClassName, BaseName, StructName>::UnwrapOwn(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
WrapperStruct* wrapperStruct = GetWrapperStruct(c.get());
|
WrapperStruct* wrapperStruct =
|
||||||
|
GetWrapperStruct(c.get(), /*require_exact_type=*/false);
|
||||||
|
|
||||||
// If the type does not match this object then we need to unwrap as the
|
// If the type does not match this object then we need to unwrap as the
|
||||||
// derived type.
|
// derived type.
|
||||||
@ -156,7 +169,8 @@ StructName* CefCToCppScoped<ClassName, BaseName, StructName>::UnwrapRaw(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
WrapperStruct* wrapperStruct = GetWrapperStruct(c);
|
WrapperStruct* wrapperStruct =
|
||||||
|
GetWrapperStruct(c, /*require_exact_type=*/false);
|
||||||
|
|
||||||
// If the type does not match this object then we need to unwrap as the
|
// If the type does not match this object then we need to unwrap as the
|
||||||
// derived type.
|
// derived type.
|
||||||
@ -173,8 +187,6 @@ NO_SANITIZE("cfi-icall")
|
|||||||
void CefCToCppScoped<ClassName, BaseName, StructName>::operator delete(
|
void CefCToCppScoped<ClassName, BaseName, StructName>::operator delete(
|
||||||
void* ptr) {
|
void* ptr) {
|
||||||
WrapperStruct* wrapperStruct = GetWrapperStruct(static_cast<BaseName*>(ptr));
|
WrapperStruct* wrapperStruct = GetWrapperStruct(static_cast<BaseName*>(ptr));
|
||||||
// Verify that the wrapper offset was calculated correctly.
|
|
||||||
DCHECK_EQ(kWrapperType, wrapperStruct->type_);
|
|
||||||
|
|
||||||
// May be NULL if UnwrapOwn() was called.
|
// May be NULL if UnwrapOwn() was called.
|
||||||
cef_base_scoped_t* base =
|
cef_base_scoped_t* base =
|
||||||
@ -194,12 +206,20 @@ void CefCToCppScoped<ClassName, BaseName, StructName>::operator delete(
|
|||||||
template <class ClassName, class BaseName, class StructName>
|
template <class ClassName, class BaseName, class StructName>
|
||||||
typename CefCToCppScoped<ClassName, BaseName, StructName>::WrapperStruct*
|
typename CefCToCppScoped<ClassName, BaseName, StructName>::WrapperStruct*
|
||||||
CefCToCppScoped<ClassName, BaseName, StructName>::GetWrapperStruct(
|
CefCToCppScoped<ClassName, BaseName, StructName>::GetWrapperStruct(
|
||||||
const BaseName* obj) {
|
const BaseName* obj,
|
||||||
|
bool require_exact_type) {
|
||||||
// Offset using the WrapperStruct size instead of individual member sizes to
|
// Offset using the WrapperStruct size instead of individual member sizes to
|
||||||
// avoid problems due to platform/compiler differences in structure padding.
|
// avoid problems due to platform/compiler differences in structure padding.
|
||||||
return reinterpret_cast<WrapperStruct*>(
|
auto* wrapperStruct = reinterpret_cast<WrapperStruct*>(
|
||||||
reinterpret_cast<char*>(const_cast<BaseName*>(obj)) -
|
reinterpret_cast<char*>(const_cast<BaseName*>(obj)) -
|
||||||
(sizeof(WrapperStruct) - sizeof(ClassName)));
|
(sizeof(WrapperStruct) - sizeof(ClassName)));
|
||||||
|
|
||||||
|
if (require_exact_type) {
|
||||||
|
// Verify that the wrapper offset was calculated correctly.
|
||||||
|
CHECK_EQ(kWrapperType, wrapperStruct->type_);
|
||||||
|
}
|
||||||
|
|
||||||
|
return wrapperStruct;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // CEF_LIBCEF_DLL_CTOCPP_CTOCPP_SCOPED_H_
|
#endif // CEF_LIBCEF_DLL_CTOCPP_CTOCPP_SCOPED_H_
|
||||||
|
@ -4,15 +4,24 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <map>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
#include "include/base/cef_build.h"
|
#include "base/logging.h"
|
||||||
#include "include/cef_api_hash.h"
|
#include "base/no_destructor.h"
|
||||||
#include "include/cef_version.h"
|
#include "cef/include/base/cef_build.h"
|
||||||
|
#include "cef/include/cef_api_hash.h"
|
||||||
|
#include "cef/include/cef_id_mappers.h"
|
||||||
|
#include "cef/include/cef_version_info.h"
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
#include "include/internal/cef_win.h"
|
#include "cef/include/internal/cef_win.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
int g_version = -1;
|
||||||
|
}
|
||||||
|
|
||||||
CEF_EXPORT int cef_version_info(int entry) {
|
CEF_EXPORT int cef_version_info(int entry) {
|
||||||
switch (entry) {
|
switch (entry) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -36,19 +45,117 @@ CEF_EXPORT int cef_version_info(int entry) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CEF_EXPORT const char* cef_api_hash(int entry) {
|
#include "cef/libcef_dll/cef_api_versions.inc"
|
||||||
|
|
||||||
|
CEF_EXPORT const char* cef_api_hash(int version, int entry) {
|
||||||
|
static const ApiVersionHash* hash = nullptr;
|
||||||
|
|
||||||
|
// Initialize on the first successful lookup.
|
||||||
|
if (!hash) {
|
||||||
|
for (size_t i = 0; i < kApiVersionHashesSize; ++i) {
|
||||||
|
if (version == kApiVersionHashes[i].version) {
|
||||||
|
hash = &kApiVersionHashes[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hash) {
|
||||||
|
g_version = version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hash) {
|
||||||
|
LOG(ERROR) << "Request for unsupported CEF API version " << version;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version != g_version) {
|
||||||
|
LOG(ERROR) << "CEF API version cannot be configured multiple times";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
switch (entry) {
|
switch (entry) {
|
||||||
case 0:
|
case 0:
|
||||||
return CEF_API_HASH_PLATFORM;
|
return hash->platform;
|
||||||
case 1:
|
case 1:
|
||||||
return CEF_API_HASH_UNIVERSAL;
|
return hash->universal;
|
||||||
case 2:
|
case 2:
|
||||||
return CEF_COMMIT_HASH;
|
return CEF_COMMIT_HASH;
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CEF_EXPORT int cef_api_version() {
|
||||||
|
return g_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "cef/libcef_dll/cef_pack_resources.inc"
|
||||||
|
|
||||||
|
CEF_EXPORT int cef_id_for_pack_resource_name(const char* name) {
|
||||||
|
static base::NoDestructor<std::map<std::string_view, int>> string_to_id_map;
|
||||||
|
|
||||||
|
// Initialize on the first call.
|
||||||
|
if (string_to_id_map->empty()) {
|
||||||
|
for (size_t i = 0; i < kIdNamesPackResourcesSize; ++i) {
|
||||||
|
(*string_to_id_map)[kIdNamesPackResources[i].name] =
|
||||||
|
kIdNamesPackResources[i].id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& it = string_to_id_map->find(name);
|
||||||
|
if (it != string_to_id_map->end()) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(WARNING) << __func__ << " called with unsupported value " << name;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "cef/libcef_dll/cef_pack_strings.inc"
|
||||||
|
|
||||||
|
CEF_EXPORT int cef_id_for_pack_string_name(const char* name) {
|
||||||
|
static base::NoDestructor<std::map<std::string_view, int>> string_to_id_map;
|
||||||
|
|
||||||
|
// Initialize on the first call.
|
||||||
|
if (string_to_id_map->empty()) {
|
||||||
|
for (size_t i = 0; i < kIdNamesPackStringsSize; ++i) {
|
||||||
|
(*string_to_id_map)[kIdNamesPackStrings[i].name] =
|
||||||
|
kIdNamesPackStrings[i].id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& it = string_to_id_map->find(name);
|
||||||
|
if (it != string_to_id_map->end()) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(WARNING) << __func__ << " called with unsupported value " << name;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "cef/libcef_dll/cef_command_ids.inc"
|
||||||
|
|
||||||
|
CEF_EXPORT int cef_id_for_command_id_name(const char* name) {
|
||||||
|
static base::NoDestructor<std::map<std::string_view, int>> string_to_id_map;
|
||||||
|
|
||||||
|
// Initialize on the first call.
|
||||||
|
if (string_to_id_map->empty()) {
|
||||||
|
for (size_t i = 0; i < kIdNamesCommandIdsSize; ++i) {
|
||||||
|
(*string_to_id_map)[kIdNamesCommandIds[i].name] =
|
||||||
|
kIdNamesCommandIds[i].id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& it = string_to_id_map->find(name);
|
||||||
|
if (it != string_to_id_map->end()) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(WARNING) << __func__ << " called with unsupported value " << name;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
|
|
||||||
#if defined(ARCH_CPU_32_BITS)
|
#if defined(ARCH_CPU_32_BITS)
|
||||||
|
@ -19,12 +19,9 @@ int CefRunWinMainWithPreferredStackSize(wWinMainPtr wWinMain,
|
|||||||
int nCmdShow) {
|
int nCmdShow) {
|
||||||
CHECK(wWinMain && hInstance);
|
CHECK(wWinMain && hInstance);
|
||||||
|
|
||||||
const char* api_hash = cef_api_hash(0);
|
const char* api_hash = cef_api_hash(CEF_API_VERSION, 0);
|
||||||
if (strcmp(api_hash, CEF_API_HASH_PLATFORM)) {
|
CHECK(!strcmp(api_hash, CEF_API_HASH_PLATFORM)) <<
|
||||||
// The libcef API hash does not match the current header API hash.
|
"API hashes for libcef and libcef_dll_wrapper do not match.";
|
||||||
DCHECK(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cef_run_winmain_with_preferred_stack_size(wWinMain, hInstance,
|
return cef_run_winmain_with_preferred_stack_size(wWinMain, hInstance,
|
||||||
lpCmdLine, nCmdShow);
|
lpCmdLine, nCmdShow);
|
||||||
@ -33,12 +30,9 @@ int CefRunWinMainWithPreferredStackSize(wWinMainPtr wWinMain,
|
|||||||
int CefRunMainWithPreferredStackSize(mainPtr main, int argc, char* argv[]) {
|
int CefRunMainWithPreferredStackSize(mainPtr main, int argc, char* argv[]) {
|
||||||
CHECK(main);
|
CHECK(main);
|
||||||
|
|
||||||
const char* api_hash = cef_api_hash(0);
|
const char* api_hash = cef_api_hash(CEF_API_VERSION, 0);
|
||||||
if (strcmp(api_hash, CEF_API_HASH_PLATFORM)) {
|
CHECK(!strcmp(api_hash, CEF_API_HASH_PLATFORM)) <<
|
||||||
// The libcef API hash does not match the current header API hash.
|
"API hashes for libcef and libcef_dll_wrapper do not match.";
|
||||||
DCHECK(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cef_run_main_with_preferred_stack_size(main, argc, argv);
|
return cef_run_main_with_preferred_stack_size(main, argc, argv);
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ index 4aaba212926f4..e8aadb2c97fe9 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
diff --git chrome/browser/ui/BUILD.gn chrome/browser/ui/BUILD.gn
|
diff --git chrome/browser/ui/BUILD.gn chrome/browser/ui/BUILD.gn
|
||||||
index 977b3222c8f7c..ee71bf3a1a463 100644
|
index 977b3222c8f7c..e5d36a4e5921e 100644
|
||||||
--- chrome/browser/ui/BUILD.gn
|
--- chrome/browser/ui/BUILD.gn
|
||||||
+++ chrome/browser/ui/BUILD.gn
|
+++ chrome/browser/ui/BUILD.gn
|
||||||
@@ -8,6 +8,7 @@ import("//build/config/compiler/compiler.gni")
|
@@ -8,6 +8,7 @@ import("//build/config/compiler/compiler.gni")
|
||||||
@ -118,18 +118,21 @@ index 977b3222c8f7c..ee71bf3a1a463 100644
|
|||||||
"//chrome:resources",
|
"//chrome:resources",
|
||||||
"//chrome:strings",
|
"//chrome:strings",
|
||||||
"//chrome/app:chrome_dll_resources",
|
"//chrome/app:chrome_dll_resources",
|
||||||
@@ -699,6 +705,10 @@ static_library("ui") {
|
@@ -699,6 +705,13 @@ static_library("ui") {
|
||||||
deps += [ "//components/plus_addresses/resources:vector_icons" ]
|
deps += [ "//components/plus_addresses/resources:vector_icons" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
+ if (enable_cef) {
|
+ if (enable_cef) {
|
||||||
+ deps += [ "//cef:cef_resources" ]
|
+ deps += [
|
||||||
|
+ "//cef:cef_resources",
|
||||||
|
+ "//cef:make_version_header",
|
||||||
|
+ ]
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
# TODO(crbug.com/41437292): Remove this circular dependency.
|
# TODO(crbug.com/41437292): Remove this circular dependency.
|
||||||
# Any circular includes must depend on the target "//chrome/browser:browser_public_dependencies".
|
# Any circular includes must depend on the target "//chrome/browser:browser_public_dependencies".
|
||||||
# These are all-platform circular includes.
|
# These are all-platform circular includes.
|
||||||
@@ -5487,6 +5497,7 @@ static_library("ui") {
|
@@ -5487,6 +5500,7 @@ static_library("ui") {
|
||||||
if (enable_printing) {
|
if (enable_printing) {
|
||||||
deps += [
|
deps += [
|
||||||
"//components/printing/browser",
|
"//components/printing/browser",
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
|
|
||||||
#include "include/base/cef_callback.h"
|
#include "include/base/cef_callback.h"
|
||||||
#include "include/cef_browser.h"
|
#include "include/cef_browser.h"
|
||||||
#include "include/cef_command_ids.h"
|
|
||||||
#include "include/cef_frame.h"
|
#include "include/cef_frame.h"
|
||||||
|
#include "include/cef_id_mappers.h"
|
||||||
#include "include/cef_parser.h"
|
#include "include/cef_parser.h"
|
||||||
#include "include/cef_shared_process_message_builder.h"
|
#include "include/cef_shared_process_message_builder.h"
|
||||||
#include "include/cef_ssl_status.h"
|
#include "include/cef_ssl_status.h"
|
||||||
@ -318,6 +318,32 @@ bool IsAllowedToolbarButton(cef_chrome_toolbar_button_type_t button_type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool IsAllowedAppMenuCommandId(int command_id) {
|
bool IsAllowedAppMenuCommandId(int command_id) {
|
||||||
|
// Version-safe static declarations of IDC variables using names from
|
||||||
|
// cef_command_ids.h.
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_NEW_WINDOW);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_NEW_INCOGNITO_WINDOW);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_ZOOM_MENU);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_ZOOM_PLUS);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_ZOOM_NORMAL);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_ZOOM_MINUS);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_FULLSCREEN);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_PRINT);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_FIND);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_FIND_NEXT);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_FIND_PREVIOUS);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_MORE_TOOLS_MENU);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_CLEAR_BROWSING_DATA);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_MANAGE_EXTENSIONS);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_PERFORMANCE);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_TASK_MANAGER);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_DEV_TOOLS);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_EDIT_MENU);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_CUT);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_COPY);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_PASTE);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_OPTIONS);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_EXIT);
|
||||||
|
|
||||||
// Only the commands in this array will be allowed.
|
// Only the commands in this array will be allowed.
|
||||||
static const int kAllowedCommandIds[] = {
|
static const int kAllowedCommandIds[] = {
|
||||||
IDC_NEW_WINDOW,
|
IDC_NEW_WINDOW,
|
||||||
@ -361,6 +387,28 @@ bool IsAllowedAppMenuCommandId(int command_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool IsAllowedContextMenuCommandId(int command_id) {
|
bool IsAllowedContextMenuCommandId(int command_id) {
|
||||||
|
// Version-safe static declarations of IDC variables using names from
|
||||||
|
// cef_command_ids.h.
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_CONTENT_CONTEXT_CUSTOM_FIRST);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_CONTENT_CONTEXT_CUSTOM_LAST);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_EXTENSIONS_CONTEXT_CUSTOM_LAST);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_BACK);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_FORWARD);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_RELOAD);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_RELOAD_BYPASSING_CACHE);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_RELOAD_CLEARING_CACHE);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_STOP);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_PRINT);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_CONTENT_CONTEXT_CUT);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_CONTENT_CONTEXT_COPY);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_CONTENT_CONTEXT_PASTE);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_CONTENT_CONTEXT_PASTE_AND_MATCH_STYLE);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_CONTENT_CONTEXT_DELETE);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_CONTENT_CONTEXT_SELECTALL);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_CONTENT_CONTEXT_UNDO);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_CONTENT_CONTEXT_REDO);
|
||||||
|
|
||||||
// Allow commands added by web content.
|
// Allow commands added by web content.
|
||||||
if (command_id >= IDC_CONTENT_CONTEXT_CUSTOM_FIRST &&
|
if (command_id >= IDC_CONTENT_CONTEXT_CUSTOM_FIRST &&
|
||||||
command_id <= IDC_CONTENT_CONTEXT_CUSTOM_LAST) {
|
command_id <= IDC_CONTENT_CONTEXT_CUSTOM_LAST) {
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#include "include/cef_app.h"
|
#include "include/cef_app.h"
|
||||||
#import "include/cef_application_mac.h"
|
#import "include/cef_application_mac.h"
|
||||||
#include "include/cef_command_ids.h"
|
#import "include/cef_id_mappers.h"
|
||||||
#import "include/wrapper/cef_library_loader.h"
|
#import "include/wrapper/cef_library_loader.h"
|
||||||
#include "tests/cefclient/browser/main_context_impl.h"
|
#include "tests/cefclient/browser/main_context_impl.h"
|
||||||
#include "tests/cefclient/browser/resource.h"
|
#include "tests/cefclient/browser/resource.h"
|
||||||
@ -404,6 +404,24 @@ void RemoveMenuItem(NSMenu* menu, SEL action_selector) {
|
|||||||
//
|
//
|
||||||
// This implementation is based on Chromium's AppController class.
|
// This implementation is based on Chromium's AppController class.
|
||||||
- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item {
|
- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item {
|
||||||
|
// Version-safe static declarations of IDC variables using names from
|
||||||
|
// cef_command_ids.h.
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_OPEN_FILE);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_NEW_TAB);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_FOCUS_LOCATION);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_FOCUS_SEARCH);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_SHOW_HISTORY);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_SHOW_BOOKMARK_MANAGER);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_CLEAR_BROWSING_DATA);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_SHOW_DOWNLOADS);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_IMPORT_SETTINGS);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_MANAGE_EXTENSIONS);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_HELP_PAGE_VIA_MENU);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_OPTIONS);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_NEW_WINDOW);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_TASK_MANAGER);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_NEW_INCOGNITO_WINDOW);
|
||||||
|
|
||||||
SEL action = [item action];
|
SEL action = [item action];
|
||||||
BOOL enable = NO;
|
BOOL enable = NO;
|
||||||
// Whether opening a new browser window is allowed.
|
// Whether opening a new browser window is allowed.
|
||||||
@ -413,37 +431,26 @@ void RemoveMenuItem(NSMenu* menu, SEL action_selector) {
|
|||||||
// no key window.
|
// no key window.
|
||||||
if (action == @selector(commandDispatch:) ||
|
if (action == @selector(commandDispatch:) ||
|
||||||
action == @selector(commandDispatchUsingKeyModifiers:)) {
|
action == @selector(commandDispatchUsingKeyModifiers:)) {
|
||||||
switch ([item tag]) {
|
const auto tag = [item tag];
|
||||||
|
if (tag == IDC_OPEN_FILE || tag == IDC_NEW_TAB ||
|
||||||
|
tag == IDC_FOCUS_LOCATION || tag == IDC_FOCUS_SEARCH ||
|
||||||
|
tag == IDC_SHOW_HISTORY || tag == IDC_SHOW_BOOKMARK_MANAGER ||
|
||||||
|
tag == IDC_CLEAR_BROWSING_DATA || tag == IDC_SHOW_DOWNLOADS ||
|
||||||
|
tag == IDC_IMPORT_SETTINGS || tag == IDC_MANAGE_EXTENSIONS ||
|
||||||
|
tag == IDC_HELP_PAGE_VIA_MENU || tag == IDC_OPTIONS) {
|
||||||
// Browser-level items that open in new tabs or perform an action in a
|
// Browser-level items that open in new tabs or perform an action in a
|
||||||
// current tab should not open if there's a window- or app-modal dialog.
|
// current tab should not open if there's a window- or app-modal dialog.
|
||||||
case IDC_OPEN_FILE:
|
|
||||||
case IDC_NEW_TAB:
|
|
||||||
case IDC_FOCUS_LOCATION:
|
|
||||||
case IDC_FOCUS_SEARCH:
|
|
||||||
case IDC_SHOW_HISTORY:
|
|
||||||
case IDC_SHOW_BOOKMARK_MANAGER:
|
|
||||||
case IDC_CLEAR_BROWSING_DATA:
|
|
||||||
case IDC_SHOW_DOWNLOADS:
|
|
||||||
case IDC_IMPORT_SETTINGS:
|
|
||||||
case IDC_MANAGE_EXTENSIONS:
|
|
||||||
case IDC_HELP_PAGE_VIA_MENU:
|
|
||||||
case IDC_OPTIONS:
|
|
||||||
enable = canOpenNewBrowser && ![self keyWindowIsModal];
|
enable = canOpenNewBrowser && ![self keyWindowIsModal];
|
||||||
break;
|
} else if (tag == IDC_NEW_WINDOW) {
|
||||||
// Browser-level items that open in new windows: allow the user to open
|
// Browser-level items that open in new windows: allow the user to open
|
||||||
// a new window even if there's a window-modal dialog.
|
// a new window even if there's a window-modal dialog.
|
||||||
case IDC_NEW_WINDOW:
|
|
||||||
enable = canOpenNewBrowser;
|
enable = canOpenNewBrowser;
|
||||||
break;
|
} else if (tag == IDC_TASK_MANAGER) {
|
||||||
case IDC_TASK_MANAGER:
|
|
||||||
enable = YES;
|
enable = YES;
|
||||||
break;
|
} else if (tag == IDC_NEW_INCOGNITO_WINDOW) {
|
||||||
case IDC_NEW_INCOGNITO_WINDOW:
|
|
||||||
enable = canOpenNewBrowser;
|
enable = canOpenNewBrowser;
|
||||||
break;
|
} else {
|
||||||
default:
|
|
||||||
enable = ![self keyWindowIsModal];
|
enable = ![self keyWindowIsModal];
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
} else if ([self respondsToSelector:action]) {
|
} else if ([self respondsToSelector:action]) {
|
||||||
// All other selectors that this class implements.
|
// All other selectors that this class implements.
|
||||||
@ -469,12 +476,16 @@ void RemoveMenuItem(NSMenu* menu, SEL action_selector) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Version-safe static declarations of IDC variables using names from
|
||||||
|
// cef_command_ids.h.
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_FIND);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_FIND_NEXT);
|
||||||
|
CEF_DECLARE_COMMAND_ID(IDC_FIND_PREVIOUS);
|
||||||
|
|
||||||
// Handle specific commands where we want to make the last active browser
|
// Handle specific commands where we want to make the last active browser
|
||||||
// frontmost and then re-execute the command.
|
// frontmost and then re-execute the command.
|
||||||
switch ([sender tag]) {
|
const auto tag = [sender tag];
|
||||||
case IDC_FIND:
|
if (tag == IDC_FIND || tag == IDC_FIND_NEXT || tag == IDC_FIND_PREVIOUS) {
|
||||||
case IDC_FIND_NEXT:
|
|
||||||
case IDC_FIND_PREVIOUS:
|
|
||||||
if (id window = [self getActiveBrowserNSWindow]) {
|
if (id window = [self getActiveBrowserNSWindow]) {
|
||||||
[window makeKeyAndOrderFront:nil];
|
[window makeKeyAndOrderFront:nil];
|
||||||
if ([window respondsToSelector:@selector(commandDispatch:)]) {
|
if ([window respondsToSelector:@selector(commandDispatch:)]) {
|
||||||
@ -482,9 +493,6 @@ void RemoveMenuItem(NSMenu* menu, SEL action_selector) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(INFO) << "Unhandled commandDispatch: for tag " << [sender tag];
|
LOG(INFO) << "Unhandled commandDispatch: for tag " << [sender tag];
|
||||||
|
868
tests/ceftests/api_version_unittest.cc
Normal file
868
tests/ceftests/api_version_unittest.cc
Normal file
@ -0,0 +1,868 @@
|
|||||||
|
// Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
|
||||||
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "include/test/cef_api_version_test.h"
|
||||||
|
#include "tests/ceftests/test_handler.h"
|
||||||
|
#include "tests/gtest/include/gtest/gtest.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static int GetValue(T& obj) {
|
||||||
|
#if CEF_API_REMOVED(13301)
|
||||||
|
return obj->GetValue();
|
||||||
|
#elif CEF_API_RANGE(13301, 13302)
|
||||||
|
return obj->GetValueV1();
|
||||||
|
#elif CEF_API_ADDED(13302)
|
||||||
|
return obj->GetValueV2();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CefRefPtr<CefApiVersionTestRefPtrLibrary> CreateRefPtrLibrary(int val) {
|
||||||
|
#if CEF_API_ADDED(13301)
|
||||||
|
return CefApiVersionTestRefPtrLibrary::Create(val);
|
||||||
|
#else
|
||||||
|
auto obj = CefApiVersionTestRefPtrLibrary::Create();
|
||||||
|
obj->SetValue(val);
|
||||||
|
return obj;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CefRefPtr<CefApiVersionTestRefPtrLibraryChild> CreateRefPtrLibraryChild(
|
||||||
|
int val1,
|
||||||
|
int val2) {
|
||||||
|
#if CEF_API_ADDED(13301)
|
||||||
|
return CefApiVersionTestRefPtrLibraryChild::Create(val1, val2);
|
||||||
|
#else
|
||||||
|
auto obj = CefApiVersionTestRefPtrLibraryChild::Create();
|
||||||
|
obj->SetValue(val1);
|
||||||
|
obj->SetOtherValue(val2);
|
||||||
|
return obj;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CEF_API_REMOVED(13301)
|
||||||
|
CefRefPtr<CefApiVersionTestRefPtrLibraryChildChild>
|
||||||
|
#elif CEF_API_RANGE(13301, 13302)
|
||||||
|
CefRefPtr<CefApiVersionTestRefPtrLibraryChildChildV1>
|
||||||
|
#elif CEF_API_ADDED(13302)
|
||||||
|
CefRefPtr<CefApiVersionTestRefPtrLibraryChildChildV2>
|
||||||
|
#endif
|
||||||
|
CreateRefPtrLibraryChildChild(int val1, int val2, int val3) {
|
||||||
|
#if CEF_API_REMOVED(13301)
|
||||||
|
auto obj = CefApiVersionTestRefPtrLibraryChildChild::Create();
|
||||||
|
obj->SetValue(val1);
|
||||||
|
obj->SetOtherValue(val2);
|
||||||
|
obj->SetOtherOtherValue(val3);
|
||||||
|
return obj;
|
||||||
|
#elif CEF_API_RANGE(13301, 13302)
|
||||||
|
return CefApiVersionTestRefPtrLibraryChildChildV1::Create(val1, val2, val3);
|
||||||
|
#elif CEF_API_ADDED(13302)
|
||||||
|
return CefApiVersionTestRefPtrLibraryChildChildV2::Create(val1, val2, val3);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Test getting/setting library-side RefPtr types.
|
||||||
|
TEST(ApiVersionTest, RefPtrLibrary) {
|
||||||
|
CefRefPtr<CefApiVersionTest> obj = CefApiVersionTest::Create();
|
||||||
|
|
||||||
|
const int kTestVal = 12;
|
||||||
|
CefRefPtr<CefApiVersionTestRefPtrLibrary> test_obj =
|
||||||
|
CreateRefPtrLibrary(kTestVal);
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj));
|
||||||
|
int retval = obj->SetRefPtrLibrary(test_obj);
|
||||||
|
EXPECT_EQ(kTestVal, retval);
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj));
|
||||||
|
|
||||||
|
const int kTestVal2 = 30;
|
||||||
|
CefRefPtr<CefApiVersionTestRefPtrLibrary> test_obj2 =
|
||||||
|
obj->GetRefPtrLibrary(kTestVal2);
|
||||||
|
EXPECT_EQ(kTestVal2, GetValue(test_obj2));
|
||||||
|
int retval2 = obj->SetRefPtrLibrary(test_obj2);
|
||||||
|
EXPECT_EQ(kTestVal2, retval2);
|
||||||
|
EXPECT_EQ(kTestVal2, GetValue(test_obj2));
|
||||||
|
|
||||||
|
// Only one reference to the object should exist.
|
||||||
|
EXPECT_TRUE(obj->HasOneRef());
|
||||||
|
EXPECT_TRUE(test_obj->HasOneRef());
|
||||||
|
EXPECT_TRUE(test_obj2->HasOneRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test getting/setting inherited library-side RefPtr types.
|
||||||
|
TEST(ApiVersionTest, RefPtrLibraryInherit) {
|
||||||
|
CefRefPtr<CefApiVersionTest> obj = CefApiVersionTest::Create();
|
||||||
|
|
||||||
|
const int kTestVal = 12;
|
||||||
|
const int kTestVal2 = 40;
|
||||||
|
auto test_obj = CreateRefPtrLibraryChild(kTestVal, kTestVal2);
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj));
|
||||||
|
EXPECT_EQ(kTestVal2, test_obj->GetOtherValue());
|
||||||
|
int retval = obj->SetRefPtrLibrary(test_obj);
|
||||||
|
EXPECT_EQ(kTestVal, retval);
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj));
|
||||||
|
EXPECT_EQ(kTestVal2, test_obj->GetOtherValue());
|
||||||
|
|
||||||
|
EXPECT_EQ(kTestVal, obj->SetChildRefPtrLibrary(test_obj));
|
||||||
|
auto parent = obj->SetChildRefPtrLibraryAndReturnParent(test_obj);
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(parent));
|
||||||
|
parent = nullptr;
|
||||||
|
|
||||||
|
const int kTestVal3 = 100;
|
||||||
|
auto test_obj2 =
|
||||||
|
CreateRefPtrLibraryChildChild(kTestVal, kTestVal2, kTestVal3);
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj2));
|
||||||
|
EXPECT_EQ(kTestVal2, test_obj2->GetOtherValue());
|
||||||
|
EXPECT_EQ(kTestVal3, test_obj2->GetOtherOtherValue());
|
||||||
|
int retval2 = obj->SetRefPtrLibrary(test_obj2);
|
||||||
|
EXPECT_EQ(kTestVal, retval2);
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj2));
|
||||||
|
EXPECT_EQ(kTestVal2, test_obj2->GetOtherValue());
|
||||||
|
EXPECT_EQ(kTestVal3, test_obj2->GetOtherOtherValue());
|
||||||
|
|
||||||
|
EXPECT_EQ(kTestVal, obj->SetChildRefPtrLibrary(test_obj2));
|
||||||
|
auto parent2 = obj->SetChildRefPtrLibraryAndReturnParent(test_obj2);
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(parent2));
|
||||||
|
parent2 = nullptr;
|
||||||
|
|
||||||
|
// Only one reference to the object should exist.
|
||||||
|
EXPECT_TRUE(obj->HasOneRef());
|
||||||
|
EXPECT_TRUE(test_obj->HasOneRef());
|
||||||
|
EXPECT_TRUE(test_obj2->HasOneRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test getting/setting library-side RefPtr list types.
|
||||||
|
TEST(ApiVersionTest, RefPtrLibraryList) {
|
||||||
|
CefRefPtr<CefApiVersionTest> obj = CefApiVersionTest::Create();
|
||||||
|
|
||||||
|
const int kVal1 = 34;
|
||||||
|
const int kVal2 = 10;
|
||||||
|
|
||||||
|
CefRefPtr<CefApiVersionTestRefPtrLibrary> val1 = CreateRefPtrLibrary(kVal1);
|
||||||
|
CefRefPtr<CefApiVersionTestRefPtrLibrary> val2 =
|
||||||
|
CreateRefPtrLibraryChild(kVal2, 0);
|
||||||
|
|
||||||
|
std::vector<CefRefPtr<CefApiVersionTestRefPtrLibrary>> list;
|
||||||
|
list.push_back(val1);
|
||||||
|
list.push_back(val2);
|
||||||
|
EXPECT_TRUE(obj->SetRefPtrLibraryList(list, kVal1, kVal2));
|
||||||
|
|
||||||
|
list.clear();
|
||||||
|
EXPECT_TRUE(obj->GetRefPtrLibraryListByRef(list, kVal1, kVal2));
|
||||||
|
EXPECT_EQ(2U, list.size());
|
||||||
|
EXPECT_EQ(kVal1, GetValue(list[0]));
|
||||||
|
EXPECT_EQ(kVal2, GetValue(list[1]));
|
||||||
|
|
||||||
|
list.clear();
|
||||||
|
|
||||||
|
// Only one reference to the object should exist.
|
||||||
|
EXPECT_TRUE(obj->HasOneRef());
|
||||||
|
EXPECT_TRUE(val1->HasOneRef());
|
||||||
|
EXPECT_TRUE(val2->HasOneRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class ApiVersionTestRefPtrClient : public CefApiVersionTestRefPtrClient {
|
||||||
|
public:
|
||||||
|
explicit ApiVersionTestRefPtrClient(int val) : val_(val) {}
|
||||||
|
|
||||||
|
int GetValueLegacy() override { return val_legacy_; }
|
||||||
|
|
||||||
|
#if CEF_API_ADDED(CEF_EXPERIMENTAL)
|
||||||
|
int GetValueExp() override { return val_exp_; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CEF_API_REMOVED(13301)
|
||||||
|
int GetValue() override { return val_; }
|
||||||
|
#elif CEF_API_RANGE(13301, 13302)
|
||||||
|
int GetValueV1() override { return val_; }
|
||||||
|
#elif CEF_API_ADDED(13302)
|
||||||
|
int GetValueV2() override { return val_; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
const int val_;
|
||||||
|
int val_legacy_ = -1;
|
||||||
|
#if CEF_API_ADDED(CEF_EXPERIMENTAL)
|
||||||
|
int val_exp_ = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING(ApiVersionTestRefPtrClient);
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(ApiVersionTestRefPtrClient);
|
||||||
|
};
|
||||||
|
|
||||||
|
#if CEF_API_REMOVED(13302)
|
||||||
|
|
||||||
|
class ApiVersionTestRefPtrClientChild
|
||||||
|
: public CefApiVersionTestRefPtrClientChild {
|
||||||
|
public:
|
||||||
|
ApiVersionTestRefPtrClientChild(int val, int other_val)
|
||||||
|
: val_(val), other_val_(other_val) {}
|
||||||
|
|
||||||
|
int GetValueLegacy() override { return val_legacy_; }
|
||||||
|
|
||||||
|
#if CEF_API_ADDED(CEF_EXPERIMENTAL)
|
||||||
|
int GetValueExp() override { return val_exp_; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CEF_API_REMOVED(13301)
|
||||||
|
int GetValue() override { return val_; }
|
||||||
|
#elif CEF_API_RANGE(13301, 13302)
|
||||||
|
int GetValueV1() override { return val_; }
|
||||||
|
#elif CEF_API_ADDED(13302)
|
||||||
|
int GetValueV2() override { return val_; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CEF_API_REMOVED(13301)
|
||||||
|
int GetOtherValue() override { return other_val_; }
|
||||||
|
#else
|
||||||
|
int GetOtherValueV1() override { return other_val_; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
const int val_;
|
||||||
|
const int other_val_;
|
||||||
|
int val_legacy_ = -1;
|
||||||
|
#if CEF_API_ADDED(CEF_EXPERIMENTAL)
|
||||||
|
int val_exp_ = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING(ApiVersionTestRefPtrClientChild);
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(ApiVersionTestRefPtrClientChild);
|
||||||
|
};
|
||||||
|
|
||||||
|
using ApiVersionTestRefPtrClientChildType = ApiVersionTestRefPtrClientChild;
|
||||||
|
|
||||||
|
#else // CEF_API_ADDED(13302)
|
||||||
|
|
||||||
|
class ApiVersionTestRefPtrClientChildV2
|
||||||
|
: public CefApiVersionTestRefPtrClientChildV2 {
|
||||||
|
public:
|
||||||
|
ApiVersionTestRefPtrClientChildV2(int val, int other_val)
|
||||||
|
: val_(val), other_val_(other_val) {}
|
||||||
|
|
||||||
|
int GetValueLegacy() override { return val_legacy_; }
|
||||||
|
|
||||||
|
#if CEF_API_ADDED(CEF_EXPERIMENTAL)
|
||||||
|
int GetValueExp() override { return val_exp_; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CEF_API_REMOVED(13301)
|
||||||
|
int GetValue() override { return val_; }
|
||||||
|
#elif CEF_API_RANGE(13301, 13302)
|
||||||
|
int GetValueV1() override { return val_; }
|
||||||
|
#elif CEF_API_ADDED(13302)
|
||||||
|
int GetValueV2() override { return val_; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int GetOtherValue() override { return other_val_; }
|
||||||
|
|
||||||
|
#if CEF_API_ADDED(13303)
|
||||||
|
int GetAnotherValue() override { return another_val_; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
const int val_;
|
||||||
|
const int other_val_;
|
||||||
|
#if CEF_API_ADDED(13303)
|
||||||
|
int another_val_ = -1;
|
||||||
|
#endif
|
||||||
|
int val_legacy_ = -1;
|
||||||
|
#if CEF_API_ADDED(CEF_EXPERIMENTAL)
|
||||||
|
int val_exp_ = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING(ApiVersionTestRefPtrClientChildV2);
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(ApiVersionTestRefPtrClientChildV2);
|
||||||
|
};
|
||||||
|
|
||||||
|
using ApiVersionTestRefPtrClientChildType = ApiVersionTestRefPtrClientChildV2;
|
||||||
|
|
||||||
|
#endif // CEF_API_ADDED(13302)
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static int GetOtherValue(T& obj) {
|
||||||
|
#if CEF_API_REMOVED(13301)
|
||||||
|
// ApiVersionTestRefPtrClientChild
|
||||||
|
return obj->GetOtherValue();
|
||||||
|
#elif CEF_API_RANGE(13301, 13302)
|
||||||
|
// ApiVersionTestRefPtrClientChild
|
||||||
|
return obj->GetOtherValueV1();
|
||||||
|
#elif CEF_API_ADDED(13302)
|
||||||
|
// ApiVersionTestRefPtrClientChildV2
|
||||||
|
return obj->GetOtherValue();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Test getting/setting client-side RefPtr types.
|
||||||
|
TEST(ApiVersionTest, RefPtrClient) {
|
||||||
|
CefRefPtr<CefApiVersionTest> obj = CefApiVersionTest::Create();
|
||||||
|
|
||||||
|
const int kTestVal = 12;
|
||||||
|
|
||||||
|
CefRefPtr<ApiVersionTestRefPtrClient> test_obj =
|
||||||
|
new ApiVersionTestRefPtrClient(kTestVal);
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj));
|
||||||
|
EXPECT_EQ(kTestVal, obj->SetRefPtrClient(test_obj.get()));
|
||||||
|
CefRefPtr<CefApiVersionTestRefPtrClient> handler =
|
||||||
|
obj->SetRefPtrClientAndReturn(test_obj.get());
|
||||||
|
EXPECT_EQ(test_obj.get(), handler.get());
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(handler));
|
||||||
|
handler = nullptr;
|
||||||
|
|
||||||
|
// Only one reference to the object should exist.
|
||||||
|
EXPECT_TRUE(obj->HasOneRef());
|
||||||
|
EXPECT_TRUE(test_obj->HasOneRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test getting/setting inherited client-side RefPtr types.
|
||||||
|
TEST(ApiVersionTest, RefPtrClientInherit) {
|
||||||
|
CefRefPtr<CefApiVersionTest> obj = CefApiVersionTest::Create();
|
||||||
|
|
||||||
|
const int kTestVal = 12;
|
||||||
|
const int kTestVal2 = 86;
|
||||||
|
|
||||||
|
CefRefPtr<ApiVersionTestRefPtrClientChildType> test_obj =
|
||||||
|
new ApiVersionTestRefPtrClientChildType(kTestVal, kTestVal2);
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj));
|
||||||
|
EXPECT_EQ(kTestVal2, GetOtherValue(test_obj));
|
||||||
|
int retval = obj->SetRefPtrClient(test_obj);
|
||||||
|
EXPECT_EQ(kTestVal, retval);
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj));
|
||||||
|
EXPECT_EQ(kTestVal2, GetOtherValue(test_obj));
|
||||||
|
|
||||||
|
EXPECT_EQ(kTestVal, obj->SetChildRefPtrClient(test_obj));
|
||||||
|
CefRefPtr<CefApiVersionTestRefPtrClient> handler =
|
||||||
|
obj->SetChildRefPtrClientAndReturnParent(test_obj);
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(handler));
|
||||||
|
EXPECT_EQ(test_obj.get(), handler.get());
|
||||||
|
handler = nullptr;
|
||||||
|
|
||||||
|
// Only one reference to the object should exist.
|
||||||
|
EXPECT_TRUE(obj->HasOneRef());
|
||||||
|
EXPECT_TRUE(test_obj->HasOneRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test getting/setting client-side RefPtr list types.
|
||||||
|
TEST(ApiVersionTest, RefPtrClientList) {
|
||||||
|
CefRefPtr<CefApiVersionTest> obj = CefApiVersionTest::Create();
|
||||||
|
|
||||||
|
const int kVal1 = 34;
|
||||||
|
const int kVal2 = 10;
|
||||||
|
|
||||||
|
CefRefPtr<CefApiVersionTestRefPtrClient> val1 =
|
||||||
|
new ApiVersionTestRefPtrClient(kVal1);
|
||||||
|
CefRefPtr<CefApiVersionTestRefPtrClient> val2 =
|
||||||
|
new ApiVersionTestRefPtrClientChildType(kVal2, 0);
|
||||||
|
|
||||||
|
std::vector<CefRefPtr<CefApiVersionTestRefPtrClient>> list;
|
||||||
|
list.push_back(val1);
|
||||||
|
list.push_back(val2);
|
||||||
|
EXPECT_TRUE(obj->SetRefPtrClientList(list, kVal1, kVal2));
|
||||||
|
|
||||||
|
list.clear();
|
||||||
|
EXPECT_TRUE(obj->GetRefPtrClientListByRef(list, val1, val2));
|
||||||
|
EXPECT_EQ(2U, list.size());
|
||||||
|
EXPECT_EQ(kVal1, GetValue(list[0]));
|
||||||
|
EXPECT_EQ(val1.get(), list[0].get());
|
||||||
|
EXPECT_EQ(kVal2, GetValue(list[1]));
|
||||||
|
EXPECT_EQ(val2.get(), list[1].get());
|
||||||
|
|
||||||
|
list.clear();
|
||||||
|
|
||||||
|
// Only one reference to the object should exist.
|
||||||
|
EXPECT_TRUE(obj->HasOneRef());
|
||||||
|
EXPECT_TRUE(val1->HasOneRef());
|
||||||
|
EXPECT_TRUE(val2->HasOneRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
CefOwnPtr<CefApiVersionTestScopedLibrary> CreateScopedLibrary(int val) {
|
||||||
|
#if CEF_API_ADDED(13301)
|
||||||
|
return CefApiVersionTestScopedLibrary::Create(val);
|
||||||
|
#else
|
||||||
|
auto obj = CefApiVersionTestScopedLibrary::Create();
|
||||||
|
obj->SetValue(val);
|
||||||
|
return obj;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CefOwnPtr<CefApiVersionTestScopedLibraryChild> CreateScopedLibraryChild(
|
||||||
|
int val1,
|
||||||
|
int val2) {
|
||||||
|
#if CEF_API_ADDED(13301)
|
||||||
|
return CefApiVersionTestScopedLibraryChild::Create(val1, val2);
|
||||||
|
#else
|
||||||
|
auto obj = CefApiVersionTestScopedLibraryChild::Create();
|
||||||
|
obj->SetValue(val1);
|
||||||
|
obj->SetOtherValue(val2);
|
||||||
|
return obj;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CEF_API_REMOVED(13301)
|
||||||
|
CefOwnPtr<CefApiVersionTestScopedLibraryChildChild>
|
||||||
|
#elif CEF_API_RANGE(13301, 13302)
|
||||||
|
CefOwnPtr<CefApiVersionTestScopedLibraryChildChildV1>
|
||||||
|
#elif CEF_API_ADDED(13302)
|
||||||
|
CefOwnPtr<CefApiVersionTestScopedLibraryChildChildV2>
|
||||||
|
#endif
|
||||||
|
CreateScopedLibraryChildChild(int val1, int val2, int val3) {
|
||||||
|
#if CEF_API_REMOVED(13301)
|
||||||
|
auto obj = CefApiVersionTestScopedLibraryChildChild::Create();
|
||||||
|
obj->SetValue(val1);
|
||||||
|
obj->SetOtherValue(val2);
|
||||||
|
obj->SetOtherOtherValue(val3);
|
||||||
|
return obj;
|
||||||
|
#elif CEF_API_RANGE(13301, 13302)
|
||||||
|
return CefApiVersionTestScopedLibraryChildChildV1::Create(val1, val2, val3);
|
||||||
|
#elif CEF_API_ADDED(13302)
|
||||||
|
return CefApiVersionTestScopedLibraryChildChildV2::Create(val1, val2, val3);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Test getting/setting library-side OwnPtr types.
|
||||||
|
TEST(ApiVersionTest, OwnPtrLibrary) {
|
||||||
|
CefRefPtr<CefApiVersionTest> obj = CefApiVersionTest::Create();
|
||||||
|
|
||||||
|
const int kTestVal = 12;
|
||||||
|
CefOwnPtr<CefApiVersionTestScopedLibrary> test_obj =
|
||||||
|
CreateScopedLibrary(kTestVal);
|
||||||
|
EXPECT_TRUE(test_obj.get());
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj));
|
||||||
|
int retval = obj->SetOwnPtrLibrary(std::move(test_obj));
|
||||||
|
EXPECT_EQ(kTestVal, retval);
|
||||||
|
EXPECT_FALSE(test_obj.get());
|
||||||
|
|
||||||
|
const int kTestVal2 = 30;
|
||||||
|
CefOwnPtr<CefApiVersionTestScopedLibrary> test_obj2 =
|
||||||
|
obj->GetOwnPtrLibrary(kTestVal2);
|
||||||
|
EXPECT_TRUE(test_obj2.get());
|
||||||
|
EXPECT_EQ(kTestVal2, GetValue(test_obj2));
|
||||||
|
int retval2 = obj->SetOwnPtrLibrary(std::move(test_obj2));
|
||||||
|
EXPECT_EQ(kTestVal2, retval2);
|
||||||
|
EXPECT_FALSE(test_obj2.get());
|
||||||
|
|
||||||
|
// Only one reference to the object should exist.
|
||||||
|
EXPECT_TRUE(obj->HasOneRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test getting/setting inherited library-side OwnPtr types.
|
||||||
|
TEST(ApiVersionTest, OwnPtrLibraryInherit) {
|
||||||
|
CefRefPtr<CefApiVersionTest> obj = CefApiVersionTest::Create();
|
||||||
|
|
||||||
|
const int kTestVal = 12;
|
||||||
|
const int kTestVal2 = 40;
|
||||||
|
auto test_obj = CreateScopedLibraryChild(kTestVal, kTestVal2);
|
||||||
|
EXPECT_TRUE(test_obj.get());
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj));
|
||||||
|
EXPECT_EQ(kTestVal2, test_obj->GetOtherValue());
|
||||||
|
int retval = obj->SetOwnPtrLibrary(std::move(test_obj));
|
||||||
|
EXPECT_EQ(kTestVal, retval);
|
||||||
|
EXPECT_FALSE(test_obj.get());
|
||||||
|
|
||||||
|
test_obj = CreateScopedLibraryChild(kTestVal, kTestVal2);
|
||||||
|
EXPECT_TRUE(test_obj.get());
|
||||||
|
EXPECT_EQ(kTestVal, obj->SetChildOwnPtrLibrary(std::move(test_obj)));
|
||||||
|
EXPECT_FALSE(test_obj.get());
|
||||||
|
|
||||||
|
test_obj = CreateScopedLibraryChild(kTestVal, kTestVal2);
|
||||||
|
EXPECT_TRUE(test_obj.get());
|
||||||
|
CefOwnPtr<CefApiVersionTestScopedLibrary> test_obj_parent =
|
||||||
|
obj->SetChildOwnPtrLibraryAndReturnParent(std::move(test_obj));
|
||||||
|
EXPECT_FALSE(test_obj.get());
|
||||||
|
EXPECT_TRUE(test_obj_parent.get());
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj_parent));
|
||||||
|
test_obj_parent.reset(nullptr);
|
||||||
|
|
||||||
|
const int kTestVal3 = 100;
|
||||||
|
auto test_obj2 =
|
||||||
|
CreateScopedLibraryChildChild(kTestVal, kTestVal2, kTestVal3);
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj2));
|
||||||
|
EXPECT_EQ(kTestVal2, test_obj2->GetOtherValue());
|
||||||
|
EXPECT_EQ(kTestVal3, test_obj2->GetOtherOtherValue());
|
||||||
|
int retval2 = obj->SetOwnPtrLibrary(std::move(test_obj2));
|
||||||
|
EXPECT_EQ(kTestVal, retval2);
|
||||||
|
EXPECT_FALSE(test_obj2.get());
|
||||||
|
|
||||||
|
test_obj2 = CreateScopedLibraryChildChild(kTestVal, kTestVal2, kTestVal3);
|
||||||
|
EXPECT_EQ(kTestVal, obj->SetChildOwnPtrLibrary(std::move(test_obj2)));
|
||||||
|
EXPECT_FALSE(test_obj2.get());
|
||||||
|
|
||||||
|
test_obj2 = CreateScopedLibraryChildChild(kTestVal, kTestVal2, kTestVal3);
|
||||||
|
test_obj_parent =
|
||||||
|
obj->SetChildOwnPtrLibraryAndReturnParent(std::move(test_obj2));
|
||||||
|
EXPECT_FALSE(test_obj2.get());
|
||||||
|
EXPECT_TRUE(test_obj_parent.get());
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj_parent));
|
||||||
|
test_obj_parent.reset(nullptr);
|
||||||
|
|
||||||
|
// Only one reference to the object should exist.
|
||||||
|
EXPECT_TRUE(obj->HasOneRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class ApiVersionTestScopedClient : public CefApiVersionTestScopedClient {
|
||||||
|
public:
|
||||||
|
ApiVersionTestScopedClient(int val, TrackCallback* got_delete)
|
||||||
|
: val_(val), got_delete_(got_delete) {}
|
||||||
|
~ApiVersionTestScopedClient() override { got_delete_->yes(); }
|
||||||
|
|
||||||
|
int GetValueLegacy() override { return val_legacy_; }
|
||||||
|
|
||||||
|
#if CEF_API_ADDED(CEF_EXPERIMENTAL)
|
||||||
|
int GetValueExp() override { return val_exp_; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CEF_API_REMOVED(13301)
|
||||||
|
int GetValue() override { return val_; }
|
||||||
|
#elif CEF_API_RANGE(13301, 13302)
|
||||||
|
int GetValueV1() override { return val_; }
|
||||||
|
#elif CEF_API_ADDED(13302)
|
||||||
|
int GetValueV2() override { return val_; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
const int val_;
|
||||||
|
int val_legacy_ = -1;
|
||||||
|
#if CEF_API_ADDED(CEF_EXPERIMENTAL)
|
||||||
|
int val_exp_ = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TrackCallback* got_delete_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(ApiVersionTestScopedClient);
|
||||||
|
};
|
||||||
|
|
||||||
|
#if CEF_API_REMOVED(13302)
|
||||||
|
|
||||||
|
class ApiVersionTestScopedClientChild
|
||||||
|
: public CefApiVersionTestScopedClientChild {
|
||||||
|
public:
|
||||||
|
ApiVersionTestScopedClientChild(int val,
|
||||||
|
int other_val,
|
||||||
|
TrackCallback* got_delete)
|
||||||
|
: val_(val), other_val_(other_val), got_delete_(got_delete) {}
|
||||||
|
~ApiVersionTestScopedClientChild() override { got_delete_->yes(); }
|
||||||
|
|
||||||
|
int GetValueLegacy() override { return val_legacy_; }
|
||||||
|
|
||||||
|
#if CEF_API_ADDED(CEF_EXPERIMENTAL)
|
||||||
|
int GetValueExp() override { return val_exp_; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CEF_API_REMOVED(13301)
|
||||||
|
int GetValue() override { return val_; }
|
||||||
|
#elif CEF_API_RANGE(13301, 13302)
|
||||||
|
int GetValueV1() override { return val_; }
|
||||||
|
#elif CEF_API_ADDED(13302)
|
||||||
|
int GetValueV2() override { return val_; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CEF_API_REMOVED(13301)
|
||||||
|
int GetOtherValue() override { return other_val_; }
|
||||||
|
#else
|
||||||
|
int GetOtherValueV1() override { return other_val_; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
const int val_;
|
||||||
|
const int other_val_;
|
||||||
|
int val_legacy_ = -1;
|
||||||
|
#if CEF_API_ADDED(CEF_EXPERIMENTAL)
|
||||||
|
int val_exp_ = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TrackCallback* got_delete_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(ApiVersionTestScopedClientChild);
|
||||||
|
};
|
||||||
|
|
||||||
|
using ApiVersionTestScopedClientChildType = ApiVersionTestScopedClientChild;
|
||||||
|
|
||||||
|
#else // CEF_API_ADDED(13302)
|
||||||
|
|
||||||
|
class ApiVersionTestScopedClientChildV2
|
||||||
|
: public CefApiVersionTestScopedClientChildV2 {
|
||||||
|
public:
|
||||||
|
ApiVersionTestScopedClientChildV2(int val,
|
||||||
|
int other_val,
|
||||||
|
TrackCallback* got_delete)
|
||||||
|
: val_(val), other_val_(other_val), got_delete_(got_delete) {}
|
||||||
|
~ApiVersionTestScopedClientChildV2() override { got_delete_->yes(); }
|
||||||
|
|
||||||
|
int GetValueLegacy() override { return val_legacy_; }
|
||||||
|
|
||||||
|
#if CEF_API_ADDED(CEF_EXPERIMENTAL)
|
||||||
|
int GetValueExp() override { return val_exp_; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CEF_API_REMOVED(13301)
|
||||||
|
int GetValue() override { return val_; }
|
||||||
|
#elif CEF_API_RANGE(13301, 13302)
|
||||||
|
int GetValueV1() override { return val_; }
|
||||||
|
#elif CEF_API_ADDED(13302)
|
||||||
|
int GetValueV2() override { return val_; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int GetOtherValue() override { return other_val_; }
|
||||||
|
|
||||||
|
#if CEF_API_ADDED(13303)
|
||||||
|
int GetAnotherValue() override { return another_val_; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
const int val_;
|
||||||
|
const int other_val_;
|
||||||
|
#if CEF_API_ADDED(13303)
|
||||||
|
int another_val_ = -1;
|
||||||
|
#endif
|
||||||
|
int val_legacy_ = -1;
|
||||||
|
#if CEF_API_ADDED(CEF_EXPERIMENTAL)
|
||||||
|
int val_exp_ = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TrackCallback* got_delete_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(ApiVersionTestScopedClientChildV2);
|
||||||
|
};
|
||||||
|
|
||||||
|
using ApiVersionTestScopedClientChildType = ApiVersionTestScopedClientChildV2;
|
||||||
|
|
||||||
|
#endif // CEF_API_ADDED(13302)
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// Test getting/setting client-side OwnPtr types.
|
||||||
|
TEST(ApiVersionTest, OwnPtrClient) {
|
||||||
|
CefRefPtr<CefApiVersionTest> obj = CefApiVersionTest::Create();
|
||||||
|
|
||||||
|
const int kTestVal = 12;
|
||||||
|
TrackCallback got_delete;
|
||||||
|
|
||||||
|
CefOwnPtr<CefApiVersionTestScopedClient> test_obj(
|
||||||
|
new ApiVersionTestScopedClient(kTestVal, &got_delete));
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj));
|
||||||
|
EXPECT_EQ(kTestVal, obj->SetOwnPtrClient(std::move(test_obj)));
|
||||||
|
EXPECT_FALSE(test_obj.get());
|
||||||
|
EXPECT_TRUE(got_delete);
|
||||||
|
|
||||||
|
got_delete.reset();
|
||||||
|
test_obj =
|
||||||
|
std::make_unique<ApiVersionTestScopedClient>(kTestVal, &got_delete);
|
||||||
|
CefOwnPtr<CefApiVersionTestScopedClient> handler =
|
||||||
|
obj->SetOwnPtrClientAndReturn(std::move(test_obj));
|
||||||
|
EXPECT_FALSE(test_obj.get());
|
||||||
|
EXPECT_TRUE(handler.get());
|
||||||
|
EXPECT_FALSE(got_delete);
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(handler));
|
||||||
|
handler.reset(nullptr);
|
||||||
|
EXPECT_TRUE(got_delete);
|
||||||
|
|
||||||
|
// Only one reference to the object should exist.
|
||||||
|
EXPECT_TRUE(obj->HasOneRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test getting/setting inherited client-side OwnPtr types.
|
||||||
|
TEST(ApiVersionTest, OwnPtrClientInherit) {
|
||||||
|
CefRefPtr<CefApiVersionTest> obj = CefApiVersionTest::Create();
|
||||||
|
|
||||||
|
const int kTestVal = 12;
|
||||||
|
const int kTestVal2 = 86;
|
||||||
|
TrackCallback got_delete;
|
||||||
|
|
||||||
|
CefOwnPtr<ApiVersionTestScopedClientChildType> test_obj(
|
||||||
|
new ApiVersionTestScopedClientChildType(kTestVal, kTestVal2,
|
||||||
|
&got_delete));
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj));
|
||||||
|
EXPECT_EQ(kTestVal2, GetOtherValue(test_obj));
|
||||||
|
EXPECT_EQ(kTestVal, obj->SetOwnPtrClient(std::move(test_obj)));
|
||||||
|
EXPECT_FALSE(test_obj.get());
|
||||||
|
EXPECT_TRUE(got_delete);
|
||||||
|
|
||||||
|
got_delete.reset();
|
||||||
|
test_obj = std::make_unique<ApiVersionTestScopedClientChildType>(
|
||||||
|
kTestVal, kTestVal2, &got_delete);
|
||||||
|
EXPECT_EQ(kTestVal, obj->SetChildOwnPtrClient(std::move(test_obj)));
|
||||||
|
EXPECT_FALSE(test_obj.get());
|
||||||
|
EXPECT_TRUE(got_delete);
|
||||||
|
|
||||||
|
got_delete.reset();
|
||||||
|
test_obj = std::make_unique<ApiVersionTestScopedClientChildType>(
|
||||||
|
kTestVal, kTestVal2, &got_delete);
|
||||||
|
CefOwnPtr<CefApiVersionTestScopedClient> handler(
|
||||||
|
obj->SetChildOwnPtrClientAndReturnParent(std::move(test_obj)));
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(handler));
|
||||||
|
EXPECT_FALSE(test_obj.get());
|
||||||
|
EXPECT_FALSE(got_delete);
|
||||||
|
handler.reset(nullptr);
|
||||||
|
EXPECT_TRUE(got_delete);
|
||||||
|
|
||||||
|
// Only one reference to the object should exist.
|
||||||
|
EXPECT_TRUE(obj->HasOneRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test getting/setting library-side RawPtr types.
|
||||||
|
TEST(ApiVersionTest, RawPtrLibrary) {
|
||||||
|
CefRefPtr<CefApiVersionTest> obj = CefApiVersionTest::Create();
|
||||||
|
|
||||||
|
const int kTestVal = 12;
|
||||||
|
auto test_obj = CreateScopedLibrary(kTestVal);
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj));
|
||||||
|
int retval = obj->SetRawPtrLibrary(test_obj.get());
|
||||||
|
EXPECT_EQ(kTestVal, retval);
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj));
|
||||||
|
|
||||||
|
const int kTestVal2 = 30;
|
||||||
|
auto test_obj2 = obj->GetOwnPtrLibrary(kTestVal2);
|
||||||
|
EXPECT_EQ(kTestVal2, GetValue(test_obj2));
|
||||||
|
int retval2 = obj->SetRawPtrLibrary(test_obj2.get());
|
||||||
|
EXPECT_EQ(kTestVal2, retval2);
|
||||||
|
EXPECT_EQ(kTestVal2, GetValue(test_obj2));
|
||||||
|
|
||||||
|
// Only one reference to the object should exist.
|
||||||
|
EXPECT_TRUE(obj->HasOneRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test getting/setting inherited library-side RawPtr types.
|
||||||
|
TEST(ApiVersionTest, RawPtrLibraryInherit) {
|
||||||
|
CefRefPtr<CefApiVersionTest> obj = CefApiVersionTest::Create();
|
||||||
|
|
||||||
|
const int kTestVal = 12;
|
||||||
|
const int kTestVal2 = 40;
|
||||||
|
auto test_obj = CreateScopedLibraryChild(kTestVal, kTestVal2);
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj));
|
||||||
|
EXPECT_EQ(kTestVal2, test_obj->GetOtherValue());
|
||||||
|
int retval = obj->SetRawPtrLibrary(test_obj.get());
|
||||||
|
EXPECT_EQ(kTestVal, retval);
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj));
|
||||||
|
EXPECT_EQ(kTestVal2, test_obj->GetOtherValue());
|
||||||
|
|
||||||
|
EXPECT_EQ(kTestVal, obj->SetChildRawPtrLibrary(test_obj.get()));
|
||||||
|
|
||||||
|
const int kTestVal3 = 100;
|
||||||
|
auto test_obj2 =
|
||||||
|
CreateScopedLibraryChildChild(kTestVal, kTestVal2, kTestVal3);
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj2));
|
||||||
|
EXPECT_EQ(kTestVal2, test_obj2->GetOtherValue());
|
||||||
|
EXPECT_EQ(kTestVal3, test_obj2->GetOtherOtherValue());
|
||||||
|
int retval2 = obj->SetRawPtrLibrary(test_obj2.get());
|
||||||
|
EXPECT_EQ(kTestVal, retval2);
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj2));
|
||||||
|
EXPECT_EQ(kTestVal2, test_obj2->GetOtherValue());
|
||||||
|
EXPECT_EQ(kTestVal3, test_obj2->GetOtherOtherValue());
|
||||||
|
|
||||||
|
EXPECT_EQ(kTestVal, obj->SetChildRawPtrLibrary(test_obj2.get()));
|
||||||
|
|
||||||
|
// Only one reference to the object should exist.
|
||||||
|
EXPECT_TRUE(obj->HasOneRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test getting/setting library-side RawPtr list types.
|
||||||
|
TEST(ApiVersionTest, RawPtrLibraryList) {
|
||||||
|
CefRefPtr<CefApiVersionTest> obj = CefApiVersionTest::Create();
|
||||||
|
|
||||||
|
const int kVal1 = 34;
|
||||||
|
const int kVal2 = 10;
|
||||||
|
|
||||||
|
auto val1 = CreateScopedLibrary(kVal1);
|
||||||
|
auto val2 = CreateScopedLibraryChild(kVal2, 0);
|
||||||
|
|
||||||
|
std::vector<CefRawPtr<CefApiVersionTestScopedLibrary>> list;
|
||||||
|
list.push_back(val1.get());
|
||||||
|
list.push_back(val2.get());
|
||||||
|
EXPECT_TRUE(obj->SetRawPtrLibraryList(list, kVal1, kVal2));
|
||||||
|
list.clear();
|
||||||
|
|
||||||
|
// Only one reference to the object should exist.
|
||||||
|
EXPECT_TRUE(obj->HasOneRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test getting/setting client-side RawPtr types.
|
||||||
|
TEST(ApiVersionTest, RawPtrClient) {
|
||||||
|
CefRefPtr<CefApiVersionTest> obj = CefApiVersionTest::Create();
|
||||||
|
|
||||||
|
const int kTestVal = 12;
|
||||||
|
TrackCallback got_delete;
|
||||||
|
|
||||||
|
CefOwnPtr<ApiVersionTestScopedClient> test_obj(
|
||||||
|
new ApiVersionTestScopedClient(kTestVal, &got_delete));
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj));
|
||||||
|
EXPECT_EQ(kTestVal, obj->SetRawPtrClient(test_obj.get()));
|
||||||
|
EXPECT_FALSE(got_delete);
|
||||||
|
test_obj.reset(nullptr);
|
||||||
|
EXPECT_TRUE(got_delete);
|
||||||
|
|
||||||
|
// Only one reference to the object should exist.
|
||||||
|
EXPECT_TRUE(obj->HasOneRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test getting/setting inherited client-side RawPtr types.
|
||||||
|
TEST(ApiVersionTest, RawPtrClientInherit) {
|
||||||
|
CefRefPtr<CefApiVersionTest> obj = CefApiVersionTest::Create();
|
||||||
|
|
||||||
|
const int kTestVal = 12;
|
||||||
|
const int kTestVal2 = 86;
|
||||||
|
TrackCallback got_delete;
|
||||||
|
|
||||||
|
CefOwnPtr<ApiVersionTestScopedClientChildType> test_obj(
|
||||||
|
new ApiVersionTestScopedClientChildType(kTestVal, kTestVal2,
|
||||||
|
&got_delete));
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj));
|
||||||
|
EXPECT_EQ(kTestVal2, GetOtherValue(test_obj));
|
||||||
|
int retval = obj->SetRawPtrClient(test_obj.get());
|
||||||
|
EXPECT_EQ(kTestVal, retval);
|
||||||
|
EXPECT_EQ(kTestVal, GetValue(test_obj));
|
||||||
|
EXPECT_EQ(kTestVal2, GetOtherValue(test_obj));
|
||||||
|
EXPECT_FALSE(got_delete);
|
||||||
|
|
||||||
|
EXPECT_EQ(kTestVal, obj->SetChildRawPtrClient(test_obj.get()));
|
||||||
|
EXPECT_FALSE(got_delete);
|
||||||
|
test_obj.reset(nullptr);
|
||||||
|
EXPECT_TRUE(got_delete);
|
||||||
|
|
||||||
|
// Only one reference to the object should exist.
|
||||||
|
EXPECT_TRUE(obj->HasOneRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test getting/setting client-side RawPtr list types.
|
||||||
|
TEST(ApiVersionTest, RawPtrClientList) {
|
||||||
|
CefRefPtr<CefApiVersionTest> obj = CefApiVersionTest::Create();
|
||||||
|
|
||||||
|
const int kVal1 = 34;
|
||||||
|
const int kVal2 = 10;
|
||||||
|
TrackCallback got_delete1, got_delete2;
|
||||||
|
|
||||||
|
CefOwnPtr<CefApiVersionTestScopedClient> val1(
|
||||||
|
new ApiVersionTestScopedClient(kVal1, &got_delete1));
|
||||||
|
CefOwnPtr<CefApiVersionTestScopedClient> val2(
|
||||||
|
new ApiVersionTestScopedClientChildType(kVal2, 0, &got_delete2));
|
||||||
|
|
||||||
|
std::vector<CefRawPtr<CefApiVersionTestScopedClient>> list;
|
||||||
|
list.push_back(val1.get());
|
||||||
|
list.push_back(val2.get());
|
||||||
|
EXPECT_TRUE(obj->SetRawPtrClientList(list, kVal1, kVal2));
|
||||||
|
list.clear();
|
||||||
|
|
||||||
|
EXPECT_FALSE(got_delete1);
|
||||||
|
val1.reset(nullptr);
|
||||||
|
EXPECT_TRUE(got_delete1);
|
||||||
|
|
||||||
|
EXPECT_FALSE(got_delete2);
|
||||||
|
val2.reset(nullptr);
|
||||||
|
EXPECT_TRUE(got_delete2);
|
||||||
|
|
||||||
|
// Only one reference to the object should exist.
|
||||||
|
EXPECT_TRUE(obj->HasOneRef());
|
||||||
|
}
|
@ -3,7 +3,6 @@
|
|||||||
// can be found in the LICENSE file.
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
#include "include/base/cef_callback.h"
|
#include "include/base/cef_callback.h"
|
||||||
#include "include/cef_pack_resources.h"
|
|
||||||
#include "include/cef_request_context_handler.h"
|
#include "include/cef_request_context_handler.h"
|
||||||
#include "include/wrapper/cef_closure_task.h"
|
#include "include/wrapper/cef_closure_task.h"
|
||||||
#include "include/wrapper/cef_stream_resource_handler.h"
|
#include "include/wrapper/cef_stream_resource_handler.h"
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "include/base/cef_callback.h"
|
#include "include/base/cef_callback.h"
|
||||||
|
#include "include/cef_api_hash.h"
|
||||||
#include "include/cef_app.h"
|
#include "include/cef_app.h"
|
||||||
#include "include/cef_task.h"
|
#include "include/cef_task.h"
|
||||||
#include "include/cef_thread.h"
|
#include "include/cef_thread.h"
|
||||||
@ -136,6 +137,10 @@ class ScopedPlatformSetup final {
|
|||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
int exit_code;
|
int exit_code;
|
||||||
|
|
||||||
|
#if CEF_API_VERSION != CEF_EXPERIMENTAL
|
||||||
|
printf("Running with configured CEF API version %d\n", CEF_API_VERSION);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(OS_WIN) && defined(ARCH_CPU_32_BITS)
|
#if defined(OS_WIN) && defined(ARCH_CPU_32_BITS)
|
||||||
// Run the main thread on 32-bit Windows using a fiber with the preferred 4MiB
|
// Run the main thread on 32-bit Windows using a fiber with the preferred 4MiB
|
||||||
// stack size. This function must be called at the top of the executable entry
|
// stack size. This function must be called at the top of the executable entry
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// can be found in the LICENSE file.
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
#include "include/cef_api_hash.h"
|
#include "include/cef_api_hash.h"
|
||||||
#include "include/cef_version.h"
|
#include "include/cef_version_info.h"
|
||||||
#include "tests/gtest/include/gtest/gtest.h"
|
#include "tests/gtest/include/gtest/gtest.h"
|
||||||
|
|
||||||
TEST(VersionTest, VersionInfo) {
|
TEST(VersionTest, VersionInfo) {
|
||||||
@ -18,7 +18,7 @@ TEST(VersionTest, VersionInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(VersionTest, ApiHash) {
|
TEST(VersionTest, ApiHash) {
|
||||||
EXPECT_STREQ(CEF_API_HASH_PLATFORM, cef_api_hash(0));
|
EXPECT_STREQ(CEF_API_HASH_PLATFORM, cef_api_hash(CEF_API_VERSION, 0));
|
||||||
EXPECT_STREQ(CEF_API_HASH_UNIVERSAL, cef_api_hash(1));
|
EXPECT_STREQ(CEF_API_HASH_UNIVERSAL, cef_api_hash(CEF_API_VERSION, 1));
|
||||||
EXPECT_STREQ(CEF_COMMIT_HASH, cef_api_hash(2));
|
EXPECT_STREQ(CEF_COMMIT_HASH, cef_api_hash(CEF_API_VERSION, 2));
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
// can be found in the LICENSE file.
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
#include "include/base/cef_callback.h"
|
#include "include/base/cef_callback.h"
|
||||||
#include "include/cef_pack_strings.h"
|
|
||||||
#include "include/views/cef_panel.h"
|
#include "include/views/cef_panel.h"
|
||||||
#include "include/views/cef_panel_delegate.h"
|
#include "include/views/cef_panel_delegate.h"
|
||||||
#include "include/views/cef_scroll_view.h"
|
#include "include/views/cef_scroll_view.h"
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
// can be found in the LICENSE file.
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
#include "include/base/cef_callback.h"
|
#include "include/base/cef_callback.h"
|
||||||
#include "include/cef_pack_strings.h"
|
|
||||||
#include "include/views/cef_textfield.h"
|
#include "include/views/cef_textfield.h"
|
||||||
#include "include/views/cef_textfield_delegate.h"
|
#include "include/views/cef_textfield_delegate.h"
|
||||||
#include "include/wrapper/cef_closure_task.h"
|
#include "include/wrapper/cef_closure_task.h"
|
||||||
|
@ -4,16 +4,16 @@
|
|||||||
|
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
from clang_util import clang_eval
|
||||||
from file_util import *
|
from file_util import *
|
||||||
|
import hashlib
|
||||||
|
import itertools
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import shutil
|
|
||||||
import string
|
import string
|
||||||
import sys
|
import sys
|
||||||
import textwrap
|
|
||||||
import time
|
import time
|
||||||
import itertools
|
from version_util import EXP_VERSION
|
||||||
import hashlib
|
|
||||||
|
|
||||||
# Determines string type for python 2 and python 3.
|
# Determines string type for python 2 and python 3.
|
||||||
if sys.version_info[0] == 3:
|
if sys.version_info[0] == 3:
|
||||||
@ -22,93 +22,172 @@ else:
|
|||||||
string_type = basestring
|
string_type = basestring
|
||||||
|
|
||||||
|
|
||||||
|
def _run_clang_eval(filename, content, api_version, added_defines, verbose):
|
||||||
|
# Add a tag so we know where the header-specific output begins.
|
||||||
|
tag = 'int begin_includes_tag;\n'
|
||||||
|
find = '#ifdef __cplusplus\nextern "C" {'
|
||||||
|
pos = content.find(find)
|
||||||
|
assert pos > 0, filename
|
||||||
|
content = content[0:pos] + tag + content[pos:]
|
||||||
|
|
||||||
|
defines = [
|
||||||
|
# Makes sure CEF_EXPORT is defined.
|
||||||
|
'USING_CEF_SHARED',
|
||||||
|
|
||||||
|
# Avoid include of generated headers.
|
||||||
|
'GENERATING_CEF_API_HASH',
|
||||||
|
]
|
||||||
|
|
||||||
|
if filename.find('test/') >= 0:
|
||||||
|
# Avoids errors parsing test includes.
|
||||||
|
defines.append('UNIT_TEST')
|
||||||
|
|
||||||
|
# Not the experimental version.
|
||||||
|
api_version = int(api_version)
|
||||||
|
if api_version != EXP_VERSION:
|
||||||
|
# Specify the exact version.
|
||||||
|
defines.append('CEF_API_VERSION=%d' % api_version)
|
||||||
|
|
||||||
|
if not added_defines is None:
|
||||||
|
defines.extend(added_defines)
|
||||||
|
|
||||||
|
includes = [
|
||||||
|
# Includes relative to the 'src/cef' directory.
|
||||||
|
'.',
|
||||||
|
# Includes relative to the 'src' directory.
|
||||||
|
'..',
|
||||||
|
]
|
||||||
|
|
||||||
|
result = clang_eval(
|
||||||
|
filename,
|
||||||
|
content,
|
||||||
|
defines=defines,
|
||||||
|
includes=includes,
|
||||||
|
as_cpp=False,
|
||||||
|
verbose=verbose)
|
||||||
|
if result is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
pos = result.find(tag)
|
||||||
|
assert pos > 0, filename
|
||||||
|
result = result[pos + len(tag):]
|
||||||
|
|
||||||
|
replacements = [
|
||||||
|
# Undo substitutions from cef_export.h
|
||||||
|
['__declspec(dllimport)', 'CEF_EXPORT'],
|
||||||
|
['__attribute__((visibility("default")))', 'CEF_EXPORT'],
|
||||||
|
['__stdcall', ''],
|
||||||
|
]
|
||||||
|
|
||||||
|
for find, replace in replacements:
|
||||||
|
result = result.replace(find, replace)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
class cef_api_hash:
|
class cef_api_hash:
|
||||||
""" CEF API hash calculator """
|
""" CEF API hash calculator """
|
||||||
|
|
||||||
def __init__(self, headerdir, debugdir=None, verbose=False):
|
def __init__(self, headerdir, verbose=False):
|
||||||
if headerdir is None or len(headerdir) == 0:
|
if headerdir is None or len(headerdir) == 0:
|
||||||
raise AssertionError("headerdir is not specified")
|
raise AssertionError("headerdir is not specified")
|
||||||
|
|
||||||
self.__headerdir = headerdir
|
self.__headerdir = headerdir
|
||||||
self.__debugdir = debugdir
|
|
||||||
self.__verbose = verbose
|
self.__verbose = verbose
|
||||||
self.__debug_enabled = not (self.__debugdir is
|
|
||||||
None) and len(self.__debugdir) > 0
|
|
||||||
|
|
||||||
self.platforms = ["windows", "mac", "linux"]
|
self.platforms = ["windows", "mac", "linux"]
|
||||||
|
|
||||||
|
cef_dir = os.path.abspath(os.path.join(self.__headerdir, os.pardir))
|
||||||
|
|
||||||
|
# Read the variables list from the autogenerated cef_paths.gypi file.
|
||||||
|
cef_paths = eval_file(os.path.join(cef_dir, 'cef_paths.gypi'))
|
||||||
|
cef_paths = cef_paths['variables']
|
||||||
|
|
||||||
|
# Read the variables list from the manually edited cef_paths2.gypi file.
|
||||||
|
cef_paths2 = eval_file(os.path.join(cef_dir, 'cef_paths2.gypi'))
|
||||||
|
cef_paths2 = cef_paths2['variables']
|
||||||
|
|
||||||
|
# Excluded files (paths relative to the include/ directory).
|
||||||
|
excluded_files = []
|
||||||
|
|
||||||
|
# List of platform-specific C API include/ files.
|
||||||
self.platform_files = {
|
self.platform_files = {
|
||||||
# List of includes_win_capi from cef_paths2.gypi.
|
"windows":
|
||||||
"windows": [
|
self.__get_filenames(cef_dir, cef_paths2['includes_win_capi'],
|
||||||
"internal/cef_app_win.h",
|
excluded_files),
|
||||||
"internal/cef_types_win.h",
|
"mac":
|
||||||
],
|
self.__get_filenames(cef_dir, cef_paths2['includes_mac_capi'],
|
||||||
# List of includes_mac_capi from cef_paths2.gypi.
|
excluded_files),
|
||||||
"mac": [
|
"linux":
|
||||||
"internal/cef_types_mac.h",
|
self.__get_filenames(cef_dir, cef_paths2['includes_linux_capi'],
|
||||||
],
|
excluded_files)
|
||||||
# List of includes_linux_capi from cef_paths2.gypi.
|
|
||||||
"linux": [
|
|
||||||
"internal/cef_types_linux.h",
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.included_files = []
|
# List of all C API include/ files.
|
||||||
|
paths = cef_paths2['includes_capi'] + cef_paths2['includes_common_capi'] + \
|
||||||
|
cef_paths2['includes_linux_capi'] + cef_paths2['includes_mac_capi'] + \
|
||||||
|
cef_paths2['includes_win_capi'] + cef_paths['autogen_capi_includes']
|
||||||
|
self.filenames = self.__get_filenames(cef_dir, paths, excluded_files)
|
||||||
|
|
||||||
# List of include/ and include/internal/ files from cef_paths2.gypi.
|
self.filecontents = {}
|
||||||
self.excluded_files = [
|
self.filecontentobjs = {}
|
||||||
# includes_common
|
|
||||||
"cef_api_hash.h",
|
|
||||||
"cef_base.h",
|
|
||||||
"cef_version.h",
|
|
||||||
"internal/cef_export.h",
|
|
||||||
"internal/cef_ptr.h",
|
|
||||||
"internal/cef_string_wrappers.h",
|
|
||||||
"internal/cef_time_wrappers.h",
|
|
||||||
"internal/cef_types_wrappers.h",
|
|
||||||
# includes_win
|
|
||||||
"cef_sandbox_win.h",
|
|
||||||
"internal/cef_win.h",
|
|
||||||
# includes_mac
|
|
||||||
"cef_application_mac.h",
|
|
||||||
"cef_sandbox_mac.h",
|
|
||||||
"internal/cef_mac.h",
|
|
||||||
# includes_linux
|
|
||||||
"internal/cef_linux.h",
|
|
||||||
]
|
|
||||||
|
|
||||||
def calculate(self):
|
# Cache values that will not change between calls to calculate().
|
||||||
filenames = [
|
for filename in self.filenames:
|
||||||
filename for filename in self.__get_filenames()
|
|
||||||
if not filename in self.excluded_files
|
|
||||||
]
|
|
||||||
|
|
||||||
objects = []
|
|
||||||
for filename in filenames:
|
|
||||||
if self.__verbose:
|
if self.__verbose:
|
||||||
print("Processing " + filename + "...")
|
print("Processing " + filename + "...")
|
||||||
|
|
||||||
|
assert not filename in self.filecontents, filename
|
||||||
|
assert not filename in self.filecontentobjs, filename
|
||||||
|
|
||||||
content = read_file(os.path.join(self.__headerdir, filename), True)
|
content = read_file(os.path.join(self.__headerdir, filename), True)
|
||||||
platforms = list([
|
content_objects = None
|
||||||
p for p in self.platforms if self.__is_platform_filename(filename, p)
|
|
||||||
])
|
|
||||||
|
|
||||||
# Parse cef_string.h happens in special case: grab only defined CEF_STRING_TYPE_xxx declaration
|
# Parse cef_string.h happens in special case: grab only defined CEF_STRING_TYPE_xxx declaration
|
||||||
content_objects = None
|
|
||||||
if filename == "internal/cef_string.h":
|
if filename == "internal/cef_string.h":
|
||||||
content_objects = self.__parse_string_type(content)
|
content_objects = self.__parse_string_type(content)
|
||||||
|
elif content.find('#if CEF_API') >= 0:
|
||||||
|
# Needs to be passed to clang with version-specific defines.
|
||||||
|
self.filecontents[filename] = content
|
||||||
else:
|
else:
|
||||||
content_objects = self.__parse_objects(content)
|
content_objects = self.__parse_objects(content)
|
||||||
|
|
||||||
for o in content_objects:
|
if not content_objects is None:
|
||||||
o["text"] = self.__prepare_text(o["text"])
|
self.__prepare_objects(filename, content_objects)
|
||||||
o["platforms"] = platforms
|
self.filecontentobjs[filename] = content_objects
|
||||||
o["filename"] = filename
|
|
||||||
objects.append(o)
|
def calculate(self, api_version, debug_dir=None, added_defines=None):
|
||||||
|
debug_enabled = not (debug_dir is None) and len(debug_dir) > 0
|
||||||
|
|
||||||
|
objects = []
|
||||||
|
for filename in self.filenames:
|
||||||
|
if self.__verbose:
|
||||||
|
print("Processing " + filename + "...")
|
||||||
|
|
||||||
|
content = self.filecontents.get(filename, None)
|
||||||
|
if not content is None:
|
||||||
|
assert content.find('#if CEF_API') >= 0, filename
|
||||||
|
content = _run_clang_eval(filename, content, api_version, added_defines,
|
||||||
|
self.__verbose)
|
||||||
|
if content is None:
|
||||||
|
sys.stderr.write(
|
||||||
|
'ERROR: Failed to compute API hash for %s\n' % filename)
|
||||||
|
return False
|
||||||
|
if debug_enabled:
|
||||||
|
self.__write_debug_file(
|
||||||
|
debug_dir, 'clang-' + filename.replace('/', '-'), content)
|
||||||
|
content_objects = self.__parse_objects(content)
|
||||||
|
self.__prepare_objects(filename, content_objects)
|
||||||
|
else:
|
||||||
|
content_objects = self.filecontentobjs.get(filename, None)
|
||||||
|
|
||||||
|
assert not content_objects is None, filename
|
||||||
|
objects.extend(content_objects)
|
||||||
|
|
||||||
# objects will be sorted including filename, to make stable universal hashes
|
# objects will be sorted including filename, to make stable universal hashes
|
||||||
objects = sorted(objects, key=lambda o: o["name"] + "@" + o["filename"])
|
objects = sorted(objects, key=lambda o: o["name"] + "@" + o["filename"])
|
||||||
|
|
||||||
if self.__debug_enabled:
|
if debug_enabled:
|
||||||
namelen = max([len(o["name"]) for o in objects])
|
namelen = max([len(o["name"]) for o in objects])
|
||||||
filenamelen = max([len(o["filename"]) for o in objects])
|
filenamelen = max([len(o["filename"]) for o in objects])
|
||||||
dumpsig = []
|
dumpsig = []
|
||||||
@ -116,14 +195,14 @@ class cef_api_hash:
|
|||||||
dumpsig.append(
|
dumpsig.append(
|
||||||
format(o["name"], str(namelen) + "s") + "|" + format(
|
format(o["name"], str(namelen) + "s") + "|" + format(
|
||||||
o["filename"], "" + str(filenamelen) + "s") + "|" + o["text"])
|
o["filename"], "" + str(filenamelen) + "s") + "|" + o["text"])
|
||||||
self.__write_debug_file("objects.txt", dumpsig)
|
self.__write_debug_file(debug_dir, "objects.txt", dumpsig)
|
||||||
|
|
||||||
revisions = {}
|
revisions = {}
|
||||||
|
|
||||||
for platform in itertools.chain(["universal"], self.platforms):
|
for platform in itertools.chain(["universal"], self.platforms):
|
||||||
sig = self.__get_final_sig(objects, platform)
|
sig = self.__get_final_sig(objects, platform)
|
||||||
if self.__debug_enabled:
|
if debug_enabled:
|
||||||
self.__write_debug_file(platform + ".sig", sig)
|
self.__write_debug_file(debug_dir, platform + ".sig", sig)
|
||||||
revstr = hashlib.sha1(sig.encode('utf-8')).hexdigest()
|
revstr = hashlib.sha1(sig.encode('utf-8')).hexdigest()
|
||||||
revisions[platform] = revstr
|
revisions[platform] = revstr
|
||||||
|
|
||||||
@ -152,7 +231,8 @@ class cef_api_hash:
|
|||||||
|
|
||||||
# enums
|
# enums
|
||||||
for m in re.finditer(
|
for m in re.finditer(
|
||||||
r"\ntypedef\s+?enum\s+?\{.*?\}\s+?(\w+)\s*?;", content, flags=re.DOTALL):
|
r"\ntypedef\s+?enum\s+?\{.*?\}\s+?(\w+)\s*?;", content,
|
||||||
|
flags=re.DOTALL):
|
||||||
object = {"name": m.group(1), "text": m.group(0).strip()}
|
object = {"name": m.group(1), "text": m.group(0).strip()}
|
||||||
objects.append(object)
|
objects.append(object)
|
||||||
|
|
||||||
@ -163,11 +243,20 @@ class cef_api_hash:
|
|||||||
|
|
||||||
return objects
|
return objects
|
||||||
|
|
||||||
|
def __prepare_objects(self, filename, objects):
|
||||||
|
platforms = list(
|
||||||
|
[p for p in self.platforms if self.__is_platform_filename(filename, p)])
|
||||||
|
for o in objects:
|
||||||
|
o["text"] = self.__prepare_text(o["text"])
|
||||||
|
o["platforms"] = platforms
|
||||||
|
o["filename"] = filename
|
||||||
|
|
||||||
def __parse_string_type(self, content):
|
def __parse_string_type(self, content):
|
||||||
""" Grab defined CEF_STRING_TYPE_xxx """
|
""" Grab defined CEF_STRING_TYPE_xxx """
|
||||||
objects = []
|
objects = []
|
||||||
for m in re.finditer(
|
for m in re.finditer(
|
||||||
r"\n\s*?#\s*?define\s+?(CEF_STRING_TYPE_\w+)\s+?.*?\n", content,
|
r"\n\s*?#\s*?define\s+?(CEF_STRING_TYPE_\w+)\s+?.*?\n",
|
||||||
|
content,
|
||||||
flags=0):
|
flags=0):
|
||||||
object = {
|
object = {
|
||||||
"name": m.group(1),
|
"name": m.group(1),
|
||||||
@ -191,35 +280,20 @@ class cef_api_hash:
|
|||||||
|
|
||||||
return "\n".join(sig)
|
return "\n".join(sig)
|
||||||
|
|
||||||
def __get_filenames(self):
|
def __get_filenames(self, cef_dir, paths, excluded_files):
|
||||||
""" Returns file names to be processed, relative to headerdir """
|
""" Returns file names to be processed, relative to headerdir """
|
||||||
headers = [
|
filenames = [
|
||||||
os.path.join(self.__headerdir, filename)
|
os.path.relpath(os.path.join(cef_dir, filename),
|
||||||
for filename in self.included_files
|
self.__headerdir).replace('\\', '/').lower()
|
||||||
|
for filename in paths
|
||||||
]
|
]
|
||||||
|
|
||||||
capi_dir = os.path.join(self.__headerdir, "capi")
|
if len(excluded_files) == 0:
|
||||||
headers = itertools.chain(headers, get_files(os.path.join(capi_dir, "*.h")))
|
return filenames
|
||||||
|
|
||||||
# Also include capi sub-directories.
|
return [
|
||||||
for root, dirs, files in os.walk(capi_dir):
|
filename for filename in filenames if not filename in excluded_files
|
||||||
for name in dirs:
|
|
||||||
headers = itertools.chain(headers,
|
|
||||||
get_files(os.path.join(root, name, "*.h")))
|
|
||||||
|
|
||||||
headers = itertools.chain(
|
|
||||||
headers, get_files(os.path.join(self.__headerdir, "internal", "*.h")))
|
|
||||||
|
|
||||||
for v in self.platform_files.values():
|
|
||||||
headers = itertools.chain(headers,
|
|
||||||
[os.path.join(self.__headerdir, f) for f in v])
|
|
||||||
|
|
||||||
normalized = [
|
|
||||||
os.path.relpath(filename, self.__headerdir) for filename in headers
|
|
||||||
]
|
]
|
||||||
normalized = [f.replace('\\', '/').lower() for f in normalized]
|
|
||||||
|
|
||||||
return list(set(normalized))
|
|
||||||
|
|
||||||
def __is_platform_filename(self, filename, platform):
|
def __is_platform_filename(self, filename, platform):
|
||||||
if platform == "universal":
|
if platform == "universal":
|
||||||
@ -235,9 +309,9 @@ class cef_api_hash:
|
|||||||
listed = True
|
listed = True
|
||||||
return not listed
|
return not listed
|
||||||
|
|
||||||
def __write_debug_file(self, filename, content):
|
def __write_debug_file(self, debug_dir, filename, content):
|
||||||
make_dir(self.__debugdir)
|
make_dir(debug_dir)
|
||||||
outfile = os.path.join(self.__debugdir, filename)
|
outfile = os.path.join(debug_dir, filename)
|
||||||
dir = os.path.dirname(outfile)
|
dir = os.path.dirname(outfile)
|
||||||
make_dir(dir)
|
make_dir(dir)
|
||||||
if not isinstance(content, string_type):
|
if not isinstance(content, string_type):
|
||||||
@ -282,14 +356,16 @@ if __name__ == "__main__":
|
|||||||
c_start_time = time.time()
|
c_start_time = time.time()
|
||||||
|
|
||||||
calc = cef_api_hash(options.cppheaderdir, options.debugdir, options.verbose)
|
calc = cef_api_hash(options.cppheaderdir, options.debugdir, options.verbose)
|
||||||
revisions = calc.calculate()
|
revisions = calc.calculate(api_version=EXP_VERSION)
|
||||||
|
|
||||||
c_completed_in = time.time() - c_start_time
|
c_completed_in = time.time() - c_start_time
|
||||||
|
|
||||||
|
if bool(revisions):
|
||||||
print("{")
|
print("{")
|
||||||
for k in sorted(revisions.keys()):
|
for k in sorted(revisions.keys()):
|
||||||
print(format("\"" + k + "\"", ">12s") + ": \"" + revisions[k] + "\"")
|
print(format("\"" + k + "\"", ">12s") + ": \"" + revisions[k] + "\"")
|
||||||
print("}")
|
print("}")
|
||||||
|
|
||||||
# print
|
# print
|
||||||
# print 'Completed in: ' + str(c_completed_in)
|
# print 'Completed in: ' + str(c_completed_in)
|
||||||
# print
|
# print
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
# can be found in the LICENSE file.
|
# can be found in the LICENSE file.
|
||||||
|
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
import bisect
|
||||||
from date_util import *
|
from date_util import *
|
||||||
from file_util import *
|
from file_util import *
|
||||||
import os
|
import os
|
||||||
@ -12,11 +13,26 @@ import string
|
|||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
import time
|
import time
|
||||||
|
from version_util import version_as_numeric, version_as_variable
|
||||||
|
|
||||||
|
_NOTIFY_CONTEXT = None
|
||||||
|
_NOTIFY_CONTEXT_LAST = None
|
||||||
|
|
||||||
|
|
||||||
|
def set_notify_context(context):
|
||||||
|
global _NOTIFY_CONTEXT
|
||||||
|
_NOTIFY_CONTEXT = context
|
||||||
|
|
||||||
|
|
||||||
def notify(msg):
|
def notify(msg):
|
||||||
""" Display a message. """
|
""" Display a message. """
|
||||||
sys.stdout.write(' NOTE: ' + msg + '\n')
|
global _NOTIFY_CONTEXT_LAST
|
||||||
|
|
||||||
|
if not _NOTIFY_CONTEXT is None and _NOTIFY_CONTEXT != _NOTIFY_CONTEXT_LAST:
|
||||||
|
print('In %s:' % _NOTIFY_CONTEXT)
|
||||||
|
_NOTIFY_CONTEXT_LAST = _NOTIFY_CONTEXT
|
||||||
|
|
||||||
|
print(' NOTE: ' + msg)
|
||||||
|
|
||||||
|
|
||||||
def wrap_text(text, indent='', maxchars=80, listitem=False):
|
def wrap_text(text, indent='', maxchars=80, listitem=False):
|
||||||
@ -44,25 +60,28 @@ def is_base_class(clsname):
|
|||||||
return clsname == 'CefBaseRefCounted' or clsname == 'CefBaseScoped'
|
return clsname == 'CefBaseRefCounted' or clsname == 'CefBaseScoped'
|
||||||
|
|
||||||
|
|
||||||
def get_capi_file_name(cppname):
|
def get_capi_file_name(cppname, versions=False):
|
||||||
""" Convert a C++ header file name to a C API header file name. """
|
""" Convert a C++ header file name to a C API header file name. """
|
||||||
return cppname[:-2] + '_capi.h'
|
return cppname[:-2] + ('_capi_versions.h' if versions else '_capi.h')
|
||||||
|
|
||||||
|
|
||||||
def get_capi_name(cppname, isclassname, prefix=None):
|
def get_capi_name(cppname, isclassname, prefix=None, version=None):
|
||||||
""" Convert a C++ CamelCaps name to a C API underscore name. """
|
""" Convert a C++ CamelCaps name to a C API underscore name. """
|
||||||
result = ''
|
result = ''
|
||||||
lastchr = ''
|
lastchr = ''
|
||||||
for chr in cppname:
|
for chr in cppname:
|
||||||
# add an underscore if the current character is an upper case letter
|
# add an underscore if the current character is an upper case letter
|
||||||
# and the last character was a lower case letter
|
# and the last character was a lower case letter or number.
|
||||||
if len(result) > 0 and not chr.isdigit() \
|
if len(result) > 0 and chr.isalpha() \
|
||||||
and chr.upper() == chr \
|
and chr.upper() == chr \
|
||||||
and not lastchr.upper() == lastchr:
|
and lastchr.isalnum() and lastchr.lower() == lastchr:
|
||||||
result += '_'
|
result += '_'
|
||||||
result += chr.lower()
|
result += chr.lower()
|
||||||
lastchr = chr
|
lastchr = chr
|
||||||
|
|
||||||
|
if isclassname and not version is None:
|
||||||
|
result += '_%d' % version
|
||||||
|
|
||||||
if isclassname:
|
if isclassname:
|
||||||
result += '_t'
|
result += '_t'
|
||||||
|
|
||||||
@ -259,7 +278,10 @@ def format_translation_changes(old, new):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def format_translation_includes(header, body):
|
def format_translation_includes(header,
|
||||||
|
body,
|
||||||
|
with_versions=False,
|
||||||
|
other_includes=None):
|
||||||
""" Return the necessary list of includes based on the contents of the
|
""" Return the necessary list of includes based on the contents of the
|
||||||
body.
|
body.
|
||||||
"""
|
"""
|
||||||
@ -269,47 +291,187 @@ def format_translation_includes(header, body):
|
|||||||
if body.find('std::min') > 0 or body.find('std::max') > 0:
|
if body.find('std::min') > 0 or body.find('std::max') > 0:
|
||||||
result += '#include <algorithm>\n'
|
result += '#include <algorithm>\n'
|
||||||
|
|
||||||
if body.find('cef_api_hash(') > 0:
|
paths = set()
|
||||||
result += '#include "include/cef_api_hash.h"\n'
|
|
||||||
|
if body.find('cef_api_hash(') > 0 or body.find('cef_api_version(') > 0:
|
||||||
|
paths.add('include/cef_api_hash.h')
|
||||||
|
|
||||||
if body.find('template_util::has_valid_size(') > 0:
|
if body.find('template_util::has_valid_size(') > 0:
|
||||||
result += '#include "libcef_dll/template_util.h"\n'
|
paths.add('libcef_dll/template_util.h')
|
||||||
|
|
||||||
# identify what CppToC classes are being used
|
search = ((True, True, r'([A-Za-z0-9_]{1,})_[0-9]{1,}_CppToC'),
|
||||||
p = re.compile(r'([A-Za-z0-9_]{1,})CppToC')
|
(True, False, r'([A-Za-z0-9_]{1,})CppToC'),
|
||||||
list = sorted(set(p.findall(body)))
|
(False, True, r'([A-Za-z0-9_]{1,})_[0-9]{1,}_CToCpp'),
|
||||||
for item in list:
|
(False, False, r'([A-Za-z0-9_]{1,})CToCpp'))
|
||||||
|
for cpptoc, versioned, regex in search:
|
||||||
|
# identify what classes are being used
|
||||||
|
p = re.compile(regex)
|
||||||
|
items = set(p.findall(body))
|
||||||
|
for item in items:
|
||||||
|
if item == 'Cef':
|
||||||
|
continue
|
||||||
|
if not versioned and item[-1] == '_':
|
||||||
|
# skip versioned names that are picked up by the unversioned regex
|
||||||
|
continue
|
||||||
directory = ''
|
directory = ''
|
||||||
if not is_base_class(item):
|
if not is_base_class(item):
|
||||||
cls = header.get_class(item)
|
cls = header.get_class(item)
|
||||||
|
if cls is None:
|
||||||
|
raise Exception('Class does not exist: ' + item)
|
||||||
dir = cls.get_file_directory()
|
dir = cls.get_file_directory()
|
||||||
if not dir is None:
|
if not dir is None:
|
||||||
directory = dir + '/'
|
directory = dir + '/'
|
||||||
result += '#include "libcef_dll/cpptoc/'+directory+ \
|
type = 'cpptoc' if cpptoc else 'ctocpp'
|
||||||
get_capi_name(item[3:], False)+'_cpptoc.h"\n'
|
paths.add('libcef_dll/' + type + '/'+directory+ \
|
||||||
|
get_capi_name(item[3:], False)+'_' + type + '.h')
|
||||||
# identify what CToCpp classes are being used
|
|
||||||
p = re.compile(r'([A-Za-z0-9_]{1,})CToCpp')
|
|
||||||
list = sorted(set(p.findall(body)))
|
|
||||||
for item in list:
|
|
||||||
directory = ''
|
|
||||||
if not is_base_class(item):
|
|
||||||
cls = header.get_class(item)
|
|
||||||
dir = cls.get_file_directory()
|
|
||||||
if not dir is None:
|
|
||||||
directory = dir + '/'
|
|
||||||
result += '#include "libcef_dll/ctocpp/'+directory+ \
|
|
||||||
get_capi_name(item[3:], False)+'_ctocpp.h"\n'
|
|
||||||
|
|
||||||
if body.find('shutdown_checker') > 0:
|
if body.find('shutdown_checker') > 0:
|
||||||
result += '#include "libcef_dll/shutdown_checker.h"\n'
|
paths.add('libcef_dll/shutdown_checker.h')
|
||||||
|
|
||||||
if body.find('transfer_') > 0:
|
if body.find('transfer_') > 0:
|
||||||
result += '#include "libcef_dll/transfer_util.h"\n'
|
paths.add('libcef_dll/transfer_util.h')
|
||||||
|
|
||||||
|
if not other_includes is None:
|
||||||
|
paths.update(other_includes)
|
||||||
|
|
||||||
|
if len(paths) > 0:
|
||||||
|
if len(result) > 0:
|
||||||
|
result += '\n'
|
||||||
|
|
||||||
|
paths = sorted(list(paths))
|
||||||
|
result += '\n'.join(['#include "%s"' % p for p in paths]) + '\n'
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def format_notreached(library_side, msg, default_retval='', indent=' '):
|
||||||
|
if library_side:
|
||||||
|
return 'NOTREACHED() << __func__ << ' + msg + ';'
|
||||||
|
return 'CHECK(false) << __func__ << ' + msg + ';\n' + \
|
||||||
|
indent + 'return%s;' % ((' ' + default_retval) if len(default_retval) > 0 else '')
|
||||||
|
|
||||||
|
|
||||||
|
def _has_version_added(attribs):
|
||||||
|
return 'added' in attribs
|
||||||
|
|
||||||
|
|
||||||
|
def _has_version_removed(attribs):
|
||||||
|
return 'removed' in attribs
|
||||||
|
|
||||||
|
|
||||||
|
def _has_version(attribs):
|
||||||
|
return _has_version_added(attribs) or _has_version_removed(attribs)
|
||||||
|
|
||||||
|
|
||||||
|
def get_version_check(attribs):
|
||||||
|
assert _has_version(attribs)
|
||||||
|
|
||||||
|
added = attribs.get('added', None)
|
||||||
|
if not added is None:
|
||||||
|
added = version_as_variable(added)
|
||||||
|
removed = attribs.get('removed', None)
|
||||||
|
if not removed is None:
|
||||||
|
removed = version_as_variable(removed)
|
||||||
|
|
||||||
|
if not added is None and not removed is None:
|
||||||
|
return 'CEF_API_RANGE(%s, %s)' % (added, removed)
|
||||||
|
elif not added is None:
|
||||||
|
return 'CEF_API_ADDED(%s)' % added
|
||||||
|
return 'CEF_API_REMOVED(%s)' % removed
|
||||||
|
|
||||||
|
|
||||||
|
def _get_version_attrib(attribs, key):
|
||||||
|
value = attribs.get(key, None)
|
||||||
|
if not value is None:
|
||||||
|
return version_as_numeric(value)
|
||||||
|
|
||||||
|
# Unversioned is always the first value.
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def _get_version_added(attribs):
|
||||||
|
""" Returns a numeric 'added' value used for sorting purposes. """
|
||||||
|
return _get_version_attrib(attribs, 'added')
|
||||||
|
|
||||||
|
|
||||||
|
def _get_version_removed(attribs):
|
||||||
|
""" Returns a numeric 'removed' value used for sorting purposes. """
|
||||||
|
return _get_version_attrib(attribs, 'removed')
|
||||||
|
|
||||||
|
|
||||||
|
def get_version_surround(obj, long=False):
|
||||||
|
""" Returns (pre,post) strings for a version check. """
|
||||||
|
version_check = obj.get_version_check() if obj.has_version() else None
|
||||||
|
|
||||||
|
# Don't duplicate the surrounding class version check for a virtual method.
|
||||||
|
if not version_check is None and \
|
||||||
|
isinstance(obj, obj_function) and isinstance(obj.parent, obj_class) and \
|
||||||
|
obj.parent.has_version() and obj.parent.get_version_check() == version_check:
|
||||||
|
version_check = None
|
||||||
|
|
||||||
|
if not version_check is None:
|
||||||
|
return ('#if %s\n' % version_check, ('#endif // %s\n' % version_check)
|
||||||
|
if long else '#endif\n')
|
||||||
|
return ('', '')
|
||||||
|
|
||||||
|
|
||||||
|
def get_clsname(cls, version):
|
||||||
|
name = cls.get_name()
|
||||||
|
|
||||||
|
if not version is None:
|
||||||
|
# Select the appropriate version for this class.
|
||||||
|
closest_version = cls.get_closest_version(version)
|
||||||
|
if closest_version is None:
|
||||||
|
raise Exception('Cannot find version <= %d for %s' % (version, name))
|
||||||
|
return '%s_%d_' % (name, closest_version)
|
||||||
|
|
||||||
|
return name
|
||||||
|
|
||||||
|
|
||||||
|
def _version_order_funcs(funcs, max_version=None):
|
||||||
|
""" Applies version-based ordering to a list of funcs. """
|
||||||
|
versions = {0: []}
|
||||||
|
|
||||||
|
for func in funcs:
|
||||||
|
if func.has_version():
|
||||||
|
added = func.get_version_added()
|
||||||
|
if not added in versions:
|
||||||
|
versions[added] = [func]
|
||||||
|
else:
|
||||||
|
versions[added].append(func)
|
||||||
|
else:
|
||||||
|
# Unversioned funcs.
|
||||||
|
versions[0].append(func)
|
||||||
|
|
||||||
|
result = []
|
||||||
|
for version in sorted(versions.keys()):
|
||||||
|
if not max_version is None and version > max_version:
|
||||||
|
break
|
||||||
|
result.extend(versions[version])
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def _get_all_versions(funcs):
|
||||||
|
# Using a set to ensure uniqueness.
|
||||||
|
versions = set({0})
|
||||||
|
|
||||||
|
for func in funcs:
|
||||||
|
if func.has_version():
|
||||||
|
versions.add(func.get_version_added())
|
||||||
|
versions.add(func.get_version_removed())
|
||||||
|
|
||||||
|
return versions
|
||||||
|
|
||||||
|
|
||||||
|
def _find_closest_not_greater(lst, target):
|
||||||
|
assert isinstance(lst, list), lst
|
||||||
|
assert isinstance(target, int), target
|
||||||
|
idx = bisect.bisect_right(lst, target) - 1
|
||||||
|
if idx < 0:
|
||||||
|
return None
|
||||||
|
return lst[idx]
|
||||||
|
|
||||||
|
|
||||||
def str_to_dict(str):
|
def str_to_dict(str):
|
||||||
""" Convert a string to a dictionary. If the same key has multiple values
|
""" Convert a string to a dictionary. If the same key has multiple values
|
||||||
the values will be stored in a list. """
|
the values will be stored in a list. """
|
||||||
@ -357,6 +519,13 @@ def dict_to_str(dict):
|
|||||||
return ','.join(str)
|
return ','.join(str)
|
||||||
|
|
||||||
|
|
||||||
|
# Attribute keys allowed in CEF metadata comments.
|
||||||
|
COMMON_ATTRIB_KEYS = ('added', 'removed')
|
||||||
|
CLASS_ATTRIB_KEYS = COMMON_ATTRIB_KEYS + ('no_debugct_check', 'source')
|
||||||
|
FUNCTION_ATTRIB_KEYS = COMMON_ATTRIB_KEYS + ('api_hash_check', 'capi_name',
|
||||||
|
'count_func', 'default_retval',
|
||||||
|
'index_param', 'optional_param')
|
||||||
|
|
||||||
# regex for matching comment-formatted attributes
|
# regex for matching comment-formatted attributes
|
||||||
_cre_attrib = r'/\*--cef\(([A-Za-z0-9_ ,=:\n]{0,})\)--\*/'
|
_cre_attrib = r'/\*--cef\(([A-Za-z0-9_ ,=:\n]{0,})\)--\*/'
|
||||||
# regex for matching class and function names
|
# regex for matching class and function names
|
||||||
@ -747,13 +916,18 @@ class obj_header:
|
|||||||
res.append(cls)
|
res.append(cls)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def get_class(self, classname, defined_structs=None):
|
def get_class(self, classname):
|
||||||
""" Return the specified class or None if not found. """
|
""" Return the specified class or None if not found. """
|
||||||
for cls in self.classes:
|
for cls in self.classes:
|
||||||
if cls.get_name() == classname:
|
if cls.get_name() == classname:
|
||||||
return cls
|
return cls
|
||||||
elif not defined_structs is None:
|
return None
|
||||||
defined_structs.append(cls.get_capi_name())
|
|
||||||
|
def get_capi_class(self, classname):
|
||||||
|
""" Return the specified class or None if not found. """
|
||||||
|
for cls in self.classes:
|
||||||
|
if cls.get_capi_name() == classname:
|
||||||
|
return cls
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_class_names(self):
|
def get_class_names(self):
|
||||||
@ -856,6 +1030,8 @@ class obj_class:
|
|||||||
self.includes = includes
|
self.includes = includes
|
||||||
self.forward_declares = forward_declares
|
self.forward_declares = forward_declares
|
||||||
|
|
||||||
|
self._validate_attribs()
|
||||||
|
|
||||||
# extract typedefs
|
# extract typedefs
|
||||||
p = re.compile(
|
p = re.compile(
|
||||||
r'\n' + _cre_space + r'typedef' + _cre_space + _cre_typedef + r';',
|
r'\n' + _cre_space + r'typedef' + _cre_space + _cre_typedef + r';',
|
||||||
@ -895,13 +1071,19 @@ class obj_class:
|
|||||||
|
|
||||||
# build the virtual function objects
|
# build the virtual function objects
|
||||||
self.virtualfuncs = []
|
self.virtualfuncs = []
|
||||||
|
self.has_versioned_funcs = False
|
||||||
for attrib, retval, argval, vfmod in list:
|
for attrib, retval, argval, vfmod in list:
|
||||||
comment = get_comment(body, retval + '(' + argval + ')')
|
comment = get_comment(body, retval + '(' + argval + ')')
|
||||||
validate_comment(filename, retval, comment)
|
validate_comment(filename, retval, comment)
|
||||||
|
if not self.has_versioned_funcs and _has_version(attrib):
|
||||||
|
self.has_versioned_funcs = True
|
||||||
self.virtualfuncs.append(
|
self.virtualfuncs.append(
|
||||||
obj_function_virtual(self, attrib, retval, argval, comment,
|
obj_function_virtual(self, attrib, retval, argval, comment,
|
||||||
vfmod.strip()))
|
vfmod.strip()))
|
||||||
|
|
||||||
|
self.virtualfuncs_ordered = None
|
||||||
|
self.allversions = None
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
result = '/* ' + dict_to_str(
|
result = '/* ' + dict_to_str(
|
||||||
self.attribs) + ' */ class ' + self.name + "\n{"
|
self.attribs) + ' */ class ' + self.name + "\n{"
|
||||||
@ -930,15 +1112,21 @@ class obj_class:
|
|||||||
result += "\n};\n"
|
result += "\n};\n"
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def _validate_attribs(self):
|
||||||
|
for key in self.attribs.keys():
|
||||||
|
if not key in CLASS_ATTRIB_KEYS:
|
||||||
|
raise Exception('Invalid attribute key \"%s\" for class %s' %
|
||||||
|
(key, self.get_name()))
|
||||||
|
|
||||||
def get_file_name(self):
|
def get_file_name(self):
|
||||||
""" Return the C++ header file name. Includes the directory component,
|
""" Return the C++ header file name. Includes the directory component,
|
||||||
if any. """
|
if any. """
|
||||||
return self.filename
|
return self.filename
|
||||||
|
|
||||||
def get_capi_file_name(self):
|
def get_capi_file_name(self, versions=False):
|
||||||
""" Return the CAPI header file name. Includes the directory component,
|
""" Return the CAPI header file name. Includes the directory component,
|
||||||
if any. """
|
if any. """
|
||||||
return get_capi_file_name(self.filename)
|
return get_capi_file_name(self.filename, versions)
|
||||||
|
|
||||||
def get_file_directory(self):
|
def get_file_directory(self):
|
||||||
""" Return the file directory component, if any. """
|
""" Return the file directory component, if any. """
|
||||||
@ -947,21 +1135,44 @@ class obj_class:
|
|||||||
return self.filename[:pos]
|
return self.filename[:pos]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self, version=None):
|
||||||
""" Return the class name. """
|
""" Return the class name. """
|
||||||
|
if not version is None:
|
||||||
|
# Select the appropriate version for this class.
|
||||||
|
closest_version = self.get_closest_version(version)
|
||||||
|
if closest_version is None:
|
||||||
|
raise Exception('Cannot find version <= %d for %s' % (version,
|
||||||
|
self.name))
|
||||||
|
return '%s_%d_' % (self.name, closest_version)
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def get_capi_name(self):
|
def get_capi_name(self, version=None, first_version=False):
|
||||||
""" Return the CAPI structure name for this class. """
|
""" Return the CAPI structure name for this class. """
|
||||||
return get_capi_name(self.name, True)
|
# Select the appropriate version for this class.
|
||||||
|
if first_version:
|
||||||
|
version = self.get_first_version()
|
||||||
|
elif not version is None:
|
||||||
|
closest_version = self.get_closest_version(version)
|
||||||
|
if closest_version is None:
|
||||||
|
raise Exception('Cannot find version <= %d for %s' % (version,
|
||||||
|
self.name))
|
||||||
|
version = closest_version
|
||||||
|
return get_capi_name(self.name, True, version=version)
|
||||||
|
|
||||||
def get_parent_name(self):
|
def get_parent_name(self):
|
||||||
""" Return the parent class name. """
|
""" Return the parent class name. """
|
||||||
return self.parent_name
|
return self.parent_name
|
||||||
|
|
||||||
def get_parent_capi_name(self):
|
def get_parent_capi_name(self, version=None):
|
||||||
""" Return the CAPI structure name for the parent class. """
|
""" Return the CAPI structure name for the parent class. """
|
||||||
return get_capi_name(self.parent_name, True)
|
if not version is None:
|
||||||
|
# Select the appropriate version for the parent class.
|
||||||
|
if is_base_class(self.parent_name):
|
||||||
|
version = None
|
||||||
|
else:
|
||||||
|
parent_cls = self.parent.get_class(self.parent_name)
|
||||||
|
version = parent_cls.get_closest_version(version)
|
||||||
|
return get_capi_name(self.parent_name, True, version=version)
|
||||||
|
|
||||||
def has_parent(self, parent_name):
|
def has_parent(self, parent_name):
|
||||||
""" Returns true if this class has the specified class anywhere in its
|
""" Returns true if this class has the specified class anywhere in its
|
||||||
@ -1043,8 +1254,17 @@ class obj_class:
|
|||||||
""" Return the array of static function objects. """
|
""" Return the array of static function objects. """
|
||||||
return self.staticfuncs
|
return self.staticfuncs
|
||||||
|
|
||||||
def get_virtual_funcs(self):
|
def get_virtual_funcs(self, version_order=False, version=None):
|
||||||
""" Return the array of virtual function objects. """
|
""" Return the array of virtual function objects. """
|
||||||
|
if version_order and self.has_versioned_funcs:
|
||||||
|
if version is None:
|
||||||
|
# Cache the ordering result for future use.
|
||||||
|
if self.virtualfuncs_ordered is None:
|
||||||
|
self.virtualfuncs_ordered = _version_order_funcs(self.virtualfuncs)
|
||||||
|
return self.virtualfuncs_ordered
|
||||||
|
|
||||||
|
# Need to order each time to apply the max version.
|
||||||
|
return _version_order_funcs(self.virtualfuncs, version)
|
||||||
return self.virtualfuncs
|
return self.virtualfuncs
|
||||||
|
|
||||||
def get_types(self, list):
|
def get_types(self, list):
|
||||||
@ -1078,6 +1298,75 @@ class obj_class:
|
|||||||
""" Returns true if the class is implemented by the client. """
|
""" Returns true if the class is implemented by the client. """
|
||||||
return self.attribs['source'] == 'client'
|
return self.attribs['source'] == 'client'
|
||||||
|
|
||||||
|
def has_version(self):
|
||||||
|
""" Returns true if the class has an associated version. """
|
||||||
|
return _has_version(self.attribs)
|
||||||
|
|
||||||
|
def has_version_added(self):
|
||||||
|
""" Returns true if the class has an associated 'added' version. """
|
||||||
|
return _has_version_added(self.attribs)
|
||||||
|
|
||||||
|
def get_version_added(self):
|
||||||
|
""" Returns the associated 'added' version. """
|
||||||
|
return _get_version_added(self.attribs)
|
||||||
|
|
||||||
|
def has_version_removed(self):
|
||||||
|
""" Returns true if the class has an associated 'removed' version. """
|
||||||
|
return _has_version_removed(self.attribs)
|
||||||
|
|
||||||
|
def get_version_removed(self):
|
||||||
|
""" Returns the associated 'removed' version. """
|
||||||
|
return _get_version_removed(self.attribs)
|
||||||
|
|
||||||
|
def removed_at_version(self, version):
|
||||||
|
""" Returns true if this class is removed at the specified version. """
|
||||||
|
return self.has_version_removed() and self.get_version_removed() <= version
|
||||||
|
|
||||||
|
def exists_at_version(self, version):
|
||||||
|
""" Returns true if this class exists at the specified version. """
|
||||||
|
if self.has_version_added() and self.get_version_added() > version:
|
||||||
|
return False
|
||||||
|
return not self.removed_at_version(version)
|
||||||
|
|
||||||
|
def get_version_check(self):
|
||||||
|
""" Returns the #if check for the associated version. """
|
||||||
|
return get_version_check(self.attribs)
|
||||||
|
|
||||||
|
def get_all_versions(self):
|
||||||
|
""" Returns all distinct versions of this class. """
|
||||||
|
if not self.allversions is None:
|
||||||
|
return self.allversions
|
||||||
|
|
||||||
|
# Using a set to ensure uniqueness.
|
||||||
|
versions = set()
|
||||||
|
|
||||||
|
# Versions from class inheritance.
|
||||||
|
if not is_base_class(self.parent_name):
|
||||||
|
versions.update(
|
||||||
|
self.parent.get_class(self.parent_name).get_all_versions())
|
||||||
|
|
||||||
|
# Versions from virtual methods.
|
||||||
|
versions.update(_get_all_versions(self.virtualfuncs))
|
||||||
|
|
||||||
|
versions = list(versions)
|
||||||
|
|
||||||
|
# Clamp to class versions, if specified.
|
||||||
|
if self.has_version_added():
|
||||||
|
versions = [x for x in versions if x >= self.get_version_added()]
|
||||||
|
if self.has_version_removed():
|
||||||
|
versions = [x for x in versions if x < self.get_version_removed()]
|
||||||
|
|
||||||
|
self.allversions = sorted(versions)
|
||||||
|
return self.allversions
|
||||||
|
|
||||||
|
def get_first_version(self):
|
||||||
|
""" Returns the first version. """
|
||||||
|
return self.get_all_versions()[0]
|
||||||
|
|
||||||
|
def get_closest_version(self, version):
|
||||||
|
""" Returns the closest version to |version| that is not greater, or None. """
|
||||||
|
return _find_closest_not_greater(self.get_all_versions(), version)
|
||||||
|
|
||||||
|
|
||||||
class obj_typedef:
|
class obj_typedef:
|
||||||
""" Class representing a typedef statement. """
|
""" Class representing a typedef statement. """
|
||||||
@ -1099,9 +1388,9 @@ class obj_typedef:
|
|||||||
""" Return the C++ header file name. """
|
""" Return the C++ header file name. """
|
||||||
return self.filename
|
return self.filename
|
||||||
|
|
||||||
def get_capi_file_name(self):
|
def get_capi_file_name(self, versions=False):
|
||||||
""" Return the CAPI header file name. """
|
""" Return the CAPI header file name. """
|
||||||
return get_capi_file_name(self.filename)
|
return get_capi_file_name(self.filename, versions)
|
||||||
|
|
||||||
def get_alias(self):
|
def get_alias(self):
|
||||||
""" Return the alias. """
|
""" Return the alias. """
|
||||||
@ -1131,6 +1420,8 @@ class obj_function:
|
|||||||
self.name = self.retval.remove_name()
|
self.name = self.retval.remove_name()
|
||||||
self.comment = comment
|
self.comment = comment
|
||||||
|
|
||||||
|
self._validate_attribs()
|
||||||
|
|
||||||
# build the argument objects
|
# build the argument objects
|
||||||
self.arguments = []
|
self.arguments = []
|
||||||
arglist = argval.split(',')
|
arglist = argval.split(',')
|
||||||
@ -1163,13 +1454,19 @@ class obj_function:
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '/* ' + dict_to_str(self.attribs) + ' */ ' + self.get_cpp_proto()
|
return '/* ' + dict_to_str(self.attribs) + ' */ ' + self.get_cpp_proto()
|
||||||
|
|
||||||
|
def _validate_attribs(self):
|
||||||
|
for key in self.attribs.keys():
|
||||||
|
if not key in FUNCTION_ATTRIB_KEYS:
|
||||||
|
raise Exception('Invalid attribute key \"%s\" for %s' %
|
||||||
|
(key, self.get_qualified_name()))
|
||||||
|
|
||||||
def get_file_name(self):
|
def get_file_name(self):
|
||||||
""" Return the C++ header file name. """
|
""" Return the C++ header file name. """
|
||||||
return self.filename
|
return self.filename
|
||||||
|
|
||||||
def get_capi_file_name(self):
|
def get_capi_file_name(self, versions=False):
|
||||||
""" Return the CAPI header file name. """
|
""" Return the CAPI header file name. """
|
||||||
return get_capi_file_name(self.filename)
|
return get_capi_file_name(self.filename, versions)
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
""" Return the function name. """
|
""" Return the function name. """
|
||||||
@ -1186,9 +1483,7 @@ class obj_function:
|
|||||||
|
|
||||||
def get_capi_name(self, prefix=None):
|
def get_capi_name(self, prefix=None):
|
||||||
""" Return the CAPI function name. """
|
""" Return the CAPI function name. """
|
||||||
if 'capi_name' in self.attribs:
|
return get_capi_name(self.get_attrib('capi_name', self.name), False, prefix)
|
||||||
return self.attribs['capi_name']
|
|
||||||
return get_capi_name(self.name, False, prefix)
|
|
||||||
|
|
||||||
def get_comment(self):
|
def get_comment(self):
|
||||||
""" Return the function comment as an array of lines. """
|
""" Return the function comment as an array of lines. """
|
||||||
@ -1202,7 +1497,7 @@ class obj_function:
|
|||||||
""" Return true if the specified attribute exists. """
|
""" Return true if the specified attribute exists. """
|
||||||
return name in self.attribs
|
return name in self.attribs
|
||||||
|
|
||||||
def get_attrib(self, name):
|
def get_attrib(self, name, default=None):
|
||||||
""" Return the first or only value for specified attribute. """
|
""" Return the first or only value for specified attribute. """
|
||||||
if name in self.attribs:
|
if name in self.attribs:
|
||||||
if isinstance(self.attribs[name], list):
|
if isinstance(self.attribs[name], list):
|
||||||
@ -1211,7 +1506,7 @@ class obj_function:
|
|||||||
else:
|
else:
|
||||||
# the value is a string
|
# the value is a string
|
||||||
return self.attribs[name]
|
return self.attribs[name]
|
||||||
return None
|
return default
|
||||||
|
|
||||||
def get_attrib_list(self, name):
|
def get_attrib_list(self, name):
|
||||||
""" Return all values for specified attribute as a list. """
|
""" Return all values for specified attribute as a list. """
|
||||||
@ -1237,10 +1532,15 @@ class obj_function:
|
|||||||
for cls in self.arguments:
|
for cls in self.arguments:
|
||||||
cls.get_types(list)
|
cls.get_types(list)
|
||||||
|
|
||||||
def get_capi_parts(self, defined_structs=[], isimpl=False, prefix=None):
|
def get_capi_parts(self,
|
||||||
|
defined_structs=[],
|
||||||
|
isimpl=False,
|
||||||
|
prefix=None,
|
||||||
|
version=None,
|
||||||
|
version_finder=None):
|
||||||
""" Return the parts of the C API function definition. """
|
""" Return the parts of the C API function definition. """
|
||||||
retval = ''
|
retval = ''
|
||||||
dict = self.retval.get_type().get_capi(defined_structs)
|
dict = self.retval.get_type().get_capi(defined_structs, version_finder)
|
||||||
if dict['format'] == 'single':
|
if dict['format'] == 'single':
|
||||||
retval = dict['value']
|
retval = dict['value']
|
||||||
|
|
||||||
@ -1249,7 +1549,7 @@ class obj_function:
|
|||||||
|
|
||||||
if isinstance(self, obj_function_virtual):
|
if isinstance(self, obj_function_virtual):
|
||||||
# virtual functions get themselves as the first argument
|
# virtual functions get themselves as the first argument
|
||||||
str = 'struct _' + self.parent.get_capi_name() + '* self'
|
str = 'struct _' + self.parent.get_capi_name(version=version) + '* self'
|
||||||
if isinstance(self, obj_function_virtual) and self.is_const():
|
if isinstance(self, obj_function_virtual) and self.is_const():
|
||||||
# const virtual functions get const self pointers
|
# const virtual functions get const self pointers
|
||||||
str = 'const ' + str
|
str = 'const ' + str
|
||||||
@ -1260,7 +1560,7 @@ class obj_function:
|
|||||||
if len(self.arguments) > 0:
|
if len(self.arguments) > 0:
|
||||||
for cls in self.arguments:
|
for cls in self.arguments:
|
||||||
type = cls.get_type()
|
type = cls.get_type()
|
||||||
dict = type.get_capi(defined_structs)
|
dict = type.get_capi(defined_structs, version_finder)
|
||||||
if dict['format'] == 'single':
|
if dict['format'] == 'single':
|
||||||
args.append(dict['value'])
|
args.append(dict['value'])
|
||||||
elif dict['format'] == 'multi-arg':
|
elif dict['format'] == 'multi-arg':
|
||||||
@ -1276,9 +1576,15 @@ class obj_function:
|
|||||||
|
|
||||||
return {'retval': retval, 'name': name, 'args': args}
|
return {'retval': retval, 'name': name, 'args': args}
|
||||||
|
|
||||||
def get_capi_proto(self, defined_structs=[], isimpl=False, prefix=None):
|
def get_capi_proto(self,
|
||||||
|
defined_structs=[],
|
||||||
|
isimpl=False,
|
||||||
|
prefix=None,
|
||||||
|
version=None,
|
||||||
|
version_finder=None):
|
||||||
""" Return the prototype of the C API function. """
|
""" Return the prototype of the C API function. """
|
||||||
parts = self.get_capi_parts(defined_structs, isimpl, prefix)
|
parts = self.get_capi_parts(defined_structs, isimpl, prefix, version,
|
||||||
|
version_finder)
|
||||||
result = parts['retval']+' '+parts['name']+ \
|
result = parts['retval']+' '+parts['name']+ \
|
||||||
'('+', '.join(parts['args'])+')'
|
'('+', '.join(parts['args'])+')'
|
||||||
return result
|
return result
|
||||||
@ -1336,6 +1642,14 @@ class obj_function:
|
|||||||
|
|
||||||
return other_is_library_side == this_is_library_side
|
return other_is_library_side == this_is_library_side
|
||||||
|
|
||||||
|
def has_version(self):
|
||||||
|
""" Returns true if the class has an associated version. """
|
||||||
|
return _has_version(self.attribs)
|
||||||
|
|
||||||
|
def get_version_check(self):
|
||||||
|
""" Returns the #if check for the associated version. """
|
||||||
|
return get_version_check(self.attribs)
|
||||||
|
|
||||||
|
|
||||||
class obj_function_static(obj_function):
|
class obj_function_static(obj_function):
|
||||||
""" Class representing a static function. """
|
""" Class representing a static function. """
|
||||||
@ -1377,6 +1691,34 @@ class obj_function_virtual(obj_function):
|
|||||||
""" Returns true if the method declaration is const. """
|
""" Returns true if the method declaration is const. """
|
||||||
return self.isconst
|
return self.isconst
|
||||||
|
|
||||||
|
def has_version_added(self):
|
||||||
|
""" Returns true if a 'added' value was specified. """
|
||||||
|
return _has_version_added(self.attribs)
|
||||||
|
|
||||||
|
def get_version_added(self):
|
||||||
|
""" Returns the numeric 'added' value, or 0 if unspecified.
|
||||||
|
Used for sorting purposes only. """
|
||||||
|
return _get_version_added(self.attribs)
|
||||||
|
|
||||||
|
def has_version_removed(self):
|
||||||
|
""" Returns true if a 'removed' value was specified. """
|
||||||
|
return _has_version_removed(self.attribs)
|
||||||
|
|
||||||
|
def get_version_removed(self):
|
||||||
|
""" Returns the numeric 'removed' value, or 0 if unspecified.
|
||||||
|
Used for sorting purposes only. """
|
||||||
|
return _get_version_removed(self.attribs)
|
||||||
|
|
||||||
|
def removed_at_version(self, version):
|
||||||
|
""" Returns true if this function is removed at the specified version. """
|
||||||
|
return self.has_version_removed() and self.get_version_removed() <= version
|
||||||
|
|
||||||
|
def exists_at_version(self, version):
|
||||||
|
""" Returns true if this function exists at the specified version. """
|
||||||
|
if self.has_version_added() and self.get_version_added() > version:
|
||||||
|
return False
|
||||||
|
return not self.removed_at_version(version)
|
||||||
|
|
||||||
|
|
||||||
class obj_argument:
|
class obj_argument:
|
||||||
""" Class representing a function argument. """
|
""" Class representing a function argument. """
|
||||||
@ -1907,12 +2249,15 @@ class obj_analysis:
|
|||||||
""" Return the *Ptr type structure name. """
|
""" Return the *Ptr type structure name. """
|
||||||
return self.result_value[:-1]
|
return self.result_value[:-1]
|
||||||
|
|
||||||
def get_result_ptr_type(self, defined_structs=[]):
|
def get_result_ptr_type(self, defined_structs=[], version_finder=None):
|
||||||
""" Return the *Ptr type. """
|
""" Return the *Ptr type. """
|
||||||
result = ''
|
result = ''
|
||||||
if not self.result_value[:-1] in defined_structs:
|
name = self.result_value[:-1]
|
||||||
|
if not version_finder is None:
|
||||||
|
name = version_finder(name)
|
||||||
|
if not name in defined_structs:
|
||||||
result += 'struct _'
|
result += 'struct _'
|
||||||
result += self.result_value
|
result += name + self.result_value[-1]
|
||||||
if self.is_byref() or self.is_byaddr():
|
if self.is_byref() or self.is_byaddr():
|
||||||
result += '*'
|
result += '*'
|
||||||
return result
|
return result
|
||||||
@ -1951,16 +2296,22 @@ class obj_analysis:
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_result_struct_type(self, defined_structs=[]):
|
def get_result_struct_type(self, defined_structs=[], version_finder=None):
|
||||||
""" Return the structure or enumeration type. """
|
""" Return the structure or enumeration type. """
|
||||||
result = ''
|
result = ''
|
||||||
|
|
||||||
|
name = self.result_value
|
||||||
|
|
||||||
is_enum = self.is_result_struct_enum()
|
is_enum = self.is_result_struct_enum()
|
||||||
if not is_enum:
|
if not is_enum:
|
||||||
if self.is_const():
|
if self.is_const():
|
||||||
result += 'const '
|
result += 'const '
|
||||||
if not self.result_value in defined_structs:
|
if not self.result_value in defined_structs:
|
||||||
result += 'struct _'
|
result += 'struct _'
|
||||||
result += self.result_value
|
if not version_finder is None:
|
||||||
|
name = version_finder(name)
|
||||||
|
|
||||||
|
result += name
|
||||||
if not is_enum:
|
if not is_enum:
|
||||||
result += '*'
|
result += '*'
|
||||||
return result
|
return result
|
||||||
@ -2026,7 +2377,7 @@ class obj_analysis:
|
|||||||
""" Return the vector structure or basic type name. """
|
""" Return the vector structure or basic type name. """
|
||||||
return self.result_value[0]['result_value']
|
return self.result_value[0]['result_value']
|
||||||
|
|
||||||
def get_result_vector_type(self, defined_structs=[]):
|
def get_result_vector_type(self, defined_structs=[], version_finder=None):
|
||||||
""" Return the vector type. """
|
""" Return the vector type. """
|
||||||
if not self.has_name():
|
if not self.has_name():
|
||||||
raise Exception('Cannot use vector as a return type')
|
raise Exception('Cannot use vector as a return type')
|
||||||
@ -2048,9 +2399,15 @@ class obj_analysis:
|
|||||||
result['value'] = str
|
result['value'] = str
|
||||||
elif type == 'refptr' or type == 'ownptr' or type == 'rawptr':
|
elif type == 'refptr' or type == 'ownptr' or type == 'rawptr':
|
||||||
str = ''
|
str = ''
|
||||||
if not value[:-1] in defined_structs:
|
|
||||||
|
# remove the * suffix
|
||||||
|
name = value[:-1]
|
||||||
|
if not version_finder is None:
|
||||||
|
name = version_finder(name)
|
||||||
|
|
||||||
|
if not name in defined_structs:
|
||||||
str += 'struct _'
|
str += 'struct _'
|
||||||
str += value
|
str += name + value[-1]
|
||||||
if self.is_const():
|
if self.is_const():
|
||||||
str += ' const'
|
str += ' const'
|
||||||
str += '*'
|
str += '*'
|
||||||
@ -2087,16 +2444,16 @@ class obj_analysis:
|
|||||||
return {'value': 'cef_string_multimap_t', 'format': 'multi'}
|
return {'value': 'cef_string_multimap_t', 'format': 'multi'}
|
||||||
raise Exception('Only mappings of strings to strings are supported')
|
raise Exception('Only mappings of strings to strings are supported')
|
||||||
|
|
||||||
def get_capi(self, defined_structs=[]):
|
def get_capi(self, defined_structs=[], version_finder=None):
|
||||||
""" Format the value for the C API. """
|
""" Format the value for the C API. """
|
||||||
result = ''
|
result = ''
|
||||||
format = 'single'
|
format = 'single'
|
||||||
if self.is_result_simple():
|
if self.is_result_simple():
|
||||||
result += self.get_result_simple_type()
|
result += self.get_result_simple_type()
|
||||||
elif self.is_result_ptr():
|
elif self.is_result_ptr():
|
||||||
result += self.get_result_ptr_type(defined_structs)
|
result += self.get_result_ptr_type(defined_structs, version_finder)
|
||||||
elif self.is_result_struct():
|
elif self.is_result_struct():
|
||||||
result += self.get_result_struct_type(defined_structs)
|
result += self.get_result_struct_type(defined_structs, version_finder)
|
||||||
elif self.is_result_string():
|
elif self.is_result_string():
|
||||||
result += self.get_result_string_type()
|
result += self.get_result_string_type()
|
||||||
elif self.is_result_map():
|
elif self.is_result_map():
|
||||||
@ -2106,7 +2463,7 @@ class obj_analysis:
|
|||||||
else:
|
else:
|
||||||
raise Exception('Unsupported map type')
|
raise Exception('Unsupported map type')
|
||||||
elif self.is_result_vector():
|
elif self.is_result_vector():
|
||||||
resdict = self.get_result_vector_type(defined_structs)
|
resdict = self.get_result_vector_type(defined_structs, version_finder)
|
||||||
if resdict['format'] != 'single':
|
if resdict['format'] != 'single':
|
||||||
format = resdict['format']
|
format = resdict['format']
|
||||||
result += resdict['value']
|
result += resdict['value']
|
||||||
|
@ -7,6 +7,7 @@ from __future__ import print_function
|
|||||||
from file_util import *
|
from file_util import *
|
||||||
import git_util as git
|
import git_util as git
|
||||||
import os
|
import os
|
||||||
|
from version_util import read_version_last, version_parse, VERSIONS_JSON_FILE
|
||||||
|
|
||||||
|
|
||||||
class VersionFormatter:
|
class VersionFormatter:
|
||||||
@ -46,15 +47,18 @@ class VersionFormatter:
|
|||||||
if not bool(self._chrome_version):
|
if not bool(self._chrome_version):
|
||||||
file_path = os.path.join(self.src_path, 'chrome', 'VERSION')
|
file_path = os.path.join(self.src_path, 'chrome', 'VERSION')
|
||||||
assert os.path.isfile(file_path), file_path
|
assert os.path.isfile(file_path), file_path
|
||||||
read_version_file(file_path, self._chrome_version)
|
assert read_version_file(file_path, self._chrome_version), file_path
|
||||||
return self._chrome_version
|
return self._chrome_version
|
||||||
|
|
||||||
|
def get_chrome_major_version(self):
|
||||||
|
return self.get_chrome_version_components()['MAJOR']
|
||||||
|
|
||||||
def get_cef_version_components(self):
|
def get_cef_version_components(self):
|
||||||
""" Returns CEF version components. """
|
""" Returns CEF version components. """
|
||||||
if not bool(self._cef_version):
|
if not bool(self._cef_version):
|
||||||
file_path = os.path.join(self.cef_path, 'VERSION.in')
|
file_path = os.path.join(self.cef_path, 'VERSION.in')
|
||||||
assert os.path.isfile(file_path), file_path
|
assert os.path.isfile(file_path), file_path
|
||||||
read_version_file(file_path, self._cef_version)
|
assert read_version_file(file_path, self._cef_version), file_path
|
||||||
return self._cef_version
|
return self._cef_version
|
||||||
|
|
||||||
def get_cef_commit_components(self):
|
def get_cef_commit_components(self):
|
||||||
@ -75,11 +79,11 @@ class VersionFormatter:
|
|||||||
# branch since branching from origin/master.
|
# branch since branching from origin/master.
|
||||||
hashes = git.get_branch_hashes(self.cef_path)
|
hashes = git.get_branch_hashes(self.cef_path)
|
||||||
for hash in hashes:
|
for hash in hashes:
|
||||||
# Determine if the API hash file was modified by the commit.
|
# Determine if the API versions file was modified by the commit.
|
||||||
found = False
|
found = False
|
||||||
files = git.get_changed_files(self.cef_path, hash)
|
files = git.get_changed_files(self.cef_path, hash)
|
||||||
for file in files:
|
for file in files:
|
||||||
if file.find('cef_api_hash.h') >= 0:
|
if file.find(VERSIONS_JSON_FILE) >= 0:
|
||||||
found = True
|
found = True
|
||||||
break
|
break
|
||||||
|
|
||||||
@ -89,6 +93,14 @@ class VersionFormatter:
|
|||||||
else:
|
else:
|
||||||
bugfix += 1
|
bugfix += 1
|
||||||
|
|
||||||
|
last_version = read_version_last(
|
||||||
|
os.path.join(self.cef_path, VERSIONS_JSON_FILE))
|
||||||
|
if not last_version is None:
|
||||||
|
major, revision = version_parse(last_version)
|
||||||
|
if major == int(self.get_chrome_major_version()) and revision > minor:
|
||||||
|
# Override the computed minor version with the last specified API version.
|
||||||
|
minor = revision
|
||||||
|
|
||||||
self._branch_version = {'MINOR': minor, 'PATCH': bugfix}
|
self._branch_version = {'MINOR': minor, 'PATCH': bugfix}
|
||||||
return self._branch_version
|
return self._branch_version
|
||||||
|
|
||||||
@ -149,8 +161,8 @@ class VersionFormatter:
|
|||||||
# - "X" is the Chromium major version (e.g. 74).
|
# - "X" is the Chromium major version (e.g. 74).
|
||||||
# - "Y" is an incremental number that starts at 0 when a release branch is
|
# - "Y" is an incremental number that starts at 0 when a release branch is
|
||||||
# created and changes only when the CEF C/C++ API changes (similar to how
|
# created and changes only when the CEF C/C++ API changes (similar to how
|
||||||
# the CEF_API_HASH_UNIVERSAL value behaves in cef_version.h) (release branch
|
# the CEF_API_HASH_UNIVERSAL value behaves in cef_api_hash.h) (release
|
||||||
# only).
|
# branch only).
|
||||||
# - "Z" is an incremental number that starts at 0 when a release branch is
|
# - "Z" is an incremental number that starts at 0 when a release branch is
|
||||||
# created and changes on each commit, with reset to 0 when "Y" changes
|
# created and changes on each commit, with reset to 0 when "Y" changes
|
||||||
# (release branch only).
|
# (release branch only).
|
||||||
@ -186,9 +198,15 @@ class VersionFormatter:
|
|||||||
# if we can get the name of the branch we are on (may be just "HEAD").
|
# if we can get the name of the branch we are on (may be just "HEAD").
|
||||||
cef_branch_name = git.get_branch_name(self.cef_path).split('/')[-1]
|
cef_branch_name = git.get_branch_name(self.cef_path).split('/')[-1]
|
||||||
|
|
||||||
|
cef_minor = cef_patch = 0
|
||||||
|
if cef_branch_name != 'HEAD' and cef_branch_name != 'master':
|
||||||
|
cef_branch = self.get_cef_branch_version_components()
|
||||||
|
cef_minor = cef_branch['MINOR']
|
||||||
|
cef_patch = cef_branch['PATCH']
|
||||||
|
|
||||||
self._version_parts = {'MAJOR': int(chrome_major), 'MINOR': 0, 'PATCH': 0}
|
self._version_parts = {'MAJOR': int(chrome_major), 'MINOR': 0, 'PATCH': 0}
|
||||||
self._version_string = '%s.0.0-%s.%s+%s+%s' % \
|
self._version_string = '%s.%d.%d-%s.%s+%s+%s' % \
|
||||||
(chrome_major, cef_branch_name, cef_commit['NUMBER'],
|
(chrome_major, cef_minor, cef_patch, cef_branch_name, cef_commit['NUMBER'],
|
||||||
cef_commit_hash, chrome_version_part)
|
cef_commit_hash, chrome_version_part)
|
||||||
else:
|
else:
|
||||||
cef_branch = self.get_cef_branch_version_components()
|
cef_branch = self.get_cef_branch_version_components()
|
||||||
|
@ -10,22 +10,66 @@ import sys
|
|||||||
|
|
||||||
# Script directory.
|
# Script directory.
|
||||||
script_dir = os.path.dirname(__file__)
|
script_dir = os.path.dirname(__file__)
|
||||||
root_dir = os.path.join(script_dir, os.pardir)
|
cef_dir = os.path.join(script_dir, os.pardir)
|
||||||
|
src_dir = os.path.abspath(os.path.join(cef_dir, os.pardir))
|
||||||
|
llvm_bin_dir = os.path.join(src_dir,
|
||||||
|
'third_party/llvm-build/Release+Asserts/bin')
|
||||||
|
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
# Force use of the clang-format version bundled with depot_tools.
|
# Force use of the clang-format version bundled with depot_tools.
|
||||||
clang_format_exe = 'clang-format.bat'
|
clang_format_exe = 'clang-format.bat'
|
||||||
|
clang_exe = os.path.join(llvm_bin_dir, 'clang-cl.exe')
|
||||||
else:
|
else:
|
||||||
clang_format_exe = 'clang-format'
|
clang_format_exe = 'clang-format'
|
||||||
|
clang_exe = os.path.join(llvm_bin_dir, 'clang')
|
||||||
|
|
||||||
|
|
||||||
def clang_format(file_name, file_contents):
|
def clang_format(file_name, file_contents):
|
||||||
# -assume-filename is necessary to find the .clang-format file and determine
|
# -assume-filename is necessary to find the .clang-format file and determine
|
||||||
# the language when specifying contents via stdin.
|
# the language when specifying contents via stdin.
|
||||||
result = exec_cmd("%s -assume-filename=%s" % (clang_format_exe, file_name), \
|
result = exec_cmd("%s -assume-filename=%s" % (clang_format_exe, file_name), \
|
||||||
root_dir, file_contents.encode('utf-8'))
|
cef_dir, file_contents.encode('utf-8'))
|
||||||
if result['err'] != '':
|
if result['err'] != '':
|
||||||
print("clang-format error: %s" % result['err'])
|
sys.stderr.write("clang-format error: %s\n" % result['err'])
|
||||||
|
if result['out'] != '':
|
||||||
|
output = result['out']
|
||||||
|
if sys.platform == 'win32':
|
||||||
|
# Convert to Unix line endings.
|
||||||
|
output = output.replace("\r", "")
|
||||||
|
return output
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def clang_format_inplace(file_name):
|
||||||
|
result = exec_cmd("%s -i %s" % (clang_format_exe, file_name), cef_dir)
|
||||||
|
if result['err'] != '':
|
||||||
|
sys.stderr.write("clang-format error: %s\n" % result['err'])
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def clang_eval(file_name,
|
||||||
|
file_contents,
|
||||||
|
defines=[],
|
||||||
|
includes=[],
|
||||||
|
as_cpp=True,
|
||||||
|
verbose=False):
|
||||||
|
lang = 'c++' if as_cpp else 'c'
|
||||||
|
if file_name.lower().endswith('.h'):
|
||||||
|
lang += '-header'
|
||||||
|
# The -P option removes unnecessary line markers and whitespace.
|
||||||
|
format = '/EP' if sys.platform == 'win32' else '-E -P'
|
||||||
|
cmd = "%s -x %s %s %s %s -" % (clang_exe, lang, format,
|
||||||
|
' '.join(['-D' + v for v in defines]),
|
||||||
|
' '.join(['-I' + v for v in includes]))
|
||||||
|
if verbose:
|
||||||
|
print('--- Running "%s" in "%s"' % (cmd, cef_dir))
|
||||||
|
|
||||||
|
result = exec_cmd(cmd, cef_dir, file_contents.encode('utf-8'))
|
||||||
|
if result['err'] != '':
|
||||||
|
err = result['err'].replace('<stdin>', file_name)
|
||||||
|
sys.stderr.write("clang error: %s\n" % err)
|
||||||
|
return None
|
||||||
if result['out'] != '':
|
if result['out'] != '':
|
||||||
output = result['out']
|
output = result['out']
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
|
@ -3,19 +3,22 @@
|
|||||||
# can be found in the LICENSE file.
|
# can be found in the LICENSE file.
|
||||||
|
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
import codecs
|
||||||
|
import fnmatch
|
||||||
from glob import iglob
|
from glob import iglob
|
||||||
from io import open
|
from io import open
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import fnmatch
|
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
|
||||||
def read_file(name, normalize=True):
|
def read_file(path, normalize=True):
|
||||||
""" Read a file. """
|
""" Read a file. """
|
||||||
|
if os.path.isfile(path):
|
||||||
try:
|
try:
|
||||||
with open(name, 'r', encoding='utf-8') as f:
|
with open(path, 'r', encoding='utf-8') as f:
|
||||||
# read the data
|
# read the data
|
||||||
data = f.read()
|
data = f.read()
|
||||||
if normalize:
|
if normalize:
|
||||||
@ -24,14 +27,21 @@ def read_file(name, normalize=True):
|
|||||||
return data
|
return data
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
(errno, strerror) = e.args
|
(errno, strerror) = e.args
|
||||||
sys.stderr.write('Failed to read file ' + name + ': ' + strerror)
|
sys.stderr.write('ERROR: Failed to read file ' + path + ': ' + strerror)
|
||||||
raise
|
raise
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def write_file(name, data):
|
def write_file(path, data, overwrite=True, quiet=True):
|
||||||
""" Write a file. """
|
""" Write a file. """
|
||||||
|
if not overwrite and os.path.exists(path):
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not quiet:
|
||||||
|
print('Writing file %s' % path)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(name, 'w', encoding='utf-8', newline='\n') as f:
|
with open(path, 'w', encoding='utf-8', newline='\n') as f:
|
||||||
# write the data
|
# write the data
|
||||||
if sys.version_info.major == 2:
|
if sys.version_info.major == 2:
|
||||||
f.write(data.decode('utf-8'))
|
f.write(data.decode('utf-8'))
|
||||||
@ -39,57 +49,67 @@ def write_file(name, data):
|
|||||||
f.write(data)
|
f.write(data)
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
(errno, strerror) = e.args
|
(errno, strerror) = e.args
|
||||||
sys.stderr.write('Failed to write file ' + name + ': ' + strerror)
|
sys.stderr.write('ERROR: Failed to write file ' + path + ': ' + strerror)
|
||||||
raise
|
raise
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def path_exists(name):
|
def path_exists(path):
|
||||||
""" Returns true if the path currently exists. """
|
""" Returns true if the path currently exists. """
|
||||||
return os.path.exists(name)
|
return os.path.exists(path)
|
||||||
|
|
||||||
|
|
||||||
def write_file_if_changed(name, data):
|
def write_file_if_changed(path, data, quiet=True):
|
||||||
""" Write a file if the contents have changed. Returns True if the file was written. """
|
""" Write a file if the contents have changed. Returns True if the file was written. """
|
||||||
if path_exists(name):
|
if path_exists(path):
|
||||||
old_contents = read_file(name)
|
old_contents = read_file(path)
|
||||||
|
assert not old_contents is None, path
|
||||||
else:
|
else:
|
||||||
old_contents = ''
|
old_contents = ''
|
||||||
|
|
||||||
if (data != old_contents):
|
if (data != old_contents):
|
||||||
write_file(name, data)
|
write_file(path, data, quiet=quiet)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def backup_file(name):
|
def backup_file(path):
|
||||||
""" Rename the file to a name that includes the current time stamp. """
|
""" Rename the file to a name that includes the current time stamp. """
|
||||||
move_file(name, name + '.' + time.strftime('%Y-%m-%d-%H-%M-%S'))
|
move_file(path, path + '.' + time.strftime('%Y-%m-%d-%H-%M-%S'))
|
||||||
|
|
||||||
|
|
||||||
def copy_file(src, dst, quiet=True):
|
def copy_file(src, dst, quiet=True):
|
||||||
""" Copy a file. """
|
""" Copy a file. """
|
||||||
|
if not os.path.isfile(src):
|
||||||
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
shutil.copy2(src, dst)
|
|
||||||
if not quiet:
|
if not quiet:
|
||||||
sys.stdout.write('Transferring ' + src + ' file.\n')
|
sys.stdout.write('Transferring ' + src + ' file.\n')
|
||||||
|
shutil.copy2(src, dst)
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
(errno, strerror) = e.args
|
(errno, strerror) = e.args
|
||||||
sys.stderr.write('Failed to copy file from ' + src + ' to ' + dst + ': ' +
|
sys.stderr.write('ERROR: Failed to copy file from ' + src + ' to ' + dst +
|
||||||
strerror)
|
': ' + strerror)
|
||||||
raise
|
raise
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def move_file(src, dst, quiet=True):
|
def move_file(src, dst, quiet=True):
|
||||||
""" Move a file. """
|
""" Move a file. """
|
||||||
|
if not os.path.isfile(src):
|
||||||
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
shutil.move(src, dst)
|
|
||||||
if not quiet:
|
if not quiet:
|
||||||
sys.stdout.write('Moving ' + src + ' file.\n')
|
print('Moving ' + src + ' file.')
|
||||||
|
shutil.move(src, dst)
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
(errno, strerror) = e.args
|
(errno, strerror) = e.args
|
||||||
sys.stderr.write('Failed to move file from ' + src + ' to ' + dst + ': ' +
|
sys.stderr.write('ERROR: Failed to move file from ' + src + ' to ' + dst +
|
||||||
strerror)
|
': ' + strerror)
|
||||||
raise
|
raise
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def copy_files(src_glob, dst_folder, quiet=True):
|
def copy_files(src_glob, dst_folder, quiet=True):
|
||||||
@ -102,56 +122,62 @@ def copy_files(src_glob, dst_folder, quiet=True):
|
|||||||
copy_file(fname, dst, quiet)
|
copy_file(fname, dst, quiet)
|
||||||
|
|
||||||
|
|
||||||
def remove_file(name, quiet=True):
|
def remove_file(path, quiet=True):
|
||||||
""" Remove the specified file. """
|
""" Remove the specified file. """
|
||||||
try:
|
try:
|
||||||
if path_exists(name):
|
if path_exists(path):
|
||||||
os.remove(name)
|
|
||||||
if not quiet:
|
if not quiet:
|
||||||
sys.stdout.write('Removing ' + name + ' file.\n')
|
print('Removing ' + path + ' file.')
|
||||||
|
os.remove(path)
|
||||||
|
return True
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
(errno, strerror) = e.args
|
(errno, strerror) = e.args
|
||||||
sys.stderr.write('Failed to remove file ' + name + ': ' + strerror)
|
sys.stderr.write('ERROR: Failed to remove file ' + path + ': ' + strerror)
|
||||||
raise
|
raise
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def copy_dir(src, dst, quiet=True):
|
def copy_dir(src, dst, quiet=True):
|
||||||
""" Copy a directory tree. """
|
""" Copy a directory tree. """
|
||||||
try:
|
try:
|
||||||
remove_dir(dst, quiet)
|
remove_dir(dst, quiet)
|
||||||
shutil.copytree(src, dst)
|
|
||||||
if not quiet:
|
if not quiet:
|
||||||
sys.stdout.write('Transferring ' + src + ' directory.\n')
|
print('Transferring ' + src + ' directory.')
|
||||||
|
shutil.copytree(src, dst)
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
(errno, strerror) = e.args
|
(errno, strerror) = e.args
|
||||||
sys.stderr.write('Failed to copy directory from ' + src + ' to ' + dst +
|
sys.stderr.write('ERROR: Failed to copy directory from ' + src + ' to ' +
|
||||||
': ' + strerror)
|
dst + ': ' + strerror)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
def remove_dir(name, quiet=True):
|
def remove_dir(path, quiet=True):
|
||||||
""" Remove the specified directory. """
|
""" Remove the specified directory. """
|
||||||
try:
|
try:
|
||||||
if path_exists(name):
|
if path_exists(path):
|
||||||
shutil.rmtree(name)
|
|
||||||
if not quiet:
|
if not quiet:
|
||||||
sys.stdout.write('Removing ' + name + ' directory.\n')
|
print('Removing ' + path + ' directory.')
|
||||||
|
shutil.rmtree(path)
|
||||||
|
return True
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
(errno, strerror) = e.args
|
(errno, strerror) = e.args
|
||||||
sys.stderr.write('Failed to remove directory ' + name + ': ' + strerror)
|
sys.stderr.write('ERROR: Failed to remove directory ' + path + ': ' +
|
||||||
|
strerror)
|
||||||
raise
|
raise
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def make_dir(name, quiet=True):
|
def make_dir(path, quiet=True):
|
||||||
""" Create the specified directory. """
|
""" Create the specified directory. """
|
||||||
try:
|
try:
|
||||||
if not path_exists(name):
|
if not path_exists(path):
|
||||||
if not quiet:
|
if not quiet:
|
||||||
sys.stdout.write('Creating ' + name + ' directory.\n')
|
print('Creating ' + path + ' directory.')
|
||||||
os.makedirs(name)
|
os.makedirs(path)
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
(errno, strerror) = e.args
|
(errno, strerror) = e.args
|
||||||
sys.stderr.write('Failed to create directory ' + name + ': ' + strerror)
|
sys.stderr.write('ERROR: Failed to create directory ' + path + ': ' +
|
||||||
|
strerror)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
@ -180,13 +206,17 @@ def get_files_recursive(directory, pattern):
|
|||||||
yield filename
|
yield filename
|
||||||
|
|
||||||
|
|
||||||
def read_version_file(file, args):
|
def read_version_file(path, args):
|
||||||
""" Read and parse a version file (key=value pairs, one per line). """
|
""" Read and parse a version file (key=value pairs, one per line). """
|
||||||
lines = read_file(file).split("\n")
|
contents = read_file(path)
|
||||||
|
if contents is None:
|
||||||
|
return False
|
||||||
|
lines = contents.split("\n")
|
||||||
for line in lines:
|
for line in lines:
|
||||||
parts = line.split('=', 1)
|
parts = line.split('=', 1)
|
||||||
if len(parts) == 2:
|
if len(parts) == 2:
|
||||||
args[parts[0]] = parts[1]
|
args[parts[0]] = parts[1]
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def eval_file(src):
|
def eval_file(src):
|
||||||
@ -199,3 +229,48 @@ def normalize_path(path):
|
|||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
return path.replace('\\', '/')
|
return path.replace('\\', '/')
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
def read_json_file(path):
|
||||||
|
""" Read and parse a JSON file. Returns a list/dictionary or None. """
|
||||||
|
if os.path.isfile(path):
|
||||||
|
try:
|
||||||
|
with codecs.open(path, 'r', encoding='utf-8') as fp:
|
||||||
|
return json.load(fp)
|
||||||
|
except IOError as e:
|
||||||
|
(errno, strerror) = e.args
|
||||||
|
sys.stderr.write('ERROR: Failed to read file ' + path + ': ' + strerror)
|
||||||
|
raise
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _bytes_encoder(z):
|
||||||
|
if isinstance(z, bytes):
|
||||||
|
return str(z, 'utf-8')
|
||||||
|
else:
|
||||||
|
type_name = z.__class__.__name__
|
||||||
|
raise TypeError(f"Object of type {type_name} is not serializable")
|
||||||
|
|
||||||
|
|
||||||
|
def write_json_file(path, data, overwrite=True, quiet=True):
|
||||||
|
""" Serialize and write a JSON file. Returns True on success. """
|
||||||
|
if not overwrite and os.path.exists(path):
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not quiet:
|
||||||
|
print('Writing file %s' % path)
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(path, 'w', encoding='utf-8') as fp:
|
||||||
|
json.dump(
|
||||||
|
data,
|
||||||
|
fp,
|
||||||
|
ensure_ascii=False,
|
||||||
|
indent=2,
|
||||||
|
sort_keys=True,
|
||||||
|
default=_bytes_encoder)
|
||||||
|
except IOError as e:
|
||||||
|
(errno, strerror) = e.args
|
||||||
|
sys.stderr.write('ERROR: Failed to write file ' + path + ': ' + strerror)
|
||||||
|
raise
|
||||||
|
return True
|
||||||
|
@ -28,8 +28,8 @@ else:
|
|||||||
print('Unknown operating system platform')
|
print('Unknown operating system platform')
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
print("\nGenerating CEF version header file...")
|
print("\nGenerating CEF translated files...")
|
||||||
cmd = [sys.executable, 'tools/make_version_header.py', 'include/cef_version.h']
|
cmd = [sys.executable, 'tools/version_manager.py', '-u', '--fast-check']
|
||||||
RunAction(cef_dir, cmd)
|
RunAction(cef_dir, cmd)
|
||||||
|
|
||||||
print("\nPatching build configuration and source files for CEF...")
|
print("\nPatching build configuration and source files for CEF...")
|
||||||
|
@ -26,85 +26,80 @@ def is_ancestor(path='.', commit1='HEAD', commit2='master'):
|
|||||||
return result['ret'] == 0
|
return result['ret'] == 0
|
||||||
|
|
||||||
|
|
||||||
def get_hash(path='.', branch='HEAD'):
|
def exec_git_cmd(args, path='.'):
|
||||||
""" Returns the git hash for the specified branch/tag/hash. """
|
""" Executes a git command with the specified |args|. """
|
||||||
cmd = "%s rev-parse %s" % (git_exe, branch)
|
cmd = "%s %s" % (git_exe, args)
|
||||||
result = exec_cmd(cmd, path)
|
result = exec_cmd(cmd, path)
|
||||||
if result['out'] != '':
|
if result['out'] != '':
|
||||||
return result['out'].strip()
|
out = result['out'].strip()
|
||||||
return 'Unknown'
|
if sys.platform == 'win32':
|
||||||
|
# Convert to Unix line endings.
|
||||||
|
out = out.replace('\r\n', '\n')
|
||||||
|
return out
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_hash(path='.', branch='HEAD'):
|
||||||
|
""" Returns the git hash for the specified branch/tag/hash. """
|
||||||
|
cmd = "rev-parse %s" % branch
|
||||||
|
result = exec_git_cmd(cmd, path)
|
||||||
|
return 'Unknown' if result is None else result
|
||||||
|
|
||||||
|
|
||||||
def get_branch_name(path='.', branch='HEAD'):
|
def get_branch_name(path='.', branch='HEAD'):
|
||||||
""" Returns the branch name for the specified branch/tag/hash. """
|
""" Returns the branch name for the specified branch/tag/hash. """
|
||||||
# Returns the branch name if not in detached HEAD state, else an empty string
|
# Returns the branch name if not in detached HEAD state, else an empty string
|
||||||
# or "HEAD".
|
# or "HEAD".
|
||||||
cmd = "%s rev-parse --abbrev-ref %s" % (git_exe, branch)
|
cmd = "rev-parse --abbrev-ref %s" % branch
|
||||||
result = exec_cmd(cmd, path)
|
result = exec_git_cmd(cmd, path)
|
||||||
if result['out'] != '':
|
if result is None:
|
||||||
name = result['out'].strip()
|
return 'Unknown'
|
||||||
if len(name) > 0 and name != 'HEAD':
|
if result != 'HEAD':
|
||||||
return name
|
return result
|
||||||
|
|
||||||
# Returns a value like "(HEAD, origin/3729, 3729)".
|
# Returns a value like "(HEAD, origin/3729, 3729)".
|
||||||
# Ubuntu 14.04 uses Git version 1.9.1 which does not support %D (which
|
# Ubuntu 14.04 uses Git version 1.9.1 which does not support %D (which
|
||||||
# provides the same output but without the parentheses).
|
# provides the same output but without the parentheses).
|
||||||
cmd = "%s log -n 1 --pretty=%%d %s" % (git_exe, branch)
|
cmd = "log -n 1 --pretty=%%d %s" % branch
|
||||||
result = exec_cmd(cmd, path)
|
result = exec_git_cmd(cmd, path)
|
||||||
if result['out'] != '':
|
return 'Unknown' if result is None else result[1:-1].split(', ')[-1]
|
||||||
return result['out'].strip()[1:-1].split(', ')[-1]
|
|
||||||
return 'Unknown'
|
|
||||||
|
|
||||||
|
|
||||||
def get_url(path='.'):
|
def get_url(path='.'):
|
||||||
""" Returns the origin url for the specified path. """
|
""" Returns the origin url for the specified path. """
|
||||||
cmd = "%s config --get remote.origin.url" % git_exe
|
cmd = "config --get remote.origin.url"
|
||||||
result = exec_cmd(cmd, path)
|
result = exec_git_cmd(cmd, path)
|
||||||
if result['out'] != '':
|
return 'Unknown' if result is None else result
|
||||||
return result['out'].strip()
|
|
||||||
return 'Unknown'
|
|
||||||
|
|
||||||
|
|
||||||
def get_commit_number(path='.', branch='HEAD'):
|
def get_commit_number(path='.', branch='HEAD'):
|
||||||
""" Returns the number of commits in the specified branch/tag/hash. """
|
""" Returns the number of commits in the specified branch/tag/hash. """
|
||||||
cmd = "%s rev-list --count %s" % (git_exe, branch)
|
cmd = "rev-list --count %s" % (branch)
|
||||||
result = exec_cmd(cmd, path)
|
result = exec_git_cmd(cmd, path)
|
||||||
if result['out'] != '':
|
return '0' if result is None else result
|
||||||
return result['out'].strip()
|
|
||||||
return '0'
|
|
||||||
|
|
||||||
|
|
||||||
def get_changed_files(path, hash):
|
def get_changed_files(path, hash):
|
||||||
""" Retrieves the list of changed files. """
|
""" Retrieves the list of changed files. """
|
||||||
if hash == 'unstaged':
|
if hash == 'unstaged':
|
||||||
cmd = "%s diff --name-only" % git_exe
|
cmd = "diff --name-only"
|
||||||
elif hash == 'staged':
|
elif hash == 'staged':
|
||||||
cmd = "%s diff --name-only --cached" % git_exe
|
cmd = "diff --name-only --cached"
|
||||||
else:
|
else:
|
||||||
cmd = "%s diff-tree --no-commit-id --name-only -r %s" % (git_exe, hash)
|
cmd = "diff-tree --no-commit-id --name-only -r %s" % hash
|
||||||
result = exec_cmd(cmd, path)
|
result = exec_git_cmd(cmd, path)
|
||||||
if result['out'] != '':
|
return [] if result is None else result.split("\n")
|
||||||
files = result['out']
|
|
||||||
if sys.platform == 'win32':
|
|
||||||
# Convert to Unix line endings.
|
|
||||||
files = files.replace('\r\n', '\n')
|
|
||||||
return files.strip().split("\n")
|
|
||||||
return []
|
|
||||||
|
|
||||||
|
|
||||||
def get_branch_hashes(path='.', branch='HEAD', ref='origin/master'):
|
def get_branch_hashes(path='.', branch='HEAD', ref='origin/master'):
|
||||||
""" Returns an ordered list of hashes for commits that have been applied since
|
""" Returns an ordered list of hashes for commits that have been applied since
|
||||||
branching from ref. """
|
branching from ref. """
|
||||||
cmd = "%s cherry %s %s" % (git_exe, ref, branch)
|
cmd = "cherry %s %s" % (ref, branch)
|
||||||
result = exec_cmd(cmd, path)
|
result = exec_git_cmd(cmd, path)
|
||||||
if result['out'] != '':
|
if result is None:
|
||||||
hashes = result['out']
|
|
||||||
if sys.platform == 'win32':
|
|
||||||
# Convert to Unix line endings.
|
|
||||||
hashes = hashes.replace('\r\n', '\n')
|
|
||||||
# Remove the "+ " or "- " prefix.
|
|
||||||
return [line[2:] for line in hashes.strip().split('\n')]
|
|
||||||
return []
|
return []
|
||||||
|
# Remove the "+ " or "- " prefix.
|
||||||
|
return [line[2:] for line in result.split('\n')]
|
||||||
|
|
||||||
|
|
||||||
def write_indented_output(output):
|
def write_indented_output(output):
|
||||||
|
@ -87,8 +87,11 @@ else:
|
|||||||
print('Unknown operating system platform')
|
print('Unknown operating system platform')
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
|
_QUIET = False
|
||||||
|
|
||||||
|
|
||||||
def msg(msg):
|
def msg(msg):
|
||||||
|
if not _QUIET:
|
||||||
print('NOTE: ' + msg)
|
print('NOTE: ' + msg)
|
||||||
|
|
||||||
|
|
||||||
@ -591,12 +594,16 @@ def LinuxSysrootExists(cpu):
|
|||||||
return os.path.isdir(os.path.join(sysroot_root, sysroot_name))
|
return os.path.isdir(os.path.join(sysroot_root, sysroot_name))
|
||||||
|
|
||||||
|
|
||||||
def GetAllPlatformConfigs(build_args):
|
def GetAllPlatformConfigs(build_args, quiet=False):
|
||||||
"""
|
"""
|
||||||
Return a map of directory name to GN args for the current platform.
|
Return a map of directory name to GN args for the current platform.
|
||||||
"""
|
"""
|
||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
|
if quiet:
|
||||||
|
global _QUIET
|
||||||
|
_QUIET = True
|
||||||
|
|
||||||
# Merged args without validation.
|
# Merged args without validation.
|
||||||
args = GetMergedArgs(build_args)
|
args = GetMergedArgs(build_args)
|
||||||
|
|
||||||
|
@ -1,95 +0,0 @@
|
|||||||
# Copyright (c) 2019 The Chromium Embedded Framework Authors. All rights
|
|
||||||
# reserved. Use of this source code is governed by a BSD-style license that
|
|
||||||
# can be found in the LICENSE file.
|
|
||||||
|
|
||||||
from __future__ import absolute_import
|
|
||||||
from cef_api_hash import cef_api_hash
|
|
||||||
from cef_parser import get_copyright
|
|
||||||
from file_util import *
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
def make_api_hash_header(cpp_header_dir):
|
|
||||||
# calculate api hashes
|
|
||||||
api_hash_calculator = cef_api_hash(cpp_header_dir, verbose=False)
|
|
||||||
api_hash = api_hash_calculator.calculate()
|
|
||||||
|
|
||||||
result = get_copyright(full=True, translator=False) + \
|
|
||||||
"""//
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// This file was generated by the make_api_hash_header.py tool.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef CEF_INCLUDE_API_HASH_H_
|
|
||||||
#define CEF_INCLUDE_API_HASH_H_
|
|
||||||
|
|
||||||
#include "include/internal/cef_export.h"
|
|
||||||
|
|
||||||
// The API hash is created by analyzing CEF header files for C API type
|
|
||||||
// definitions. The hash value will change when header files are modified in a
|
|
||||||
// way that may cause binary incompatibility with other builds. The universal
|
|
||||||
// hash value will change if any platform is affected whereas the platform hash
|
|
||||||
// values will change only if that particular platform is affected.
|
|
||||||
#define CEF_API_HASH_UNIVERSAL "$UNIVERSAL$"
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
#define CEF_API_HASH_PLATFORM "$WINDOWS$"
|
|
||||||
#elif defined(OS_MAC)
|
|
||||||
#define CEF_API_HASH_PLATFORM "$MAC$"
|
|
||||||
#elif defined(OS_LINUX)
|
|
||||||
#define CEF_API_HASH_PLATFORM "$LINUX$"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
///
|
|
||||||
// Returns CEF API hashes for the libcef library. The returned string is owned
|
|
||||||
// by the library and should not be freed. The |entry| parameter describes which
|
|
||||||
// hash value will be returned:
|
|
||||||
// 0 - CEF_API_HASH_PLATFORM
|
|
||||||
// 1 - CEF_API_HASH_UNIVERSAL
|
|
||||||
// 2 - CEF_COMMIT_HASH (from cef_version.h)
|
|
||||||
///
|
|
||||||
CEF_EXPORT const char* cef_api_hash(int entry);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif // CEF_INCLUDE_API_HASH_H_
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Substitute hash values for placeholders.
|
|
||||||
for platform, value in api_hash.items():
|
|
||||||
result = result.replace('$%s$' % platform.upper(), value)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def write_api_hash_header(output, cpp_header_dir):
|
|
||||||
output = os.path.abspath(output)
|
|
||||||
result = make_api_hash_header(cpp_header_dir)
|
|
||||||
ret = write_file_if_changed(output, result)
|
|
||||||
|
|
||||||
# Also write to |cpp_header_dir| if a different path from |output|, since we
|
|
||||||
# need to commit the hash header for cef_version.py to correctly calculate the
|
|
||||||
# version number based on git history.
|
|
||||||
header_path = os.path.abspath(
|
|
||||||
os.path.join(cpp_header_dir, os.path.basename(output)))
|
|
||||||
if (output != header_path):
|
|
||||||
write_file_if_changed(header_path, result)
|
|
||||||
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
def main(argv):
|
|
||||||
if len(argv) < 3:
|
|
||||||
print(("Usage:\n %s <output_filename> <cpp_header_dir>" % argv[0]))
|
|
||||||
sys.exit(-1)
|
|
||||||
write_api_hash_header(argv[1], argv[2])
|
|
||||||
|
|
||||||
|
|
||||||
if '__main__' == __name__:
|
|
||||||
main(sys.argv)
|
|
130
tools/make_api_versions_header.py
Normal file
130
tools/make_api_versions_header.py
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
# Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
|
||||||
|
# reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
# can be found in the LICENSE file.
|
||||||
|
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from cef_parser import get_copyright
|
||||||
|
from file_util import write_file_if_changed
|
||||||
|
from version_util import read_version_files
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def make_api_versions_header(json):
|
||||||
|
result = get_copyright(full=True, translator=False) + \
|
||||||
|
"""//
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This file was generated by the make_api_versions_header.py tool. Versions
|
||||||
|
// are managed using the version_manager.py tool. For usage details see
|
||||||
|
// https://bitbucket.org/chromiumembedded/cef/wiki/ApiVersioning.md
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef CEF_INCLUDE_CEF_API_VERSIONS_H_
|
||||||
|
#define CEF_INCLUDE_CEF_API_VERSIONS_H_
|
||||||
|
|
||||||
|
#include "include/base/cef_build.h"
|
||||||
|
"""
|
||||||
|
|
||||||
|
for version, hashes in json['hashes'].items():
|
||||||
|
version_part = """
|
||||||
|
// $COMMENT$
|
||||||
|
#define CEF_API_VERSION_$VER$ $VER$
|
||||||
|
#define CEF_API_HASH_$VER$_UNIVERSAL "$UNIVERSAL$"
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
#define CEF_API_HASH_$VER$_PLATFORM "$WINDOWS$"
|
||||||
|
#elif defined(OS_MAC)
|
||||||
|
#define CEF_API_HASH_$VER$_PLATFORM "$MAC$"
|
||||||
|
#elif defined(OS_LINUX)
|
||||||
|
#define CEF_API_HASH_$VER$_PLATFORM "$LINUX$"
|
||||||
|
#endif
|
||||||
|
""".replace('$VER$', version)
|
||||||
|
|
||||||
|
# Substitute hash values for placeholders.
|
||||||
|
for key, value in hashes.items():
|
||||||
|
version_part = version_part.replace('$%s$' % key.upper(), value)
|
||||||
|
|
||||||
|
result += version_part
|
||||||
|
|
||||||
|
result += \
|
||||||
|
"""
|
||||||
|
// Oldest supported CEF version.
|
||||||
|
#define CEF_API_VERSION_MIN CEF_API_VERSION_$MIN$
|
||||||
|
|
||||||
|
// Newest supported CEF version.
|
||||||
|
#define CEF_API_VERSION_LAST CEF_API_VERSION_$LAST$
|
||||||
|
|
||||||
|
#endif // CEF_INCLUDE_CEF_API_VERSIONS_H_
|
||||||
|
""".replace('$LAST$', json['last']).replace('$MIN$', json['min'])
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def make_api_versions_inc(json):
|
||||||
|
result = get_copyright(full=False, translator=False) + \
|
||||||
|
"""//
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This file was generated by the make_api_versions_header.py tool.
|
||||||
|
//
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct ApiVersionHash {
|
||||||
|
int version;
|
||||||
|
const char* const universal;
|
||||||
|
const char* const platform;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ApiVersionHash kApiVersionHashes[] = {"""
|
||||||
|
|
||||||
|
for version, hashes in json['hashes'].items():
|
||||||
|
result += """
|
||||||
|
{$VER$, CEF_API_HASH_$VER$_UNIVERSAL, CEF_API_HASH_$VER$_PLATFORM},""".replace(
|
||||||
|
'$VER$', version)
|
||||||
|
|
||||||
|
result += \
|
||||||
|
"""
|
||||||
|
};
|
||||||
|
|
||||||
|
const size_t kApiVersionHashesSize = std::size(kApiVersionHashes);
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
"""
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def write_api_versions(out_header_file, out_inc_file, json):
|
||||||
|
out_file = os.path.abspath(out_header_file)
|
||||||
|
result = make_api_versions_header(json)
|
||||||
|
if not bool(result):
|
||||||
|
sys.stderr.write('Failed to create %s\n' % out_file)
|
||||||
|
sys.exit(1)
|
||||||
|
retval1 = write_file_if_changed(out_file, result)
|
||||||
|
|
||||||
|
out_file = os.path.abspath(out_inc_file)
|
||||||
|
result = make_api_versions_inc(json)
|
||||||
|
if not bool(result):
|
||||||
|
sys.stderr.write('Failed to create %s\n' % out_file)
|
||||||
|
sys.exit(1)
|
||||||
|
retval2 = write_file_if_changed(out_file, result)
|
||||||
|
|
||||||
|
return retval1 or retval2
|
||||||
|
|
||||||
|
|
||||||
|
def main(argv):
|
||||||
|
if len(argv) < 5:
|
||||||
|
print(
|
||||||
|
"Usage:\n %s <output_header_file> <output_inc_file> <api_versions_file> <api_untracked_file>"
|
||||||
|
% argv[0])
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
json, initialized = \
|
||||||
|
read_version_files(argv[3], argv[4], True, combine=True)
|
||||||
|
if not write_api_versions(argv[1], argv[2], json):
|
||||||
|
print('Nothing done')
|
||||||
|
|
||||||
|
|
||||||
|
if '__main__' == __name__:
|
||||||
|
main(sys.argv)
|
@ -8,33 +8,41 @@ from cef_parser import *
|
|||||||
|
|
||||||
def make_capi_global_funcs(funcs, defined_names, translate_map, indent):
|
def make_capi_global_funcs(funcs, defined_names, translate_map, indent):
|
||||||
result = ''
|
result = ''
|
||||||
first = True
|
|
||||||
for func in funcs:
|
for func in funcs:
|
||||||
comment = func.get_comment()
|
comment = func.get_comment()
|
||||||
if first or len(comment) > 0:
|
pre, post = get_version_surround(func)
|
||||||
result += '\n' + format_comment(comment, indent, translate_map)
|
result += '\n' + pre
|
||||||
|
if len(comment) > 0:
|
||||||
|
result += format_comment(comment, indent, translate_map)
|
||||||
if func.get_retval().get_type().is_result_string():
|
if func.get_retval().get_type().is_result_string():
|
||||||
result += indent + '// The resulting string must be freed by calling cef_string_userfree_free().\n'
|
result += indent + '// The resulting string must be freed by calling cef_string_userfree_free().\n'
|
||||||
result += indent + 'CEF_EXPORT ' + func.get_capi_proto(defined_names) + ';\n'
|
result += indent + 'CEF_EXPORT ' + func.get_capi_proto(
|
||||||
if first:
|
defined_names) + ';\n' + post
|
||||||
first = False
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def make_capi_member_funcs(funcs, defined_names, translate_map, indent):
|
def make_capi_member_funcs(funcs, defined_names, translate_map, indent):
|
||||||
result = ''
|
result = ''
|
||||||
first = True
|
|
||||||
for func in funcs:
|
for func in funcs:
|
||||||
comment = func.get_comment()
|
comment = func.get_comment()
|
||||||
if first or len(comment) > 0:
|
pre, post = get_version_surround(func)
|
||||||
result += '\n' + format_comment(comment, indent, translate_map)
|
result += '\n' + pre
|
||||||
|
if len(comment) > 0:
|
||||||
|
result += format_comment(comment, indent, translate_map)
|
||||||
if func.get_retval().get_type().is_result_string():
|
if func.get_retval().get_type().is_result_string():
|
||||||
result += indent + '// The resulting string must be freed by calling cef_string_userfree_free().\n'
|
result += indent + '// The resulting string must be freed by calling cef_string_userfree_free().\n'
|
||||||
parts = func.get_capi_parts()
|
parts = func.get_capi_parts()
|
||||||
result += indent+parts['retval']+' (CEF_CALLBACK *'+parts['name']+ \
|
result += indent + parts['retval'] + ' (CEF_CALLBACK *' + parts['name'] + \
|
||||||
')('+', '.join(parts['args'])+');\n'
|
')(' + ', '.join(parts['args']) + ');\n'
|
||||||
if first:
|
if len(post) > 0 and func.has_version_removed():
|
||||||
first = False
|
if func.has_version_added():
|
||||||
|
result += '#elif ' + get_version_check({
|
||||||
|
'added': func.get_attrib('removed')
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
result += '#else'
|
||||||
|
result += '\n' + indent + 'uintptr_t ' + parts['name'] + '_removed;\n'
|
||||||
|
result += post
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
@ -61,13 +69,16 @@ def make_capi_header(header, filename):
|
|||||||
#define $GUARD$
|
#define $GUARD$
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(BUILDING_CEF_SHARED)
|
||||||
|
#error This file cannot be included DLL-side
|
||||||
|
#endif
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Protect against incorrect use of test headers.
|
# Protect against incorrect use of test headers.
|
||||||
if filename.startswith('test/'):
|
if filename.startswith('test/'):
|
||||||
result += \
|
result += \
|
||||||
"""#if !defined(BUILDING_CEF_SHARED) && !defined(WRAPPING_CEF_SHARED) && \\
|
"""#if !defined(WRAPPING_CEF_SHARED) && !defined(UNIT_TEST)
|
||||||
!defined(UNIT_TEST)
|
|
||||||
#error This file can be included for unit tests only
|
#error This file can be included for unit tests only
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -78,7 +89,7 @@ def make_capi_header(header, filename):
|
|||||||
# identify all includes and forward declarations
|
# identify all includes and forward declarations
|
||||||
translated_includes = set([])
|
translated_includes = set([])
|
||||||
internal_includes = set([])
|
internal_includes = set([])
|
||||||
all_declares = set([])
|
all_declares = {}
|
||||||
for cls in classes:
|
for cls in classes:
|
||||||
includes = cls.get_includes()
|
includes = cls.get_includes()
|
||||||
for include in includes:
|
for include in includes:
|
||||||
@ -87,7 +98,7 @@ def make_capi_header(header, filename):
|
|||||||
# translated CEF API headers.
|
# translated CEF API headers.
|
||||||
raise Exception('Disallowed include of %s.h from %s' % (include,
|
raise Exception('Disallowed include of %s.h from %s' % (include,
|
||||||
filename))
|
filename))
|
||||||
elif include.startswith('internal/'):
|
elif include.startswith('internal/') or include == 'cef_api_hash':
|
||||||
# internal/ headers may be C or C++. Include them as-is.
|
# internal/ headers may be C or C++. Include them as-is.
|
||||||
internal_includes.add(include)
|
internal_includes.add(include)
|
||||||
else:
|
else:
|
||||||
@ -97,7 +108,10 @@ def make_capi_header(header, filename):
|
|||||||
declare_cls = header.get_class(declare)
|
declare_cls = header.get_class(declare)
|
||||||
if declare_cls is None:
|
if declare_cls is None:
|
||||||
raise Exception('Unknown class: %s' % declare)
|
raise Exception('Unknown class: %s' % declare)
|
||||||
all_declares.add(declare_cls.get_capi_name())
|
capi_name = declare_cls.get_capi_name()
|
||||||
|
if not capi_name in all_declares:
|
||||||
|
all_declares[capi_name] = declare_cls.get_version_check() \
|
||||||
|
if declare_cls.has_version() else None
|
||||||
|
|
||||||
# output translated includes
|
# output translated includes
|
||||||
if len(translated_includes) > 0:
|
if len(translated_includes) > 0:
|
||||||
@ -122,22 +136,39 @@ extern "C" {
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# output forward declarations
|
# output forward declarations
|
||||||
if len(all_declares) > 0:
|
if bool(all_declares):
|
||||||
sorted_declares = sorted(all_declares)
|
sorted_declares = sorted(all_declares.keys())
|
||||||
for declare in sorted_declares:
|
for declare in sorted_declares:
|
||||||
|
cls_version_check = all_declares[declare]
|
||||||
|
if not cls_version_check is None:
|
||||||
|
result += '#if ' + cls_version_check + '\n'
|
||||||
result += 'struct _' + declare + ';\n'
|
result += 'struct _' + declare + ';\n'
|
||||||
|
if not cls_version_check is None:
|
||||||
|
result += '#endif\n'
|
||||||
|
|
||||||
# output classes
|
# output classes
|
||||||
for cls in classes:
|
for cls in classes:
|
||||||
|
pre, post = get_version_surround(cls, long=True)
|
||||||
|
if len(pre) > 0:
|
||||||
|
result += '\n' + pre
|
||||||
|
|
||||||
|
comment = cls.get_comment()
|
||||||
|
add_comment = []
|
||||||
|
if comment[-1] != '':
|
||||||
|
add_comment.append('')
|
||||||
|
add_comment.append('NOTE: This struct is allocated %s-side.' % \
|
||||||
|
('client' if cls.is_client_side() else 'DLL'))
|
||||||
|
add_comment.append('')
|
||||||
|
|
||||||
# virtual functions are inside the structure
|
# virtual functions are inside the structure
|
||||||
classname = cls.get_capi_name()
|
classname = cls.get_capi_name()
|
||||||
result += '\n' + format_comment(cls.get_comment(), '', translate_map)
|
result += '\n' + format_comment(comment + add_comment, '', translate_map)
|
||||||
result += 'typedef struct _'+classname+' {\n'+\
|
result += 'typedef struct _'+classname+' {\n'+\
|
||||||
' ///\n'+\
|
' ///\n'+\
|
||||||
' /// Base structure.\n'+\
|
' /// Base structure.\n'+\
|
||||||
' ///\n'+\
|
' ///\n'+\
|
||||||
' '+cls.get_parent_capi_name()+' base;\n'
|
' '+cls.get_parent_capi_name()+' base;\n'
|
||||||
funcs = cls.get_virtual_funcs()
|
funcs = cls.get_virtual_funcs(version_order=True)
|
||||||
result += make_capi_member_funcs(funcs, defined_names, translate_map, ' ')
|
result += make_capi_member_funcs(funcs, defined_names, translate_map, ' ')
|
||||||
result += '} ' + classname + ';\n\n'
|
result += '} ' + classname + ';\n\n'
|
||||||
|
|
||||||
@ -149,6 +180,8 @@ extern "C" {
|
|||||||
result += make_capi_global_funcs(funcs, defined_names, translate_map,
|
result += make_capi_global_funcs(funcs, defined_names, translate_map,
|
||||||
'') + '\n'
|
'') + '\n'
|
||||||
|
|
||||||
|
result += post
|
||||||
|
|
||||||
# output global functions
|
# output global functions
|
||||||
funcs = header.get_funcs(filename)
|
funcs = header.get_funcs(filename)
|
||||||
if len(funcs) > 0:
|
if len(funcs) > 0:
|
||||||
|
189
tools/make_capi_versions_header.py
Normal file
189
tools/make_capi_versions_header.py
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
# Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
|
||||||
|
# reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
# can be found in the LICENSE file.
|
||||||
|
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from cef_parser import *
|
||||||
|
import functools
|
||||||
|
|
||||||
|
|
||||||
|
def _version_finder(header, name):
|
||||||
|
cls = header.get_capi_class(name)
|
||||||
|
if not cls is None:
|
||||||
|
return cls.get_capi_name(first_version=True)
|
||||||
|
return name
|
||||||
|
|
||||||
|
|
||||||
|
def make_capi_global_funcs(version, version_finder, funcs, defined_names):
|
||||||
|
result = ''
|
||||||
|
for func in funcs:
|
||||||
|
result += 'CEF_EXPORT ' + func.get_capi_proto(
|
||||||
|
defined_names, version=version, version_finder=version_finder) + ';\n'
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def make_capi_member_funcs(version, version_finder, funcs, defined_names,
|
||||||
|
translate_map, indent):
|
||||||
|
result = ''
|
||||||
|
for func in funcs:
|
||||||
|
parts = func.get_capi_parts(version=version, version_finder=version_finder)
|
||||||
|
if func.removed_at_version(version):
|
||||||
|
result += indent + 'uintptr_t ' + parts['name'] + '_removed;\n'
|
||||||
|
else:
|
||||||
|
result += indent + parts['retval'] + ' (CEF_CALLBACK *' + parts['name'] + \
|
||||||
|
')(' + ', '.join(parts['args']) + ');\n'
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def make_capi_versions_header(header, filename):
|
||||||
|
# structure names that have already been defined
|
||||||
|
defined_names = header.get_defined_structs()
|
||||||
|
|
||||||
|
# map of strings that will be changed in C++ comments
|
||||||
|
translate_map = header.get_capi_translations()
|
||||||
|
|
||||||
|
# header string
|
||||||
|
result = get_copyright(full=True, translator=False) + \
|
||||||
|
"""//
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This file was generated by the CEF translator tool and should not edited
|
||||||
|
// by hand. See the translator.README.txt file in the tools directory for
|
||||||
|
// more information.
|
||||||
|
//
|
||||||
|
// $hash=$$HASH$$$
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef $GUARD$
|
||||||
|
#define $GUARD$
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(BUILDING_CEF_SHARED)
|
||||||
|
#error This file can be included DLL-side only
|
||||||
|
#endif
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
classes = header.get_classes(filename)
|
||||||
|
|
||||||
|
# identify all includes and forward declarations
|
||||||
|
translated_includes = set()
|
||||||
|
internal_includes = set()
|
||||||
|
all_declares = set()
|
||||||
|
for cls in classes:
|
||||||
|
includes = cls.get_includes()
|
||||||
|
for include in includes:
|
||||||
|
if include.startswith('base/'):
|
||||||
|
# base/ headers are C++. They should not be included by
|
||||||
|
# translated CEF API headers.
|
||||||
|
raise Exception('Disallowed include of %s.h from %s' % (include,
|
||||||
|
filename))
|
||||||
|
elif include.startswith('internal/') or include == 'cef_api_hash':
|
||||||
|
# internal/ headers may be C or C++. Include them as-is.
|
||||||
|
internal_includes.add(include)
|
||||||
|
else:
|
||||||
|
translated_includes.add(include)
|
||||||
|
declares = cls.get_forward_declares()
|
||||||
|
for declare in declares:
|
||||||
|
declare_cls = header.get_class(declare)
|
||||||
|
if declare_cls is None:
|
||||||
|
raise Exception('Unknown class: %s' % declare)
|
||||||
|
for version in declare_cls.get_all_versions():
|
||||||
|
all_declares.add(declare_cls.get_capi_name(version=version))
|
||||||
|
|
||||||
|
# output translated includes
|
||||||
|
if len(translated_includes) > 0:
|
||||||
|
sorted_includes = sorted(translated_includes)
|
||||||
|
for include in sorted_includes:
|
||||||
|
suffix = '_versions' if not include in ('cef_base',) else ''
|
||||||
|
result += '#include "include/capi/' + include + '_capi' + suffix + '.h"\n'
|
||||||
|
else:
|
||||||
|
result += '#include "include/capi/cef_base_capi.h"\n'
|
||||||
|
|
||||||
|
# output internal includes
|
||||||
|
if len(internal_includes) > 0:
|
||||||
|
sorted_includes = sorted(internal_includes)
|
||||||
|
for include in sorted_includes:
|
||||||
|
result += '#include "include/' + include + '.h"\n'
|
||||||
|
|
||||||
|
result += \
|
||||||
|
"""
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# output forward declarations
|
||||||
|
if bool(all_declares):
|
||||||
|
for declare in sorted(all_declares):
|
||||||
|
result += 'struct _' + declare + ';\n'
|
||||||
|
result += '\n'
|
||||||
|
|
||||||
|
version_finder = functools.partial(_version_finder, header)
|
||||||
|
|
||||||
|
# output classes
|
||||||
|
for cls in classes:
|
||||||
|
for version in cls.get_all_versions():
|
||||||
|
# virtual functions are inside the structure
|
||||||
|
classname = cls.get_capi_name(version=version)
|
||||||
|
result += 'typedef struct _'+classname+' {\n'+\
|
||||||
|
' '+cls.get_parent_capi_name(version=version)+' base;\n'
|
||||||
|
funcs = cls.get_virtual_funcs(version_order=True, version=version)
|
||||||
|
result += make_capi_member_funcs(version, version_finder, funcs,
|
||||||
|
defined_names, translate_map, ' ')
|
||||||
|
result += '} ' + classname + ';\n\n'
|
||||||
|
|
||||||
|
defined_names.append(classname)
|
||||||
|
|
||||||
|
# static functions become global
|
||||||
|
funcs = cls.get_static_funcs()
|
||||||
|
if len(funcs) > 0:
|
||||||
|
result += make_capi_global_funcs(version, version_finder, funcs,
|
||||||
|
defined_names) + '\n'
|
||||||
|
|
||||||
|
# output global functions
|
||||||
|
funcs = header.get_funcs(filename)
|
||||||
|
if len(funcs) > 0:
|
||||||
|
result += make_capi_global_funcs(None, version_finder, funcs,
|
||||||
|
defined_names) + '\n'
|
||||||
|
|
||||||
|
# footer string
|
||||||
|
result += \
|
||||||
|
"""#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // $GUARD$
|
||||||
|
"""
|
||||||
|
|
||||||
|
# add the guard string
|
||||||
|
guard = 'CEF_INCLUDE_CAPI_' + \
|
||||||
|
filename.replace('/', '_').replace('.', '_capi_versions_').upper() + '_'
|
||||||
|
result = result.replace('$GUARD$', guard)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def write_capi_versions_header(header, header_dir, filename):
|
||||||
|
file = get_capi_file_name(os.path.join(header_dir, filename), versions=True)
|
||||||
|
newcontents = make_capi_versions_header(header, filename)
|
||||||
|
return (file, newcontents)
|
||||||
|
|
||||||
|
|
||||||
|
# test the module
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# verify that the correct number of command-line arguments are provided
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
sys.stderr.write('Usage: ' + sys.argv[0] + ' <infile>\n')
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
# create the header object
|
||||||
|
header = obj_header()
|
||||||
|
header.add_file(sys.argv[1])
|
||||||
|
|
||||||
|
# dump the result to stdout
|
||||||
|
filename = os.path.split(sys.argv[1])[1]
|
||||||
|
sys.stdout.write(make_capi_versions_header(header, filename))
|
@ -20,8 +20,6 @@ def make_cpptoc_header(header, clsname):
|
|||||||
defname += get_capi_name(clsname[3:], False)
|
defname += get_capi_name(clsname[3:], False)
|
||||||
defname = defname.upper()
|
defname = defname.upper()
|
||||||
|
|
||||||
capiname = cls.get_capi_name()
|
|
||||||
|
|
||||||
result = get_copyright()
|
result = get_copyright()
|
||||||
|
|
||||||
result += '#ifndef CEF_LIBCEF_DLL_CPPTOC_'+defname+'_CPPTOC_H_\n'+ \
|
result += '#ifndef CEF_LIBCEF_DLL_CPPTOC_'+defname+'_CPPTOC_H_\n'+ \
|
||||||
@ -41,9 +39,11 @@ def make_cpptoc_header(header, clsname):
|
|||||||
#endif
|
#endif
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
with_versions = dllside
|
||||||
|
|
||||||
# include the headers for this class
|
# include the headers for this class
|
||||||
result += '\n#include "include/'+cls.get_file_name()+'"\n' \
|
result += '\n#include "include/'+cls.get_file_name()+'"\n' \
|
||||||
'#include "include/capi/'+cls.get_capi_file_name()+'"\n'
|
'#include "include/capi/'+cls.get_capi_file_name(versions=with_versions)+'"\n'
|
||||||
|
|
||||||
# include headers for any forward declared classes that are not in the same file
|
# include headers for any forward declared classes that are not in the same file
|
||||||
declares = cls.get_forward_declares()
|
declares = cls.get_forward_declares()
|
||||||
@ -51,7 +51,7 @@ def make_cpptoc_header(header, clsname):
|
|||||||
dcls = header.get_class(declare)
|
dcls = header.get_class(declare)
|
||||||
if dcls.get_file_name() != cls.get_file_name():
|
if dcls.get_file_name() != cls.get_file_name():
|
||||||
result += '#include "include/'+dcls.get_file_name()+'"\n' \
|
result += '#include "include/'+dcls.get_file_name()+'"\n' \
|
||||||
'#include "include/capi/'+dcls.get_capi_file_name()+'"\n'
|
'#include "include/capi/'+dcls.get_capi_file_name(versions=with_versions)+'"\n'
|
||||||
|
|
||||||
base_class_name = header.get_base_class_name(clsname)
|
base_class_name = header.get_base_class_name(clsname)
|
||||||
base_scoped = True if base_class_name == 'CefBaseScoped' else False
|
base_scoped = True if base_class_name == 'CefBaseScoped' else False
|
||||||
@ -63,20 +63,79 @@ def make_cpptoc_header(header, clsname):
|
|||||||
template_class = 'CefCppToCRefCounted'
|
template_class = 'CefCppToCRefCounted'
|
||||||
|
|
||||||
result += '#include "libcef_dll/cpptoc/' + template_file + '"'
|
result += '#include "libcef_dll/cpptoc/' + template_file + '"'
|
||||||
result += '\n\n// Wrap a C++ class with a C structure.\n'
|
|
||||||
|
|
||||||
|
if with_versions:
|
||||||
|
pre = post = ''
|
||||||
|
else:
|
||||||
|
pre, post = get_version_surround(cls, long=True)
|
||||||
|
if len(pre) > 0:
|
||||||
|
result += '\n\n' + pre.strip()
|
||||||
|
|
||||||
|
result += '\n\n'
|
||||||
|
|
||||||
|
versions = cls.get_all_versions() if with_versions else (None,)
|
||||||
|
|
||||||
|
for version in versions:
|
||||||
|
result += '// Wrap a C++ class with a C structure%s.\n' % \
|
||||||
|
('' if version is None else ' at API version %d' % version)
|
||||||
if dllside:
|
if dllside:
|
||||||
result += '// This class may be instantiated and accessed DLL-side only.\n'
|
result += '// This class may be instantiated and accessed DLL-side only.\n'
|
||||||
else:
|
else:
|
||||||
result += '// This class may be instantiated and accessed wrapper-side only.\n'
|
result += '// This class may be instantiated and accessed wrapper-side only.\n'
|
||||||
|
|
||||||
result += 'class '+clsname+'CppToC\n'+ \
|
capiname = cls.get_capi_name(version=version)
|
||||||
' : public ' + template_class + '<'+clsname+'CppToC, '+clsname+', '+capiname+'> {\n'+ \
|
if version is None:
|
||||||
|
typename = clsname + 'CppToC'
|
||||||
|
else:
|
||||||
|
typename = clsname + '_%d_CppToC' % version
|
||||||
|
|
||||||
|
result += 'class '+typename+'\n'+ \
|
||||||
|
' : public ' + template_class + '<'+typename+', '+clsname+', '+capiname+'> {\n'+ \
|
||||||
' public:\n'+ \
|
' public:\n'+ \
|
||||||
' '+clsname+'CppToC();\n'+ \
|
' '+typename+'();\n'+ \
|
||||||
' virtual ~'+clsname+'CppToC();\n'+ \
|
' virtual ~'+typename+'();\n'+ \
|
||||||
'};\n\n'
|
'};\n\n'
|
||||||
|
|
||||||
|
typename = clsname + 'CppToC'
|
||||||
|
if len(versions) > 1:
|
||||||
|
result += '// Helpers to return objects at the globally configured API version.\n'
|
||||||
|
structname = cls.get_capi_name(version=versions[0])
|
||||||
|
if base_scoped:
|
||||||
|
result += structname + '* ' + typename + '_WrapOwn(CefOwnPtr<' + clsname + '> c);\n' + \
|
||||||
|
'std::pair<CefOwnPtr<CefBaseScoped>, '+ structname + '*> ' + typename + '_WrapRaw(CefRawPtr<' + clsname + '> c);\n' + \
|
||||||
|
'CefOwnPtr<' + clsname + '> ' + typename + '_UnwrapOwn('+ structname + '* s);\n' + \
|
||||||
|
'CefRawPtr<' + clsname + '> ' + typename + '_UnwrapRaw('+ structname + '* s);\n' + \
|
||||||
|
'CefBaseScoped* ' + typename + '_GetWrapper('+ structname + '* s);\n\n'
|
||||||
|
else:
|
||||||
|
result += structname + '* ' + typename + '_Wrap(CefRefPtr<' + clsname + '> c);\n' + \
|
||||||
|
'CefRefPtr<' + clsname + '> ' + typename + '_Unwrap('+ structname + '* s);\n\n'
|
||||||
|
else:
|
||||||
|
if versions[0] is None:
|
||||||
|
targetname = clsname + 'CppToC'
|
||||||
|
structname = cls.get_capi_name()
|
||||||
|
else:
|
||||||
|
targetname = clsname + '_%d_CppToC' % versions[0]
|
||||||
|
structname = cls.get_capi_name(version=versions[0])
|
||||||
|
if base_scoped:
|
||||||
|
result += 'constexpr auto ' + typename + '_WrapOwn = ' + targetname + '::WrapOwn;\n' + \
|
||||||
|
'constexpr auto ' + typename + '_WrapRaw = ' + targetname + '::WrapRaw;\n' + \
|
||||||
|
'constexpr auto ' + typename + '_UnwrapOwn = ' + targetname + '::UnwrapOwn;\n' + \
|
||||||
|
'constexpr auto ' + typename + '_UnwrapRaw = ' + targetname + '::UnwrapRaw;\n' + \
|
||||||
|
'constexpr auto ' + typename + '_GetWrapper = ' + targetname + '::GetWrapper;\n\n'
|
||||||
|
else:
|
||||||
|
result += 'constexpr auto ' + typename + '_Wrap = ' + targetname + '::Wrap;\n' + \
|
||||||
|
'constexpr auto ' + typename + '_Unwrap = ' + targetname + '::Unwrap;\n\n'
|
||||||
|
|
||||||
|
if base_scoped:
|
||||||
|
result += 'inline ' + structname + '* ' + typename + '_WrapRawAndRelease(CefRawPtr<' + clsname + '> c) {\n' + \
|
||||||
|
' auto [ownerPtr, structPtr] = ' + typename + '_WrapRaw(c);\n' + \
|
||||||
|
' ownerPtr.release();\n' + \
|
||||||
|
' return structPtr;\n' + \
|
||||||
|
'}\n\n'
|
||||||
|
|
||||||
|
if len(post) > 0:
|
||||||
|
result += post + '\n'
|
||||||
|
|
||||||
result += '#endif // CEF_LIBCEF_DLL_CPPTOC_' + defname + '_CPPTOC_H_'
|
result += '#endif // CEF_LIBCEF_DLL_CPPTOC_' + defname + '_CPPTOC_H_'
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from cef_parser import *
|
from cef_parser import *
|
||||||
|
import copy
|
||||||
|
import functools
|
||||||
|
|
||||||
|
|
||||||
def make_cpptoc_impl_proto(name, func, parts):
|
def make_cpptoc_impl_proto(name, func, parts):
|
||||||
@ -16,27 +18,37 @@ def make_cpptoc_impl_proto(name, func, parts):
|
|||||||
return proto
|
return proto
|
||||||
|
|
||||||
|
|
||||||
def make_cpptoc_function_impl_existing(cls, name, func, impl, defined_names):
|
def make_cpptoc_function_impl_existing(cls, name, func, impl, defined_names,
|
||||||
|
version, version_finder):
|
||||||
notify(name + ' has manual edits')
|
notify(name + ' has manual edits')
|
||||||
|
|
||||||
# retrieve the C API prototype parts
|
# retrieve the C API prototype parts
|
||||||
parts = func.get_capi_parts(defined_names, True)
|
parts = func.get_capi_parts(
|
||||||
|
defined_names, True, version=version, version_finder=version_finder)
|
||||||
|
|
||||||
changes = format_translation_changes(impl, parts)
|
changes = format_translation_changes(impl, parts)
|
||||||
if len(changes) > 0:
|
if len(changes) > 0:
|
||||||
notify(name + ' prototype changed')
|
notify(name + ' prototype changed')
|
||||||
|
|
||||||
return make_cpptoc_impl_proto(
|
return make_cpptoc_impl_proto(name, func,
|
||||||
name, func, parts) + '{' + changes + impl['body'] + '\n}\n\n'
|
parts) + '{' + changes + impl['body'] + '\n}\n'
|
||||||
|
|
||||||
|
|
||||||
def make_cpptoc_function_impl_new(cls, name, func, defined_names, base_scoped):
|
def make_cpptoc_function_impl_new(cls, name, func, defined_names, base_scoped,
|
||||||
|
version, version_finder):
|
||||||
|
if not version is None and isinstance(func, obj_function_virtual) and \
|
||||||
|
not func.exists_at_version(version):
|
||||||
|
raise Exception(
|
||||||
|
'Attempting to generate non-existing function %s at version %d' %
|
||||||
|
(name, version))
|
||||||
|
|
||||||
# Special handling for the cef_shutdown global function.
|
# Special handling for the cef_shutdown global function.
|
||||||
is_cef_shutdown = name == 'cef_shutdown' and isinstance(
|
is_cef_shutdown = name == 'cef_shutdown' and isinstance(
|
||||||
func.parent, obj_header)
|
func.parent, obj_header)
|
||||||
|
|
||||||
# retrieve the C API prototype parts
|
# retrieve the C API prototype parts
|
||||||
parts = func.get_capi_parts(defined_names, True)
|
parts = func.get_capi_parts(
|
||||||
|
defined_names, True, version=version, version_finder=version_finder)
|
||||||
result = make_cpptoc_impl_proto(name, func, parts) + ' {'
|
result = make_cpptoc_impl_proto(name, func, parts) + ' {'
|
||||||
|
|
||||||
if isinstance(func.parent, obj_class) and \
|
if isinstance(func.parent, obj_class) and \
|
||||||
@ -219,31 +231,31 @@ def make_cpptoc_function_impl_new(cls, name, func, defined_names, base_scoped):
|
|||||||
elif arg_type == 'refptr_same' or arg_type == 'refptr_diff':
|
elif arg_type == 'refptr_same' or arg_type == 'refptr_diff':
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = arg.get_type().get_ptr_type()
|
||||||
if arg_type == 'refptr_same':
|
if arg_type == 'refptr_same':
|
||||||
params.append(ptr_class + 'CppToC::Unwrap(' + arg_name + ')')
|
params.append(ptr_class + 'CppToC_Unwrap(' + arg_name + ')')
|
||||||
else:
|
else:
|
||||||
params.append(ptr_class + 'CToCpp::Wrap(' + arg_name + ')')
|
params.append(ptr_class + 'CToCpp_Wrap(' + arg_name + ')')
|
||||||
elif arg_type == 'ownptr_same' or arg_type == 'rawptr_same':
|
elif arg_type == 'ownptr_same' or arg_type == 'rawptr_same':
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = arg.get_type().get_ptr_type()
|
||||||
if arg_type == 'ownptr_same':
|
if arg_type == 'ownptr_same':
|
||||||
params.append(ptr_class + 'CppToC::UnwrapOwn(' + arg_name + ')')
|
params.append(ptr_class + 'CppToC_UnwrapOwn(' + arg_name + ')')
|
||||||
else:
|
else:
|
||||||
params.append(ptr_class + 'CppToC::UnwrapRaw(' + arg_name + ')')
|
params.append(ptr_class + 'CppToC_UnwrapRaw(' + arg_name + ')')
|
||||||
elif arg_type == 'ownptr_diff' or arg_type == 'rawptr_diff':
|
elif arg_type == 'ownptr_diff' or arg_type == 'rawptr_diff':
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = arg.get_type().get_ptr_type()
|
||||||
result += comment+\
|
result += comment+\
|
||||||
'\n CefOwnPtr<'+ptr_class+'> '+arg_name+'Ptr('+ptr_class+'CToCpp::Wrap('+arg_name+'));'
|
'\n CefOwnPtr<'+ptr_class+'> '+arg_name+'Ptr('+ptr_class+'CToCpp_Wrap('+arg_name+'));'
|
||||||
if arg_type == 'ownptr_diff':
|
if arg_type == 'ownptr_diff':
|
||||||
params.append('std::move(' + arg_name + 'Ptr)')
|
params.append('std::move(' + arg_name + 'Ptr)')
|
||||||
else:
|
else:
|
||||||
params.append(arg_name + 'Ptr.get()')
|
params.append(arg_name + 'Ptr.get()')
|
||||||
elif arg_type == 'refptr_same_byref' or arg_type == 'refptr_diff_byref':
|
elif arg_type == 'refptr_same_byref' or arg_type == 'refptr_diff_byref':
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = ptr_class_u = arg.get_type().get_ptr_type()
|
||||||
if arg_type == 'refptr_same_byref':
|
if arg_type == 'refptr_same_byref':
|
||||||
assign = ptr_class + 'CppToC::Unwrap(*' + arg_name + ')'
|
assign = ptr_class + 'CppToC_Unwrap(*' + arg_name + ')'
|
||||||
else:
|
else:
|
||||||
assign = ptr_class + 'CToCpp::Wrap(*' + arg_name + ')'
|
assign = ptr_class + 'CToCpp_Wrap(*' + arg_name + ')'
|
||||||
result += comment+\
|
result += comment+\
|
||||||
'\n CefRefPtr<'+ptr_class+'> '+arg_name+'Ptr;'\
|
'\n CefRefPtr<'+ptr_class_u+'> '+arg_name+'Ptr;'\
|
||||||
'\n if ('+arg_name+' && *'+arg_name+') {'\
|
'\n if ('+arg_name+' && *'+arg_name+') {'\
|
||||||
'\n '+arg_name+'Ptr = '+assign+';'\
|
'\n '+arg_name+'Ptr = '+assign+';'\
|
||||||
'\n }'\
|
'\n }'\
|
||||||
@ -273,10 +285,10 @@ def make_cpptoc_function_impl_new(cls, name, func, defined_names, base_scoped):
|
|||||||
assign = arg_name + '[i]?true:false'
|
assign = arg_name + '[i]?true:false'
|
||||||
elif arg_type == 'refptr_vec_same_byref':
|
elif arg_type == 'refptr_vec_same_byref':
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = arg.get_type().get_ptr_type()
|
||||||
assign = ptr_class + 'CppToC::Unwrap(' + arg_name + '[i])'
|
assign = ptr_class + 'CppToC_Unwrap(' + arg_name + '[i])'
|
||||||
elif arg_type == 'refptr_vec_diff_byref':
|
elif arg_type == 'refptr_vec_diff_byref':
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = arg.get_type().get_ptr_type()
|
||||||
assign = ptr_class + 'CToCpp::Wrap(' + arg_name + '[i])'
|
assign = ptr_class + 'CToCpp_Wrap(' + arg_name + '[i])'
|
||||||
result += comment+\
|
result += comment+\
|
||||||
'\n std::vector<'+vec_type+' > '+arg_name+'List;'\
|
'\n std::vector<'+vec_type+' > '+arg_name+'List;'\
|
||||||
'\n if ('+arg_name+'Count && *'+arg_name+'Count > 0 && '+arg_name+') {'\
|
'\n if ('+arg_name+'Count && *'+arg_name+'Count > 0 && '+arg_name+') {'\
|
||||||
@ -296,13 +308,13 @@ def make_cpptoc_function_impl_new(cls, name, func, defined_names, base_scoped):
|
|||||||
else:
|
else:
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = arg.get_type().get_ptr_type()
|
||||||
if arg_type == 'refptr_vec_same_byref_const':
|
if arg_type == 'refptr_vec_same_byref_const':
|
||||||
assign = ptr_class + 'CppToC::Unwrap(' + arg_name + '[i])'
|
assign = ptr_class + 'CppToC_Unwrap(' + arg_name + '[i])'
|
||||||
elif arg_type == 'refptr_vec_diff_byref_const':
|
elif arg_type == 'refptr_vec_diff_byref_const':
|
||||||
assign = ptr_class + 'CToCpp::Wrap(' + arg_name + '[i])'
|
assign = ptr_class + 'CToCpp_Wrap(' + arg_name + '[i])'
|
||||||
elif arg_type == 'rawptr_vec_same_byref_const':
|
elif arg_type == 'rawptr_vec_same_byref_const':
|
||||||
assign = ptr_class + 'CppToC::UnwrapRaw(' + arg_name + '[i])'
|
assign = ptr_class + 'CppToC_UnwrapRaw(' + arg_name + '[i])'
|
||||||
elif arg_type == 'rawptr_vec_diff_byref_const':
|
elif arg_type == 'rawptr_vec_diff_byref_const':
|
||||||
assign = ptr_class + 'CToCpp::Wrap(' + arg_name + '[i]).release()'
|
assign = ptr_class + 'CToCpp_Wrap(' + arg_name + '[i]).release()'
|
||||||
result += comment+\
|
result += comment+\
|
||||||
'\n std::vector<'+vec_type+' > '+arg_name+'List;'\
|
'\n std::vector<'+vec_type+' > '+arg_name+'List;'\
|
||||||
'\n if ('+arg_name+'Count > 0) {'\
|
'\n if ('+arg_name+'Count > 0) {'\
|
||||||
@ -334,13 +346,16 @@ def make_cpptoc_function_impl_new(cls, name, func, defined_names, base_scoped):
|
|||||||
if isinstance(func.parent, obj_class):
|
if isinstance(func.parent, obj_class):
|
||||||
# virtual and static class methods
|
# virtual and static class methods
|
||||||
if isinstance(func, obj_function_virtual):
|
if isinstance(func, obj_function_virtual):
|
||||||
|
ptr_class = cls.get_name()
|
||||||
|
if not version_finder is None:
|
||||||
|
ptr_class = version_finder(ptr_class, as_cpp=True)
|
||||||
if cls.get_name() == func.parent.get_name():
|
if cls.get_name() == func.parent.get_name():
|
||||||
# virtual method for the current class
|
# virtual method called for the current class
|
||||||
result += func.parent.get_name() + 'CppToC::Get(self)->'
|
result += ptr_class + 'CppToC::Get(self)->'
|
||||||
else:
|
else:
|
||||||
# virtual method for a parent class
|
# virtual method called for a parent class
|
||||||
result += cls.get_name(
|
result += ptr_class + 'CppToC::Get(reinterpret_cast<' + cls.get_capi_name(
|
||||||
) + 'CppToC::Get(reinterpret_cast<' + cls.get_capi_name() + '*>(self))->'
|
version) + '*>(self))->'
|
||||||
else:
|
else:
|
||||||
result += func.parent.get_name() + '::'
|
result += func.parent.get_name() + '::'
|
||||||
result += func.get_name() + '('
|
result += func.get_name() + '('
|
||||||
@ -382,9 +397,9 @@ def make_cpptoc_function_impl_new(cls, name, func, defined_names, base_scoped):
|
|||||||
elif arg_type == 'refptr_same_byref' or arg_type == 'refptr_diff_byref':
|
elif arg_type == 'refptr_same_byref' or arg_type == 'refptr_diff_byref':
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = arg.get_type().get_ptr_type()
|
||||||
if arg_type == 'refptr_same_byref':
|
if arg_type == 'refptr_same_byref':
|
||||||
assign = ptr_class + 'CppToC::Wrap(' + arg_name + 'Ptr)'
|
assign = ptr_class + 'CppToC_Wrap(' + arg_name + 'Ptr)'
|
||||||
else:
|
else:
|
||||||
assign = ptr_class + 'CToCpp::Unwrap(' + arg_name + 'Ptr)'
|
assign = ptr_class + 'CToCpp_Unwrap(' + arg_name + 'Ptr)'
|
||||||
result += comment+\
|
result += comment+\
|
||||||
'\n if ('+arg_name+') {'\
|
'\n if ('+arg_name+') {'\
|
||||||
'\n if ('+arg_name+'Ptr.get()) {'\
|
'\n if ('+arg_name+'Ptr.get()) {'\
|
||||||
@ -413,10 +428,10 @@ def make_cpptoc_function_impl_new(cls, name, func, defined_names, base_scoped):
|
|||||||
assign = arg_name + 'List[i]'
|
assign = arg_name + 'List[i]'
|
||||||
elif arg_type == 'refptr_vec_same_byref':
|
elif arg_type == 'refptr_vec_same_byref':
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = arg.get_type().get_ptr_type()
|
||||||
assign = ptr_class + 'CppToC::Wrap(' + arg_name + 'List[i])'
|
assign = ptr_class + 'CppToC_Wrap(' + arg_name + 'List[i])'
|
||||||
elif arg_type == 'refptr_vec_diff_byref':
|
elif arg_type == 'refptr_vec_diff_byref':
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = arg.get_type().get_ptr_type()
|
||||||
assign = ptr_class + 'CToCpp::Unwrap(' + arg_name + 'List[i])'
|
assign = ptr_class + 'CToCpp_Unwrap(' + arg_name + 'List[i])'
|
||||||
result += comment+\
|
result += comment+\
|
||||||
'\n if ('+arg_name+'Count && '+arg_name+') {'\
|
'\n if ('+arg_name+'Count && '+arg_name+') {'\
|
||||||
'\n *'+arg_name+'Count = std::min('+arg_name+'List.size(), *'+arg_name+'Count);'\
|
'\n *'+arg_name+'Count = std::min('+arg_name+'List.size(), *'+arg_name+'Count);'\
|
||||||
@ -452,80 +467,121 @@ def make_cpptoc_function_impl_new(cls, name, func, defined_names, base_scoped):
|
|||||||
result += '\n return _retval.DetachToUserFree();'
|
result += '\n return _retval.DetachToUserFree();'
|
||||||
elif retval_type == 'refptr_same':
|
elif retval_type == 'refptr_same':
|
||||||
ptr_class = retval.get_type().get_ptr_type()
|
ptr_class = retval.get_type().get_ptr_type()
|
||||||
result += '\n return ' + ptr_class + 'CppToC::Wrap(_retval);'
|
result += '\n return ' + ptr_class + 'CppToC_Wrap(_retval);'
|
||||||
elif retval_type == 'refptr_diff':
|
elif retval_type == 'refptr_diff':
|
||||||
ptr_class = retval.get_type().get_ptr_type()
|
ptr_class = retval.get_type().get_ptr_type()
|
||||||
result += '\n return ' + ptr_class + 'CToCpp::Unwrap(_retval);'
|
result += '\n return ' + ptr_class + 'CToCpp_Unwrap(_retval);'
|
||||||
elif retval_type == 'ownptr_same':
|
elif retval_type == 'ownptr_same':
|
||||||
ptr_class = retval.get_type().get_ptr_type()
|
ptr_class = retval.get_type().get_ptr_type()
|
||||||
result += '\n return ' + ptr_class + 'CppToC::WrapOwn(std::move(_retval));'
|
result += '\n return ' + ptr_class + 'CppToC_WrapOwn(std::move(_retval));'
|
||||||
elif retval_type == 'ownptr_diff':
|
elif retval_type == 'ownptr_diff':
|
||||||
ptr_class = retval.get_type().get_ptr_type()
|
ptr_class = retval.get_type().get_ptr_type()
|
||||||
result += '\n return ' + ptr_class + 'CToCpp::UnwrapOwn(std::move(_retval));'
|
result += '\n return ' + ptr_class + 'CToCpp_UnwrapOwn(std::move(_retval));'
|
||||||
else:
|
else:
|
||||||
raise Exception('Unsupported return type %s in %s' % (retval_type, name))
|
raise Exception('Unsupported return type %s in %s' % (retval_type, name))
|
||||||
|
|
||||||
if len(result) != result_len:
|
if len(result) != result_len:
|
||||||
result += '\n'
|
result += '\n'
|
||||||
|
|
||||||
result += '}\n\n'
|
result += '}\n'
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def make_cpptoc_function_impl(cls, funcs, existing, prefixname, defined_names,
|
def make_cpptoc_function_impl(cls, funcs, existing, prefixname, suffixname,
|
||||||
base_scoped):
|
defined_names, base_scoped, version,
|
||||||
|
version_finder):
|
||||||
impl = ''
|
impl = ''
|
||||||
|
|
||||||
|
customized = False
|
||||||
|
|
||||||
for func in funcs:
|
for func in funcs:
|
||||||
if not prefixname is None:
|
if not version is None and isinstance(func, obj_function_virtual) and \
|
||||||
name = prefixname + '_' + func.get_capi_name()
|
not func.exists_at_version(version):
|
||||||
else:
|
continue
|
||||||
|
|
||||||
name = func.get_capi_name()
|
name = func.get_capi_name()
|
||||||
|
if not prefixname is None:
|
||||||
|
name = prefixname + '_' + name
|
||||||
|
if not suffixname is None:
|
||||||
|
name += '_' + suffixname
|
||||||
|
|
||||||
|
if version is None:
|
||||||
|
pre, post = get_version_surround(func, long=True)
|
||||||
|
else:
|
||||||
|
pre = post = ''
|
||||||
|
|
||||||
value = get_next_function_impl(existing, name)
|
value = get_next_function_impl(existing, name)
|
||||||
if not value is None \
|
if not value is None \
|
||||||
and value['body'].find('// AUTO-GENERATED CONTENT') < 0:
|
and value['body'].find('// AUTO-GENERATED CONTENT') < 0:
|
||||||
# an implementation exists that was not auto-generated
|
# an implementation exists that was not auto-generated
|
||||||
impl += make_cpptoc_function_impl_existing(cls, name, func, value,
|
customized = True
|
||||||
defined_names)
|
impl += pre + make_cpptoc_function_impl_existing(
|
||||||
|
cls, name, func, value, defined_names, version,
|
||||||
|
version_finder) + post + '\n'
|
||||||
else:
|
else:
|
||||||
impl += make_cpptoc_function_impl_new(cls, name, func, defined_names,
|
impl += pre + make_cpptoc_function_impl_new(
|
||||||
base_scoped)
|
cls, name, func, defined_names, base_scoped, version,
|
||||||
|
version_finder) + post + '\n'
|
||||||
|
|
||||||
return impl
|
if not customized and impl.find('// COULD NOT IMPLEMENT') >= 0:
|
||||||
|
customized = True
|
||||||
|
|
||||||
|
return (impl, customized)
|
||||||
|
|
||||||
|
|
||||||
def make_cpptoc_virtual_function_impl(header, cls, existing, prefixname,
|
def make_cpptoc_virtual_function_impl(header, cls, existing, prefixname,
|
||||||
defined_names, base_scoped):
|
suffixname, defined_names, base_scoped,
|
||||||
funcs = []
|
version, version_finder):
|
||||||
funcs.extend(cls.get_virtual_funcs())
|
# don't modify the original list
|
||||||
|
funcs = copy.copy(cls.get_virtual_funcs(version=version))
|
||||||
cur_cls = cls
|
cur_cls = cls
|
||||||
while True:
|
while True:
|
||||||
parent_name = cur_cls.get_parent_name()
|
parent_name = cur_cls.get_parent_name()
|
||||||
if is_base_class(parent_name):
|
if is_base_class(parent_name):
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
parent_cls = header.get_class(parent_name, defined_names)
|
parent_cls = header.get_class(parent_name)
|
||||||
if parent_cls is None:
|
if parent_cls is None:
|
||||||
raise Exception('Class does not exist: ' + parent_name)
|
raise Exception('Class does not exist: ' + parent_name)
|
||||||
funcs.extend(parent_cls.get_virtual_funcs())
|
defined_names.append(parent_cls.get_capi_name(version))
|
||||||
cur_cls = header.get_class(parent_name, defined_names)
|
funcs.extend(parent_cls.get_virtual_funcs(version=version))
|
||||||
|
cur_cls = header.get_class(parent_name)
|
||||||
|
defined_names.append(cur_cls.get_capi_name(version))
|
||||||
|
|
||||||
return make_cpptoc_function_impl(cls, funcs, existing, prefixname,
|
return make_cpptoc_function_impl(cls, funcs, existing, prefixname, suffixname,
|
||||||
defined_names, base_scoped)
|
defined_names, base_scoped, version,
|
||||||
|
version_finder)
|
||||||
|
|
||||||
|
|
||||||
def make_cpptoc_virtual_function_assignment_block(funcs, offset, prefixname):
|
def make_cpptoc_virtual_function_assignment_block(cls, offset, prefixname,
|
||||||
|
suffixname, version):
|
||||||
impl = ''
|
impl = ''
|
||||||
|
|
||||||
|
funcs = cls.get_virtual_funcs(version_order=True, version=version)
|
||||||
|
|
||||||
for func in funcs:
|
for func in funcs:
|
||||||
name = func.get_capi_name()
|
# should only include methods directly declared in the current class
|
||||||
impl += ' GetStruct()->' + offset + name + ' = ' + prefixname + '_' + name + ';\n'
|
assert func.parent.get_name() == cls.get_name(), func.get_name()
|
||||||
|
if version is None:
|
||||||
|
pre, post = get_version_surround(func)
|
||||||
|
else:
|
||||||
|
if func.removed_at_version(version):
|
||||||
|
continue
|
||||||
|
pre = post = ''
|
||||||
|
name = oname = func.get_capi_name()
|
||||||
|
if not prefixname is None:
|
||||||
|
name = prefixname + '_' + name
|
||||||
|
if not suffixname is None:
|
||||||
|
name += '_' + suffixname
|
||||||
|
impl += pre + ' GetStruct()->' + offset + oname + ' = ' + name + ';\n' + post
|
||||||
return impl
|
return impl
|
||||||
|
|
||||||
|
|
||||||
def make_cpptoc_virtual_function_assignment(header, cls, prefixname,
|
def make_cpptoc_virtual_function_assignment(header, cls, prefixname, suffixname,
|
||||||
defined_names):
|
defined_names, version,
|
||||||
impl = make_cpptoc_virtual_function_assignment_block(cls.get_virtual_funcs(),
|
version_finder):
|
||||||
'', prefixname)
|
impl = make_cpptoc_virtual_function_assignment_block(cls, '', prefixname,
|
||||||
|
suffixname, version)
|
||||||
|
|
||||||
cur_cls = cls
|
cur_cls = cls
|
||||||
offset = ''
|
offset = ''
|
||||||
@ -535,17 +591,19 @@ def make_cpptoc_virtual_function_assignment(header, cls, prefixname,
|
|||||||
if is_base_class(parent_name):
|
if is_base_class(parent_name):
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
parent_cls = header.get_class(parent_name, defined_names)
|
parent_cls = header.get_class(parent_name)
|
||||||
if parent_cls is None:
|
if parent_cls is None:
|
||||||
raise Exception('Class does not exist: ' + parent_name)
|
raise Exception('Class does not exist: ' + parent_name)
|
||||||
|
defined_names.append(parent_cls.get_capi_name(version))
|
||||||
impl += make_cpptoc_virtual_function_assignment_block(
|
impl += make_cpptoc_virtual_function_assignment_block(
|
||||||
parent_cls.get_virtual_funcs(), offset, prefixname)
|
parent_cls, offset, prefixname, suffixname, version)
|
||||||
cur_cls = header.get_class(parent_name, defined_names)
|
cur_cls = header.get_class(parent_name)
|
||||||
|
defined_names.append(cur_cls.get_capi_name(version))
|
||||||
|
|
||||||
return impl
|
return impl
|
||||||
|
|
||||||
|
|
||||||
def make_cpptoc_unwrap_derived(header, cls, base_scoped):
|
def make_cpptoc_unwrap_derived(header, cls, base_scoped, version):
|
||||||
# identify all classes that derive from cls
|
# identify all classes that derive from cls
|
||||||
derived_classes = []
|
derived_classes = []
|
||||||
cur_clsname = cls.get_name()
|
cur_clsname = cls.get_name()
|
||||||
@ -561,39 +619,193 @@ def make_cpptoc_unwrap_derived(header, cls, base_scoped):
|
|||||||
if base_scoped:
|
if base_scoped:
|
||||||
impl = ['', '']
|
impl = ['', '']
|
||||||
for clsname in derived_classes:
|
for clsname in derived_classes:
|
||||||
impl[0] += ' if (type == '+get_wrapper_type_enum(clsname)+') {\n'+\
|
derived_cls = header.get_class(clsname)
|
||||||
' return '+clsname+'CppToC::UnwrapOwn(reinterpret_cast<'+\
|
if version is None:
|
||||||
get_capi_name(clsname, True)+'*>(s));\n'+\
|
capiname = derived_cls.get_capi_name()
|
||||||
' }\n'
|
pre, post = get_version_surround(derived_cls)
|
||||||
impl[1] += ' if (type == '+get_wrapper_type_enum(clsname)+') {\n'+\
|
else:
|
||||||
' return '+clsname+'CppToC::UnwrapRaw(reinterpret_cast<'+\
|
if not derived_cls.exists_at_version(version):
|
||||||
get_capi_name(clsname, True)+'*>(s));\n'+\
|
continue
|
||||||
' }\n'
|
capiname = derived_cls.get_capi_name(first_version=True)
|
||||||
|
pre = post = ''
|
||||||
|
|
||||||
|
impl[0] += pre + ' if (type == '+get_wrapper_type_enum(clsname)+') {\n'+\
|
||||||
|
' return '+clsname+'CppToC_UnwrapOwn(reinterpret_cast<'+capiname+'*>(s));\n'+\
|
||||||
|
' }\n' + post
|
||||||
|
impl[1] += pre + ' if (type == '+get_wrapper_type_enum(clsname)+') {\n'+\
|
||||||
|
' return '+clsname+'CppToC_UnwrapRaw(reinterpret_cast<'+capiname+'*>(s));\n'+\
|
||||||
|
' }\n' + post
|
||||||
else:
|
else:
|
||||||
impl = ''
|
impl = ''
|
||||||
for clsname in derived_classes:
|
for clsname in derived_classes:
|
||||||
impl += ' if (type == '+get_wrapper_type_enum(clsname)+') {\n'+\
|
derived_cls = header.get_class(clsname)
|
||||||
' return '+clsname+'CppToC::Unwrap(reinterpret_cast<'+\
|
if version is None:
|
||||||
get_capi_name(clsname, True)+'*>(s));\n'+\
|
capiname = derived_cls.get_capi_name()
|
||||||
' }\n'
|
pre, post = get_version_surround(derived_cls)
|
||||||
|
else:
|
||||||
|
if not derived_cls.exists_at_version(version):
|
||||||
|
continue
|
||||||
|
capiname = derived_cls.get_capi_name(first_version=True)
|
||||||
|
pre = post = ''
|
||||||
|
|
||||||
|
impl += pre + ' if (type == '+get_wrapper_type_enum(clsname)+') {\n'+\
|
||||||
|
' return '+clsname+'CppToC_Unwrap(reinterpret_cast<'+capiname+'*>(s));\n'+\
|
||||||
|
' }\n' + post
|
||||||
return impl
|
return impl
|
||||||
|
|
||||||
|
|
||||||
|
def make_cpptoc_version_wrappers(header, cls, base_scoped, versions):
|
||||||
|
assert len(versions) > 0
|
||||||
|
|
||||||
|
clsname = cls.get_name()
|
||||||
|
typename = clsname + 'CppToC'
|
||||||
|
structname = cls.get_capi_name(version=versions[0])
|
||||||
|
|
||||||
|
rversions = sorted(versions, reverse=True)
|
||||||
|
|
||||||
|
notreached = format_notreached(
|
||||||
|
True,
|
||||||
|
'" called with invalid version " << version',
|
||||||
|
default_retval='nullptr')
|
||||||
|
|
||||||
|
impl = ''
|
||||||
|
|
||||||
|
if base_scoped:
|
||||||
|
impl += structname + '* ' + typename + '_WrapOwn(CefOwnPtr<' + clsname + '> c) {\n' + \
|
||||||
|
' const int version = cef_api_version();\n'
|
||||||
|
|
||||||
|
for version in rversions:
|
||||||
|
vstr = str(version)
|
||||||
|
impl += ' if (version >= ' + vstr + ') {\n'
|
||||||
|
if versions[0] == version:
|
||||||
|
impl += ' return ' + clsname + '_' + vstr + '_CppToC::WrapOwn(std::move(c));\n'
|
||||||
|
else:
|
||||||
|
impl += ' return reinterpret_cast<' + structname + '*>(' + clsname + '_' + vstr + '_CppToC::WrapOwn(std::move(c)));\n'
|
||||||
|
impl += ' }\n'
|
||||||
|
|
||||||
|
impl += ' ' + notreached + '\n'+ \
|
||||||
|
'}\n\n' + \
|
||||||
|
'std::pair<CefOwnPtr<CefBaseScoped>, '+ structname + '*> ' + typename + '_WrapRaw(CefRawPtr<' + clsname + '> c) {\n' + \
|
||||||
|
' const int version = cef_api_version();\n'
|
||||||
|
|
||||||
|
for version in rversions:
|
||||||
|
vstr = str(version)
|
||||||
|
impl += ' if (version >= ' + vstr + ') {\n'
|
||||||
|
if versions[0] == version:
|
||||||
|
impl += ' return ' + clsname + '_' + vstr + '_CppToC::WrapRaw(std::move(c));\n'
|
||||||
|
else:
|
||||||
|
impl += ' auto [ownPtr, structPtr] = ' + clsname + '_' + vstr + '_CppToC::WrapRaw(std::move(c));\n' + \
|
||||||
|
' return std::make_pair(std::move(ownPtr), reinterpret_cast<' + structname + '*>(structPtr));\n'
|
||||||
|
impl += ' }\n'
|
||||||
|
|
||||||
|
impl += ' ' + notreached + '\n'+ \
|
||||||
|
'}\n\n' + \
|
||||||
|
'CefOwnPtr<' + clsname + '> ' + typename + '_UnwrapOwn('+ structname + '* s) {\n' + \
|
||||||
|
' const int version = cef_api_version();\n'
|
||||||
|
|
||||||
|
for version in rversions:
|
||||||
|
vstr = str(version)
|
||||||
|
impl += ' if (version >= ' + vstr + ') {\n'
|
||||||
|
if versions[0] == version:
|
||||||
|
impl += ' return ' + clsname + '_' + vstr + '_CppToC::UnwrapOwn(s);\n'
|
||||||
|
else:
|
||||||
|
impl += ' return ' + clsname + '_' + vstr + '_CppToC::UnwrapOwn(reinterpret_cast<' + cls.get_capi_name(
|
||||||
|
version) + '*>(s));\n'
|
||||||
|
impl += ' }\n'
|
||||||
|
|
||||||
|
impl += ' ' + notreached + '\n'+ \
|
||||||
|
'}\n\n' + \
|
||||||
|
'CefRawPtr<' + clsname + '> ' + typename + '_UnwrapRaw('+ structname + '* s) {\n' + \
|
||||||
|
' const int version = cef_api_version();\n'
|
||||||
|
|
||||||
|
for version in rversions:
|
||||||
|
vstr = str(version)
|
||||||
|
impl += ' if (version >= ' + vstr + ') {\n'
|
||||||
|
if versions[0] == version:
|
||||||
|
impl += ' return ' + clsname + '_' + vstr + '_CppToC::UnwrapRaw(s);\n'
|
||||||
|
else:
|
||||||
|
impl += ' return ' + clsname + '_' + vstr + '_CppToC::UnwrapRaw(reinterpret_cast<' + cls.get_capi_name(
|
||||||
|
version) + '*>(s));\n'
|
||||||
|
impl += ' }\n'
|
||||||
|
|
||||||
|
impl += ' ' + notreached + '\n'+ \
|
||||||
|
'}\n\n' + \
|
||||||
|
'CefBaseScoped* ' + typename + '_GetWrapper('+ structname + '* s) {\n' + \
|
||||||
|
' const int version = cef_api_version();\n'
|
||||||
|
|
||||||
|
for version in rversions:
|
||||||
|
vstr = str(version)
|
||||||
|
impl += ' if (version >= ' + vstr + ') {\n'
|
||||||
|
if versions[0] == version:
|
||||||
|
impl += ' return ' + clsname + '_' + vstr + '_CppToC::GetWrapper(s);\n'
|
||||||
|
else:
|
||||||
|
impl += ' return ' + clsname + '_' + vstr + '_CppToC::GetWrapper(reinterpret_cast<' + cls.get_capi_name(
|
||||||
|
version) + '*>(s));\n'
|
||||||
|
impl += ' }\n'
|
||||||
|
|
||||||
|
impl += ' ' + notreached + '\n'+ \
|
||||||
|
'}\n'
|
||||||
|
else:
|
||||||
|
impl += structname + '* ' + typename + '_Wrap(CefRefPtr<' + clsname + '> c) {\n' + \
|
||||||
|
' const int version = cef_api_version();\n'
|
||||||
|
|
||||||
|
for version in rversions:
|
||||||
|
vstr = str(version)
|
||||||
|
impl += ' if (version >= ' + vstr + ') {\n'
|
||||||
|
if versions[0] == version:
|
||||||
|
impl += ' return ' + clsname + '_' + vstr + '_CppToC::Wrap(c);\n'
|
||||||
|
else:
|
||||||
|
impl += ' return reinterpret_cast<' + structname + '*>(' + clsname + '_' + vstr + '_CppToC::Wrap(c));\n'
|
||||||
|
impl += ' }\n'
|
||||||
|
|
||||||
|
impl += ' ' + notreached + '\n'+ \
|
||||||
|
'}\n\n' + \
|
||||||
|
'CefRefPtr<' + clsname + '> ' + typename + '_Unwrap('+ structname + '* s) {\n' + \
|
||||||
|
' const int version = cef_api_version();\n'
|
||||||
|
|
||||||
|
for version in rversions:
|
||||||
|
vstr = str(version)
|
||||||
|
impl += ' if (version >= ' + vstr + ') {\n'
|
||||||
|
if versions[0] == version:
|
||||||
|
impl += ' return ' + clsname + '_' + vstr + '_CppToC::Unwrap(s);\n'
|
||||||
|
else:
|
||||||
|
impl += ' return ' + clsname + '_' + vstr + '_CppToC::Unwrap(reinterpret_cast<' + cls.get_capi_name(
|
||||||
|
version) + '*>(s));\n'
|
||||||
|
impl += ' }\n'
|
||||||
|
|
||||||
|
impl += ' ' + notreached + '\n'+ \
|
||||||
|
'}\n'
|
||||||
|
|
||||||
|
return impl + '\n'
|
||||||
|
|
||||||
|
|
||||||
|
def _version_finder(header, version, name, as_cpp=False):
|
||||||
|
assert version is None or isinstance(version, int), version
|
||||||
|
assert name[-1] != '*', name
|
||||||
|
|
||||||
|
if as_cpp:
|
||||||
|
cls = header.get_class(name)
|
||||||
|
if cls is None:
|
||||||
|
return name
|
||||||
|
return cls.get_name(version=version)
|
||||||
|
|
||||||
|
cls = header.get_capi_class(name)
|
||||||
|
if not cls is None:
|
||||||
|
return cls.get_capi_name(first_version=True)
|
||||||
|
return name
|
||||||
|
|
||||||
|
|
||||||
def make_cpptoc_class_impl(header, clsname, impl):
|
def make_cpptoc_class_impl(header, clsname, impl):
|
||||||
# structure names that have already been defined
|
# structure names that have already been defined
|
||||||
defined_names = header.get_defined_structs()
|
defined_names = header.get_defined_structs()
|
||||||
|
|
||||||
# retrieve the class and populate the defined names
|
# retrieve the class and populate the defined names
|
||||||
cls = header.get_class(clsname, defined_names)
|
cls = header.get_class(clsname)
|
||||||
if cls is None:
|
if cls is None:
|
||||||
raise Exception('Class does not exist: ' + clsname)
|
raise Exception('Class does not exist: ' + clsname)
|
||||||
|
|
||||||
capiname = cls.get_capi_name()
|
|
||||||
prefixname = get_capi_name(clsname[3:], False)
|
prefixname = get_capi_name(clsname[3:], False)
|
||||||
|
|
||||||
# retrieve the existing virtual function implementations
|
|
||||||
existing = get_function_impls(impl, 'CEF_CALLBACK')
|
|
||||||
|
|
||||||
base_class_name = header.get_base_class_name(clsname)
|
base_class_name = header.get_base_class_name(clsname)
|
||||||
base_scoped = True if base_class_name == 'CefBaseScoped' else False
|
base_scoped = True if base_class_name == 'CefBaseScoped' else False
|
||||||
if base_scoped:
|
if base_scoped:
|
||||||
@ -601,80 +813,143 @@ def make_cpptoc_class_impl(header, clsname, impl):
|
|||||||
else:
|
else:
|
||||||
template_class = 'CefCppToCRefCounted'
|
template_class = 'CefCppToCRefCounted'
|
||||||
|
|
||||||
# generate virtual functions
|
with_versions = cls.is_library_side()
|
||||||
virtualimpl = make_cpptoc_virtual_function_impl(
|
versions = list(cls.get_all_versions()) if with_versions else (None,)
|
||||||
header, cls, existing, prefixname, defined_names, base_scoped)
|
|
||||||
if len(virtualimpl) > 0:
|
|
||||||
virtualimpl = '\nnamespace {\n\n// MEMBER FUNCTIONS - Body may be edited by hand.\n\n' + virtualimpl + '} // namespace'
|
|
||||||
|
|
||||||
# the current class is already defined for static functions
|
|
||||||
defined_names.append(cls.get_capi_name())
|
|
||||||
|
|
||||||
# retrieve the existing static function implementations
|
# retrieve the existing static function implementations
|
||||||
existing = get_function_impls(impl, 'CEF_EXPORT')
|
existing_static = get_function_impls(impl, 'CEF_EXPORT')
|
||||||
|
|
||||||
|
# retrieve the existing virtual function implementations
|
||||||
|
existing_virtual = get_function_impls(impl, 'CEF_CALLBACK')
|
||||||
|
|
||||||
|
staticout = virtualout = ''
|
||||||
|
customized = False
|
||||||
|
first = True
|
||||||
|
idx = 0
|
||||||
|
|
||||||
|
for version in versions:
|
||||||
|
version_finder = functools.partial(_version_finder, header,
|
||||||
|
version) if with_versions else None
|
||||||
|
defined_names.append(cls.get_capi_name(version=version))
|
||||||
|
|
||||||
|
if first:
|
||||||
|
first = False
|
||||||
|
|
||||||
# generate static functions
|
# generate static functions
|
||||||
staticimpl = make_cpptoc_function_impl(cls,
|
staticimpl, scustomized = make_cpptoc_function_impl(
|
||||||
cls.get_static_funcs(), existing, None,
|
cls,
|
||||||
defined_names, base_scoped)
|
cls.get_static_funcs(), existing_static, None, None, defined_names,
|
||||||
|
base_scoped, version, version_finder)
|
||||||
if len(staticimpl) > 0:
|
if len(staticimpl) > 0:
|
||||||
staticimpl = '\n// GLOBAL FUNCTIONS - Body may be edited by hand.\n\n' + staticimpl
|
staticout += '// GLOBAL FUNCTIONS - Body may be edited by hand.\n\n' + staticimpl
|
||||||
|
if scustomized:
|
||||||
|
customized = True
|
||||||
|
|
||||||
resultingimpl = staticimpl + virtualimpl
|
if len(versions) > 1:
|
||||||
|
staticout += '// HELPER FUNCTIONS - Do not edit by hand.\n\n'
|
||||||
|
staticout += make_cpptoc_version_wrappers(header, cls, base_scoped,
|
||||||
|
versions)
|
||||||
|
|
||||||
|
comment = '' if version is None else (' FOR VERSION %d' % version)
|
||||||
|
|
||||||
|
suffixname = str(version) if (len(versions) > 1 and version > 0) else None
|
||||||
|
|
||||||
|
# generate virtual functions
|
||||||
|
virtualimpl, vcustomized = make_cpptoc_virtual_function_impl(
|
||||||
|
header, cls, existing_virtual, prefixname, suffixname, defined_names,
|
||||||
|
base_scoped, version, version_finder)
|
||||||
|
if len(virtualimpl) > 0:
|
||||||
|
virtualout += 'namespace {\n\n// MEMBER FUNCTIONS' + comment + ' - Body may be edited by hand.\n\n' + \
|
||||||
|
virtualimpl + '} // namespace\n\n'
|
||||||
|
if vcustomized:
|
||||||
|
customized = True
|
||||||
|
|
||||||
# any derived classes can be unwrapped
|
# any derived classes can be unwrapped
|
||||||
unwrapderived = make_cpptoc_unwrap_derived(header, cls, base_scoped)
|
unwrapderived = make_cpptoc_unwrap_derived(header, cls, base_scoped,
|
||||||
|
version)
|
||||||
|
|
||||||
|
capiname = cls.get_capi_name(version=version)
|
||||||
|
typename = cls.get_name(version=version) + 'CppToC'
|
||||||
|
|
||||||
|
const = '// CONSTRUCTOR' + comment + ' - Do not edit by hand.\n\n'+ \
|
||||||
|
typename+'::'+typename+'() {\n'
|
||||||
|
|
||||||
|
if not version is None:
|
||||||
|
if idx < len(versions) - 1:
|
||||||
|
condition = 'version < %d || version >= %d' % (version, versions[idx
|
||||||
|
+ 1])
|
||||||
|
else:
|
||||||
|
condition = 'version < %d' % version
|
||||||
|
|
||||||
|
const += ' const int version = cef_api_version();\n' + \
|
||||||
|
' LOG_IF(FATAL, ' + condition + ') << __func__ << " called with invalid version " << version;\n\n'
|
||||||
|
|
||||||
const = '// CONSTRUCTOR - Do not edit by hand.\n\n'+ \
|
|
||||||
clsname+'CppToC::'+clsname+'CppToC() {\n'
|
|
||||||
const += make_cpptoc_virtual_function_assignment(header, cls, prefixname,
|
const += make_cpptoc_virtual_function_assignment(header, cls, prefixname,
|
||||||
defined_names)
|
suffixname, defined_names,
|
||||||
|
version, version_finder)
|
||||||
const += '}\n\n'+ \
|
const += '}\n\n'+ \
|
||||||
'// DESTRUCTOR - Do not edit by hand.\n\n'+ \
|
'// DESTRUCTOR' + comment + ' - Do not edit by hand.\n\n'+ \
|
||||||
clsname+'CppToC::~'+clsname+'CppToC() {\n'
|
typename+'::~'+typename+'() {\n'
|
||||||
|
|
||||||
if not cls.has_attrib('no_debugct_check') and not base_scoped:
|
if not cls.has_attrib('no_debugct_check') and not base_scoped:
|
||||||
const += ' shutdown_checker::AssertNotShutdown();\n'
|
const += ' shutdown_checker::AssertNotShutdown();\n'
|
||||||
|
|
||||||
const += '}\n\n'
|
const += '}\n\n'
|
||||||
|
|
||||||
# determine what includes are required by identifying what translation
|
parent_sig = template_class + '<' + typename + ', ' + clsname + ', ' + capiname + '>'
|
||||||
# classes are being used
|
notreached = format_notreached(
|
||||||
includes = format_translation_includes(header, const + resultingimpl +
|
with_versions,
|
||||||
(unwrapderived[0]
|
'" called with unexpected class type " << type',
|
||||||
if base_scoped else unwrapderived))
|
default_retval='nullptr')
|
||||||
|
|
||||||
# build the final output
|
|
||||||
result = get_copyright()
|
|
||||||
|
|
||||||
result += includes + '\n' + resultingimpl + '\n'
|
|
||||||
|
|
||||||
parent_sig = template_class + '<' + clsname + 'CppToC, ' + clsname + ', ' + capiname + '>'
|
|
||||||
|
|
||||||
if base_scoped:
|
if base_scoped:
|
||||||
const += 'template<> CefOwnPtr<'+clsname+'> '+parent_sig+'::UnwrapDerivedOwn(CefWrapperType type, '+capiname+'* s) {\n' + \
|
const += 'template<> CefOwnPtr<'+clsname+'> '+parent_sig+'::UnwrapDerivedOwn(CefWrapperType type, '+capiname+'* s) {\n' + \
|
||||||
unwrapderived[0] + \
|
unwrapderived[0] + \
|
||||||
' DCHECK(false) << "Unexpected class type: " << type;\n'+ \
|
' ' + notreached + '\n'+ \
|
||||||
' return CefOwnPtr<'+clsname+'>();\n'+ \
|
|
||||||
'}\n\n' + \
|
'}\n\n' + \
|
||||||
'template<> CefRawPtr<'+clsname+'> '+parent_sig+'::UnwrapDerivedRaw(CefWrapperType type, '+capiname+'* s) {\n' + \
|
'template<> CefRawPtr<'+clsname+'> '+parent_sig+'::UnwrapDerivedRaw(CefWrapperType type, '+capiname+'* s) {\n' + \
|
||||||
unwrapderived[1] + \
|
unwrapderived[1] + \
|
||||||
' DCHECK(false) << "Unexpected class type: " << type;\n'+ \
|
' ' + notreached + '\n'+ \
|
||||||
' return nullptr;\n'+ \
|
|
||||||
'}\n\n'
|
'}\n\n'
|
||||||
else:
|
else:
|
||||||
const += 'template<> CefRefPtr<'+clsname+'> '+parent_sig+'::UnwrapDerived(CefWrapperType type, '+capiname+'* s) {\n' + \
|
const += 'template<> CefRefPtr<'+clsname+'> '+parent_sig+'::UnwrapDerived(CefWrapperType type, '+capiname+'* s) {\n' + \
|
||||||
unwrapderived + \
|
unwrapderived + \
|
||||||
' DCHECK(false) << "Unexpected class type: " << type;\n'+ \
|
' ' + notreached + '\n'+ \
|
||||||
' return nullptr;\n'+ \
|
|
||||||
'}\n\n'
|
'}\n\n'
|
||||||
|
|
||||||
const += 'template<> CefWrapperType ' + parent_sig + '::kWrapperType = ' + get_wrapper_type_enum(
|
const += 'template<> CefWrapperType ' + parent_sig + '::kWrapperType = ' + get_wrapper_type_enum(
|
||||||
clsname) + ';'
|
clsname) + ';\n\n'
|
||||||
|
|
||||||
result += '\n\n' + const
|
virtualout += const
|
||||||
|
idx += 1
|
||||||
|
|
||||||
return result
|
out = staticout + virtualout
|
||||||
|
|
||||||
|
# determine what includes are required by identifying what translation
|
||||||
|
# classes are being used
|
||||||
|
includes = format_translation_includes(
|
||||||
|
header,
|
||||||
|
out + (unwrapderived[0] if base_scoped else unwrapderived),
|
||||||
|
with_versions=with_versions)
|
||||||
|
|
||||||
|
# build the final output
|
||||||
|
result = get_copyright()
|
||||||
|
|
||||||
|
result += includes + '\n'
|
||||||
|
|
||||||
|
if with_versions:
|
||||||
|
pre = post = ''
|
||||||
|
else:
|
||||||
|
pre, post = get_version_surround(cls, long=True)
|
||||||
|
if len(pre) > 0:
|
||||||
|
result += pre + '\n'
|
||||||
|
|
||||||
|
result += out + '\n'
|
||||||
|
|
||||||
|
if len(post) > 0:
|
||||||
|
result += post + '\n'
|
||||||
|
|
||||||
|
return (result, customized)
|
||||||
|
|
||||||
|
|
||||||
def make_cpptoc_global_impl(header, impl):
|
def make_cpptoc_global_impl(header, impl):
|
||||||
@ -684,34 +959,36 @@ def make_cpptoc_global_impl(header, impl):
|
|||||||
# retrieve the existing global function implementations
|
# retrieve the existing global function implementations
|
||||||
existing = get_function_impls(impl, 'CEF_EXPORT')
|
existing = get_function_impls(impl, 'CEF_EXPORT')
|
||||||
|
|
||||||
|
version_finder = functools.partial(_version_finder, header, None)
|
||||||
|
|
||||||
# generate global functions
|
# generate global functions
|
||||||
impl = make_cpptoc_function_impl(None,
|
impl, customized = make_cpptoc_function_impl(None,
|
||||||
header.get_funcs(), existing, None,
|
header.get_funcs(), existing,
|
||||||
defined_names, False)
|
None, None, defined_names, False,
|
||||||
|
None, version_finder)
|
||||||
if len(impl) > 0:
|
if len(impl) > 0:
|
||||||
impl = '\n// GLOBAL FUNCTIONS - Body may be edited by hand.\n\n' + impl
|
impl = '\n// GLOBAL FUNCTIONS - Body may be edited by hand.\n\n' + impl
|
||||||
|
|
||||||
includes = ''
|
includes = ''
|
||||||
|
|
||||||
# include required headers for global functions
|
# include required headers for global functions
|
||||||
filenames = []
|
paths = set()
|
||||||
for func in header.get_funcs():
|
for func in header.get_funcs():
|
||||||
filename = func.get_file_name()
|
filename = func.get_file_name()
|
||||||
if not filename in filenames:
|
paths.add('include/' + func.get_file_name())
|
||||||
includes += '#include "include/'+func.get_file_name()+'"\n' \
|
paths.add('include/capi/' + func.get_capi_file_name(versions=True))
|
||||||
'#include "include/capi/'+func.get_capi_file_name()+'"\n'
|
|
||||||
filenames.append(filename)
|
|
||||||
|
|
||||||
# determine what includes are required by identifying what translation
|
# determine what includes are required by identifying what translation
|
||||||
# classes are being used
|
# classes are being used
|
||||||
includes += format_translation_includes(header, impl)
|
includes += format_translation_includes(
|
||||||
|
header, impl, with_versions=True, other_includes=paths)
|
||||||
|
|
||||||
# build the final output
|
# build the final output
|
||||||
result = get_copyright()
|
result = get_copyright()
|
||||||
|
|
||||||
result += includes + '\n' + impl
|
result += includes + '\n' + impl
|
||||||
|
|
||||||
return result
|
return (result, customized)
|
||||||
|
|
||||||
|
|
||||||
def write_cpptoc_impl(header, clsname, dir):
|
def write_cpptoc_impl(header, clsname, dir):
|
||||||
@ -725,16 +1002,22 @@ def write_cpptoc_impl(header, clsname, dir):
|
|||||||
dir = os.path.dirname(os.path.join(dir, cls.get_file_name()))
|
dir = os.path.dirname(os.path.join(dir, cls.get_file_name()))
|
||||||
file = os.path.join(dir, get_capi_name(clsname[3:], False) + '_cpptoc.cc')
|
file = os.path.join(dir, get_capi_name(clsname[3:], False) + '_cpptoc.cc')
|
||||||
|
|
||||||
|
set_notify_context(file)
|
||||||
|
|
||||||
if path_exists(file):
|
if path_exists(file):
|
||||||
oldcontents = read_file(file)
|
oldcontents = read_file(file)
|
||||||
else:
|
else:
|
||||||
oldcontents = ''
|
oldcontents = ''
|
||||||
|
|
||||||
if clsname is None:
|
if clsname is None:
|
||||||
newcontents = make_cpptoc_global_impl(header, oldcontents)
|
newcontents, customized = make_cpptoc_global_impl(header, oldcontents)
|
||||||
else:
|
else:
|
||||||
newcontents = make_cpptoc_class_impl(header, clsname, oldcontents)
|
newcontents, customized = make_cpptoc_class_impl(header, clsname,
|
||||||
return (file, newcontents)
|
oldcontents)
|
||||||
|
|
||||||
|
set_notify_context(None)
|
||||||
|
|
||||||
|
return (file, newcontents, customized)
|
||||||
|
|
||||||
|
|
||||||
# test the module
|
# test the module
|
||||||
|
@ -6,22 +6,25 @@ from __future__ import absolute_import
|
|||||||
from cef_parser import *
|
from cef_parser import *
|
||||||
|
|
||||||
|
|
||||||
def make_function_body_block(cls):
|
def make_function_body_block(cls, with_versions):
|
||||||
impl = ' // ' + cls.get_name() + ' methods.\n'
|
impl = ' // ' + cls.get_name() + ' methods.\n'
|
||||||
|
|
||||||
funcs = cls.get_virtual_funcs()
|
funcs = cls.get_virtual_funcs()
|
||||||
for func in funcs:
|
for func in funcs:
|
||||||
impl += ' ' + func.get_cpp_proto()
|
if func.parent.get_name() != cls.get_name():
|
||||||
if cls.is_client_side():
|
# skip methods that are not directly declared in the current class
|
||||||
impl += ' override;\n'
|
continue
|
||||||
|
if with_versions:
|
||||||
|
pre = post = ''
|
||||||
else:
|
else:
|
||||||
impl += ' override;\n'
|
pre, post = get_version_surround(func)
|
||||||
|
impl += pre + ' ' + func.get_cpp_proto() + ' override;\n' + post
|
||||||
|
|
||||||
return impl
|
return impl
|
||||||
|
|
||||||
|
|
||||||
def make_function_body(header, cls):
|
def make_function_body(header, cls, with_versions):
|
||||||
impl = make_function_body_block(cls)
|
impl = make_function_body_block(cls, with_versions)
|
||||||
|
|
||||||
cur_cls = cls
|
cur_cls = cls
|
||||||
while True:
|
while True:
|
||||||
@ -34,7 +37,7 @@ def make_function_body(header, cls):
|
|||||||
raise Exception('Class does not exist: ' + parent_name)
|
raise Exception('Class does not exist: ' + parent_name)
|
||||||
if len(impl) > 0:
|
if len(impl) > 0:
|
||||||
impl += '\n'
|
impl += '\n'
|
||||||
impl += make_function_body_block(parent_cls)
|
impl += make_function_body_block(parent_cls, with_versions)
|
||||||
cur_cls = header.get_class(parent_name)
|
cur_cls = header.get_class(parent_name)
|
||||||
|
|
||||||
return impl
|
return impl
|
||||||
@ -54,8 +57,6 @@ def make_ctocpp_header(header, clsname):
|
|||||||
defname += get_capi_name(clsname[3:], False)
|
defname += get_capi_name(clsname[3:], False)
|
||||||
defname = defname.upper()
|
defname = defname.upper()
|
||||||
|
|
||||||
capiname = cls.get_capi_name()
|
|
||||||
|
|
||||||
result = get_copyright()
|
result = get_copyright()
|
||||||
|
|
||||||
result += '#ifndef CEF_LIBCEF_DLL_CTOCPP_'+defname+'_CTOCPP_H_\n'+ \
|
result += '#ifndef CEF_LIBCEF_DLL_CTOCPP_'+defname+'_CTOCPP_H_\n'+ \
|
||||||
@ -75,8 +76,10 @@ def make_ctocpp_header(header, clsname):
|
|||||||
#endif
|
#endif
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
with_versions = clientside
|
||||||
|
|
||||||
# build the function body
|
# build the function body
|
||||||
func_body = make_function_body(header, cls)
|
func_body = make_function_body(header, cls, with_versions)
|
||||||
|
|
||||||
# include standard headers
|
# include standard headers
|
||||||
if func_body.find('std::map') > 0 or func_body.find('std::multimap') > 0:
|
if func_body.find('std::map') > 0 or func_body.find('std::multimap') > 0:
|
||||||
@ -86,7 +89,7 @@ def make_ctocpp_header(header, clsname):
|
|||||||
|
|
||||||
# include the headers for this class
|
# include the headers for this class
|
||||||
result += '\n#include "include/'+cls.get_file_name()+'"'+ \
|
result += '\n#include "include/'+cls.get_file_name()+'"'+ \
|
||||||
'\n#include "include/capi/'+cls.get_capi_file_name()+'"\n'
|
'\n#include "include/capi/'+cls.get_capi_file_name(versions=with_versions)+'"\n'
|
||||||
|
|
||||||
# include headers for any forward declared classes that are not in the same file
|
# include headers for any forward declared classes that are not in the same file
|
||||||
declares = cls.get_forward_declares()
|
declares = cls.get_forward_declares()
|
||||||
@ -94,7 +97,7 @@ def make_ctocpp_header(header, clsname):
|
|||||||
dcls = header.get_class(declare)
|
dcls = header.get_class(declare)
|
||||||
if dcls.get_file_name() != cls.get_file_name():
|
if dcls.get_file_name() != cls.get_file_name():
|
||||||
result += '#include "include/'+dcls.get_file_name()+'"\n' \
|
result += '#include "include/'+dcls.get_file_name()+'"\n' \
|
||||||
'#include "include/capi/'+dcls.get_capi_file_name()+'"\n'
|
'#include "include/capi/'+dcls.get_capi_file_name(versions=with_versions)+'"\n'
|
||||||
|
|
||||||
base_class_name = header.get_base_class_name(clsname)
|
base_class_name = header.get_base_class_name(clsname)
|
||||||
base_scoped = True if base_class_name == 'CefBaseScoped' else False
|
base_scoped = True if base_class_name == 'CefBaseScoped' else False
|
||||||
@ -106,22 +109,67 @@ def make_ctocpp_header(header, clsname):
|
|||||||
template_class = 'CefCToCppRefCounted'
|
template_class = 'CefCToCppRefCounted'
|
||||||
|
|
||||||
result += '#include "libcef_dll/ctocpp/' + template_file + '"'
|
result += '#include "libcef_dll/ctocpp/' + template_file + '"'
|
||||||
result += '\n\n// Wrap a C structure with a C++ class.\n'
|
|
||||||
|
|
||||||
|
if with_versions:
|
||||||
|
pre = post = ''
|
||||||
|
else:
|
||||||
|
pre, post = get_version_surround(cls, long=True)
|
||||||
|
if len(pre) > 0:
|
||||||
|
result += '\n\n' + pre.strip()
|
||||||
|
|
||||||
|
result += '\n\n'
|
||||||
|
|
||||||
|
versions = cls.get_all_versions() if with_versions else (None,)
|
||||||
|
|
||||||
|
for version in versions:
|
||||||
|
result += '// Wrap a C structure with a C++ class%s.\n' % \
|
||||||
|
('' if version is None else ' at API version %d' % version)
|
||||||
if clientside:
|
if clientside:
|
||||||
result += '// This class may be instantiated and accessed DLL-side only.\n'
|
result += '// This class may be instantiated and accessed DLL-side only.\n'
|
||||||
else:
|
else:
|
||||||
result += '// This class may be instantiated and accessed wrapper-side only.\n'
|
result += '// This class may be instantiated and accessed wrapper-side only.\n'
|
||||||
|
|
||||||
result += 'class '+clsname+'CToCpp\n'+ \
|
capiname = cls.get_capi_name(version=version)
|
||||||
' : public ' + template_class + '<'+clsname+'CToCpp, '+clsname+', '+capiname+'> {\n'+ \
|
if version is None:
|
||||||
|
typename = clsname + 'CToCpp'
|
||||||
|
else:
|
||||||
|
typename = clsname + '_%d_CToCpp' % version
|
||||||
|
|
||||||
|
result += 'class '+typename+'\n'+ \
|
||||||
|
' : public ' + template_class + '<'+typename+', '+clsname+', '+capiname+'> {\n'+ \
|
||||||
' public:\n'+ \
|
' public:\n'+ \
|
||||||
' '+clsname+'CToCpp();\n'+ \
|
' '+typename+'();\n'+ \
|
||||||
' virtual ~'+clsname+'CToCpp();\n\n'
|
' virtual ~'+typename+'();\n\n'
|
||||||
|
|
||||||
result += func_body
|
result += func_body
|
||||||
result += '};\n\n'
|
result += '};\n\n'
|
||||||
|
|
||||||
|
typename = clsname + 'CToCpp'
|
||||||
|
if len(versions) > 1:
|
||||||
|
result += '// Helpers to return objects at the globally configured API version.\n'
|
||||||
|
structname = cls.get_capi_name(version=versions[0])
|
||||||
|
if base_scoped:
|
||||||
|
result += 'CefOwnPtr<' + clsname + '> ' + typename + '_Wrap(' + structname + '* s);\n' + \
|
||||||
|
structname + '* ' + typename + '_UnwrapOwn(CefOwnPtr<' + clsname + '> c);\n' + \
|
||||||
|
structname + '* ' + typename + '_UnwrapRaw(CefRawPtr<' + clsname + '> c);\n\n'
|
||||||
|
else:
|
||||||
|
result += 'CefRefPtr<' + clsname + '> ' + typename + '_Wrap(' + structname + '* s);\n' + \
|
||||||
|
structname + '* ' + typename + '_Unwrap(CefRefPtr<' + clsname + '> c);\n\n'
|
||||||
|
else:
|
||||||
|
if versions[0] is None:
|
||||||
|
targetname = clsname + 'CToCpp'
|
||||||
|
else:
|
||||||
|
targetname = clsname + '_%d_CToCpp' % versions[0]
|
||||||
|
if base_scoped:
|
||||||
|
result += 'constexpr auto ' + typename + '_Wrap = ' + targetname + '::Wrap;\n' + \
|
||||||
|
'constexpr auto ' + typename + '_UnwrapOwn = ' + targetname + '::UnwrapOwn;\n' + \
|
||||||
|
'constexpr auto ' + typename + '_UnwrapRaw = ' + targetname + '::UnwrapRaw;\n\n'
|
||||||
|
else:
|
||||||
|
result += 'constexpr auto ' + typename + '_Wrap = ' + targetname + '::Wrap;\n' + \
|
||||||
|
'constexpr auto ' + typename + '_Unwrap = ' + targetname + '::Unwrap;\n\n'
|
||||||
|
if len(post) > 0:
|
||||||
|
result += post + '\n'
|
||||||
|
|
||||||
result += '#endif // CEF_LIBCEF_DLL_CTOCPP_' + defname + '_CTOCPP_H_'
|
result += '#endif // CEF_LIBCEF_DLL_CTOCPP_' + defname + '_CTOCPP_H_'
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from cef_parser import *
|
from cef_parser import *
|
||||||
|
import functools
|
||||||
|
|
||||||
|
|
||||||
def make_ctocpp_impl_proto(clsname, name, func, parts):
|
def make_ctocpp_impl_proto(clsname, name, func, parts):
|
||||||
@ -25,42 +26,31 @@ def make_ctocpp_impl_proto(clsname, name, func, parts):
|
|||||||
return proto
|
return proto
|
||||||
|
|
||||||
|
|
||||||
def make_ctocpp_function_impl_existing(clsname, name, func, impl):
|
def make_ctocpp_function_impl_existing(cls, name, func, impl, version):
|
||||||
notify(name + ' has manual edits')
|
clsname = None if cls is None else cls.get_name(version=version)
|
||||||
|
notify_name = name if clsname is None else '%sCToCpp::%s' % (clsname, name)
|
||||||
|
|
||||||
|
notify(notify_name + ' has manual edits')
|
||||||
|
|
||||||
# retrieve the C++ prototype parts
|
# retrieve the C++ prototype parts
|
||||||
parts = func.get_cpp_parts(True)
|
parts = func.get_cpp_parts(True)
|
||||||
|
|
||||||
changes = format_translation_changes(impl, parts)
|
changes = format_translation_changes(impl, parts)
|
||||||
if len(changes) > 0:
|
if len(changes) > 0:
|
||||||
notify(name + ' prototype changed')
|
notify(notify_name + ' prototype changed')
|
||||||
|
|
||||||
return make_ctocpp_impl_proto(clsname, name, func, parts)+'{'+ \
|
return make_ctocpp_impl_proto(clsname, name, func, parts)+'{'+ \
|
||||||
changes+impl['body']+'\n}\n\n'
|
changes+impl['body']+'\n}\n'
|
||||||
|
|
||||||
|
|
||||||
def make_ctocpp_function_impl_new(clsname, name, func, base_scoped):
|
def make_ctocpp_function_impl_new(cls, name, func, base_scoped, version,
|
||||||
|
version_finder):
|
||||||
# Special handling for the CefShutdown global function.
|
# Special handling for the CefShutdown global function.
|
||||||
is_cef_shutdown = name == 'CefShutdown' and isinstance(
|
is_cef_shutdown = name == 'CefShutdown' and isinstance(
|
||||||
func.parent, obj_header)
|
func.parent, obj_header)
|
||||||
|
|
||||||
# build the C++ prototype
|
clsname = None if cls is None else cls.get_name(version=version)
|
||||||
parts = func.get_cpp_parts(True)
|
notify_name = name if clsname is None else '%sCToCpp::%s' % (clsname, name)
|
||||||
result = make_ctocpp_impl_proto(clsname, name, func, parts) + ' {'
|
|
||||||
|
|
||||||
if isinstance(func.parent, obj_class) and \
|
|
||||||
not func.parent.has_attrib('no_debugct_check') and \
|
|
||||||
not base_scoped:
|
|
||||||
result += '\n shutdown_checker::AssertNotShutdown();\n'
|
|
||||||
|
|
||||||
if isinstance(func, obj_function_virtual):
|
|
||||||
# determine how the struct should be referenced
|
|
||||||
if clsname == func.parent.get_name():
|
|
||||||
result += '\n ' + get_capi_name(clsname,
|
|
||||||
True) + '* _struct = GetStruct();'
|
|
||||||
else:
|
|
||||||
result += '\n '+func.parent.get_capi_name()+'* _struct = reinterpret_cast<'+\
|
|
||||||
func.parent.get_capi_name()+'*>(GetStruct());'
|
|
||||||
|
|
||||||
invalid = []
|
invalid = []
|
||||||
|
|
||||||
@ -83,23 +73,43 @@ def make_ctocpp_function_impl_new(clsname, name, func, base_scoped):
|
|||||||
if len(retval_default) > 0:
|
if len(retval_default) > 0:
|
||||||
retval_default = ' ' + retval_default
|
retval_default = ' ' + retval_default
|
||||||
|
|
||||||
|
# build the C++ prototype
|
||||||
|
parts = func.get_cpp_parts(True)
|
||||||
|
result = make_ctocpp_impl_proto(clsname, name, func, parts) + ' {'
|
||||||
|
|
||||||
|
is_virtual = isinstance(func, obj_function_virtual)
|
||||||
|
|
||||||
|
if is_virtual and not version is None and not func.exists_at_version(version):
|
||||||
|
notreached = format_notreached(
|
||||||
|
True,
|
||||||
|
'" should not be called at version %d"' % version,
|
||||||
|
default_retval=retval_default.strip())
|
||||||
|
result += '\n // AUTO-GENERATED CONTENT' + \
|
||||||
|
'\n ' + notreached + \
|
||||||
|
'\n}\n'
|
||||||
|
return result
|
||||||
|
|
||||||
|
if isinstance(func.parent, obj_class) and \
|
||||||
|
not func.parent.has_attrib('no_debugct_check') and \
|
||||||
|
not base_scoped:
|
||||||
|
result += '\n shutdown_checker::AssertNotShutdown();\n'
|
||||||
|
|
||||||
|
if is_virtual:
|
||||||
|
# determine how the struct should be referenced
|
||||||
|
if cls.get_name() == func.parent.get_name():
|
||||||
|
result += '\n auto* _struct = GetStruct();'
|
||||||
|
else:
|
||||||
|
result += '\n auto* _struct = reinterpret_cast<'+\
|
||||||
|
func.parent.get_capi_name(version=version)+'*>(GetStruct());'
|
||||||
|
|
||||||
# add API hash check
|
# add API hash check
|
||||||
if func.has_attrib('api_hash_check'):
|
if func.has_attrib('api_hash_check'):
|
||||||
result += '\n const char* api_hash = cef_api_hash(0);'\
|
result += '\n const char* api_hash = cef_api_hash(CEF_API_VERSION, 0);'\
|
||||||
'\n if (strcmp(api_hash, CEF_API_HASH_PLATFORM)) {'\
|
'\n CHECK(!strcmp(api_hash, CEF_API_HASH_PLATFORM)) <<'\
|
||||||
'\n // The libcef API hash does not match the current header API hash.'\
|
'\n "API hashes for libcef and libcef_dll_wrapper do not match.";\n'
|
||||||
'\n DCHECK(false);'\
|
|
||||||
'\n return'+retval_default+';'\
|
|
||||||
'\n }\n'
|
|
||||||
|
|
||||||
if isinstance(func, obj_function_virtual):
|
|
||||||
# add the structure size check
|
|
||||||
result += '\n if (CEF_MEMBER_MISSING(_struct, ' + func.get_capi_name() + ')) {'\
|
|
||||||
'\n return' + retval_default + ';\n'\
|
|
||||||
'\n }\n'
|
|
||||||
|
|
||||||
if len(invalid) > 0:
|
if len(invalid) > 0:
|
||||||
notify(name + ' could not be autogenerated')
|
notify(notify_name + ' could not be autogenerated')
|
||||||
# code could not be auto-generated
|
# code could not be auto-generated
|
||||||
result += '\n // BEGIN DELETE BEFORE MODIFYING'
|
result += '\n // BEGIN DELETE BEFORE MODIFYING'
|
||||||
result += '\n // AUTO-GENERATED CONTENT'
|
result += '\n // AUTO-GENERATED CONTENT'
|
||||||
@ -209,38 +219,39 @@ def make_ctocpp_function_impl_new(clsname, name, func, base_scoped):
|
|||||||
params.append(arg_name + '.GetWritableStruct()')
|
params.append(arg_name + '.GetWritableStruct()')
|
||||||
elif arg_type == 'refptr_same':
|
elif arg_type == 'refptr_same':
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = arg.get_type().get_ptr_type()
|
||||||
params.append(ptr_class + 'CToCpp::Unwrap(' + arg_name + ')')
|
params.append(ptr_class + 'CToCpp_Unwrap(' + arg_name + ')')
|
||||||
elif arg_type == 'ownptr_same':
|
elif arg_type == 'ownptr_same':
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = arg.get_type().get_ptr_type()
|
||||||
params.append(ptr_class + 'CToCpp::UnwrapOwn(std::move(' + arg_name +
|
params.append(ptr_class + 'CToCpp_UnwrapOwn(std::move(' + arg_name + '))')
|
||||||
'))')
|
|
||||||
elif arg_type == 'rawptr_same':
|
elif arg_type == 'rawptr_same':
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = arg.get_type().get_ptr_type()
|
||||||
params.append(ptr_class + 'CToCpp::UnwrapRaw(' + arg_name + ')')
|
params.append(ptr_class + 'CToCpp_UnwrapRaw(' + arg_name + ')')
|
||||||
elif arg_type == 'refptr_diff':
|
elif arg_type == 'refptr_diff':
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = arg.get_type().get_ptr_type()
|
||||||
params.append(ptr_class + 'CppToC::Wrap(' + arg_name + ')')
|
params.append(ptr_class + 'CppToC_Wrap(' + arg_name + ')')
|
||||||
elif arg_type == 'ownptr_diff':
|
elif arg_type == 'ownptr_diff':
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = arg.get_type().get_ptr_type()
|
||||||
params.append(ptr_class + 'CppToC::WrapOwn(std::move(' + arg_name + '))')
|
params.append(ptr_class + 'CppToC_WrapOwn(std::move(' + arg_name + '))')
|
||||||
elif arg_type == 'rawptr_diff':
|
elif arg_type == 'rawptr_diff':
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = arg.get_type().get_ptr_type()
|
||||||
result += comment+\
|
result += comment+\
|
||||||
'\n CefOwnPtr<'+ptr_class+'CppToC> '+arg_name+'Ptr('+ptr_class+'CppToC::WrapRaw('+arg_name+'));'
|
'\n auto ['+arg_name+'Ptr, '+arg_name+'Struct] = '+ptr_class+'CppToC_WrapRaw('+arg_name+');'
|
||||||
params.append(arg_name + 'Ptr->GetStruct()')
|
params.append(arg_name + 'Struct')
|
||||||
elif arg_type == 'refptr_same_byref' or arg_type == 'refptr_diff_byref':
|
elif arg_type == 'refptr_same_byref' or arg_type == 'refptr_diff_byref':
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = arg.get_type().get_ptr_type()
|
||||||
ptr_struct = arg.get_type().get_result_ptr_type_root()
|
ptr_struct = arg.get_type().get_result_ptr_type_root()
|
||||||
|
if not version_finder is None:
|
||||||
|
ptr_struct = version_finder(ptr_struct)
|
||||||
if arg_type == 'refptr_same_byref':
|
if arg_type == 'refptr_same_byref':
|
||||||
assign = ptr_class + 'CToCpp::Unwrap(' + arg_name + ')'
|
assign = ptr_class + 'CToCpp_Unwrap(' + arg_name + ')'
|
||||||
else:
|
else:
|
||||||
assign = ptr_class + 'CppToC::Wrap(' + arg_name + ')'
|
assign = ptr_class + 'CppToC_Wrap(' + arg_name + ')'
|
||||||
result += comment+\
|
result += comment+\
|
||||||
'\n '+ptr_struct+'* '+arg_name+'Struct = NULL;'\
|
'\n '+ptr_struct+'* '+arg_name+'Struct = NULL;'\
|
||||||
'\n if ('+arg_name+'.get()) {'\
|
'\n if ('+arg_name+'.get()) {'\
|
||||||
'\n '+arg_name+'Struct = '+assign+';'\
|
'\n '+arg_name+'Struct = '+assign+';'\
|
||||||
'\n }'\
|
'\n }'\
|
||||||
'\n '+ptr_struct+'* '+arg_name+'Orig = '+arg_name+'Struct;'
|
'\n auto* '+arg_name+'Orig = '+arg_name+'Struct;'
|
||||||
params.append('&' + arg_name + 'Struct')
|
params.append('&' + arg_name + 'Struct')
|
||||||
elif arg_type == 'string_vec_byref' or arg_type == 'string_vec_byref_const':
|
elif arg_type == 'string_vec_byref' or arg_type == 'string_vec_byref_const':
|
||||||
result += comment+\
|
result += comment+\
|
||||||
@ -270,12 +281,15 @@ def make_ctocpp_function_impl_new(clsname, name, func, base_scoped):
|
|||||||
arg_type == 'refptr_vec_same_byref' or arg_type == 'refptr_vec_diff_byref':
|
arg_type == 'refptr_vec_same_byref' or arg_type == 'refptr_vec_diff_byref':
|
||||||
count_func = arg.get_attrib_count_func()
|
count_func = arg.get_attrib_count_func()
|
||||||
vec_type = arg.get_type().get_result_vector_type_root()
|
vec_type = arg.get_type().get_result_vector_type_root()
|
||||||
|
if not version_finder is None:
|
||||||
|
vec_type = version_finder(vec_type)
|
||||||
|
|
||||||
if arg_type == 'refptr_vec_same_byref':
|
if arg_type == 'refptr_vec_same_byref':
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = arg.get_type().get_ptr_type()
|
||||||
assign = ptr_class + 'CToCpp::Unwrap(' + arg_name + '[i])'
|
assign = ptr_class + 'CToCpp_Unwrap(' + arg_name + '[i])'
|
||||||
elif arg_type == 'refptr_vec_diff_byref':
|
elif arg_type == 'refptr_vec_diff_byref':
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = arg.get_type().get_ptr_type()
|
||||||
assign = ptr_class + 'CppToC::Wrap(' + arg_name + '[i])'
|
assign = ptr_class + 'CppToC_Wrap(' + arg_name + '[i])'
|
||||||
else:
|
else:
|
||||||
assign = arg_name + '[i]'
|
assign = arg_name + '[i]'
|
||||||
result += comment+\
|
result += comment+\
|
||||||
@ -301,18 +315,21 @@ def make_ctocpp_function_impl_new(clsname, name, func, base_scoped):
|
|||||||
arg_type == 'rawptr_vec_same_byref_const' or arg_type == 'rawptr_vec_diff_byref_const':
|
arg_type == 'rawptr_vec_same_byref_const' or arg_type == 'rawptr_vec_diff_byref_const':
|
||||||
count_func = arg.get_attrib_count_func()
|
count_func = arg.get_attrib_count_func()
|
||||||
vec_type = arg.get_type().get_result_vector_type_root()
|
vec_type = arg.get_type().get_result_vector_type_root()
|
||||||
|
if not version_finder is None:
|
||||||
|
vec_type = version_finder(vec_type)
|
||||||
|
|
||||||
if arg_type == 'simple_vec_byref_const' or arg_type == 'bool_vec_byref_const':
|
if arg_type == 'simple_vec_byref_const' or arg_type == 'bool_vec_byref_const':
|
||||||
assign = arg_name + '[i]'
|
assign = arg_name + '[i]'
|
||||||
else:
|
else:
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = arg.get_type().get_ptr_type()
|
||||||
if arg_type == 'refptr_vec_same_byref_const':
|
if arg_type == 'refptr_vec_same_byref_const':
|
||||||
assign = ptr_class + 'CToCpp::Unwrap(' + arg_name + '[i])'
|
assign = ptr_class + 'CToCpp_Unwrap(' + arg_name + '[i])'
|
||||||
elif arg_type == 'refptr_vec_diff_byref_const':
|
elif arg_type == 'refptr_vec_diff_byref_const':
|
||||||
assign = ptr_class + 'CppToC::Wrap(' + arg_name + '[i])'
|
assign = ptr_class + 'CppToC_Wrap(' + arg_name + '[i])'
|
||||||
elif arg_type == 'rawptr_vec_same_byref_const':
|
elif arg_type == 'rawptr_vec_same_byref_const':
|
||||||
assign = ptr_class + 'CToCpp::UnwrapRaw(' + arg_name + '[i])'
|
assign = ptr_class + 'CToCpp_UnwrapRaw(' + arg_name + '[i])'
|
||||||
elif arg_type == 'rawptr_vec_diff_byref_const':
|
elif arg_type == 'rawptr_vec_diff_byref_const':
|
||||||
assign = ptr_class + 'CppToC::WrapRaw(' + arg_name + '[i]).release()->GetStruct()'
|
assign = ptr_class + 'CppToC_WrapRawAndRelease(' + arg_name + '[i])'
|
||||||
result += comment+\
|
result += comment+\
|
||||||
'\n const size_t '+arg_name+'Count = '+arg_name+'.size();'\
|
'\n const size_t '+arg_name+'Count = '+arg_name+'.size();'\
|
||||||
'\n '+vec_type+'* '+arg_name+'List = NULL;'\
|
'\n '+vec_type+'* '+arg_name+'List = NULL;'\
|
||||||
@ -348,8 +365,7 @@ def make_ctocpp_function_impl_new(clsname, name, func, base_scoped):
|
|||||||
result += 'cef_string_userfree_t'
|
result += 'cef_string_userfree_t'
|
||||||
elif retval_type == 'refptr_same' or retval_type == 'refptr_diff' or \
|
elif retval_type == 'refptr_same' or retval_type == 'refptr_diff' or \
|
||||||
retval_type == 'ownptr_same' or retval_type == 'ownptr_diff':
|
retval_type == 'ownptr_same' or retval_type == 'ownptr_diff':
|
||||||
ptr_struct = retval.get_type().get_result_ptr_type_root()
|
result += 'auto*'
|
||||||
result += ptr_struct + '*'
|
|
||||||
else:
|
else:
|
||||||
raise Exception('Unsupported return type %s in %s' % (retval_type, name))
|
raise Exception('Unsupported return type %s in %s' % (retval_type, name))
|
||||||
|
|
||||||
@ -390,11 +406,10 @@ def make_ctocpp_function_impl_new(clsname, name, func, base_scoped):
|
|||||||
'\n }'
|
'\n }'
|
||||||
elif arg_type == 'refptr_same_byref' or arg_type == 'refptr_diff_byref':
|
elif arg_type == 'refptr_same_byref' or arg_type == 'refptr_diff_byref':
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = arg.get_type().get_ptr_type()
|
||||||
ptr_struct = arg.get_type().get_result_ptr_type_root()
|
|
||||||
if arg_type == 'refptr_same_byref':
|
if arg_type == 'refptr_same_byref':
|
||||||
assign = ptr_class + 'CToCpp::Wrap(' + arg_name + 'Struct)'
|
assign = ptr_class + 'CToCpp_Wrap(' + arg_name + 'Struct)'
|
||||||
else:
|
else:
|
||||||
assign = ptr_class + 'CppToC::Unwrap(' + arg_name + 'Struct)'
|
assign = ptr_class + 'CppToC_Unwrap(' + arg_name + 'Struct)'
|
||||||
result += comment+\
|
result += comment+\
|
||||||
'\n if ('+arg_name+'Struct) {'\
|
'\n if ('+arg_name+'Struct) {'\
|
||||||
'\n if ('+arg_name+'Struct != '+arg_name+'Orig) {'\
|
'\n if ('+arg_name+'Struct != '+arg_name+'Orig) {'\
|
||||||
@ -442,13 +457,13 @@ def make_ctocpp_function_impl_new(clsname, name, func, base_scoped):
|
|||||||
elif arg_type == 'simple_vec_byref' or arg_type == 'bool_vec_byref' or \
|
elif arg_type == 'simple_vec_byref' or arg_type == 'bool_vec_byref' or \
|
||||||
arg_type == 'refptr_vec_same_byref' or arg_type == 'refptr_vec_diff_byref':
|
arg_type == 'refptr_vec_same_byref' or arg_type == 'refptr_vec_diff_byref':
|
||||||
count_func = arg.get_attrib_count_func()
|
count_func = arg.get_attrib_count_func()
|
||||||
vec_type = arg.get_type().get_result_vector_type_root()
|
|
||||||
if arg_type == 'refptr_vec_same_byref':
|
if arg_type == 'refptr_vec_same_byref':
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = arg.get_type().get_ptr_type()
|
||||||
assign = ptr_class + 'CToCpp::Wrap(' + arg_name + 'List[i])'
|
assign = ptr_class + 'CToCpp_Wrap(' + arg_name + 'List[i])'
|
||||||
elif arg_type == 'refptr_vec_diff_byref':
|
elif arg_type == 'refptr_vec_diff_byref':
|
||||||
ptr_class = arg.get_type().get_ptr_type()
|
ptr_class = arg.get_type().get_ptr_type()
|
||||||
assign = ptr_class + 'CppToC::Unwrap(' + arg_name + 'List[i])'
|
assign = ptr_class + 'CppToC_Unwrap(' + arg_name + 'List[i])'
|
||||||
elif arg_type == 'bool_vec_byref':
|
elif arg_type == 'bool_vec_byref':
|
||||||
assign = arg_name + 'List[i]?true:false'
|
assign = arg_name + 'List[i]?true:false'
|
||||||
else:
|
else:
|
||||||
@ -468,7 +483,7 @@ def make_ctocpp_function_impl_new(clsname, name, func, base_scoped):
|
|||||||
if arg_type == 'rawptr_vec_diff_byref_const':
|
if arg_type == 'rawptr_vec_diff_byref_const':
|
||||||
result += '\n if ('+arg_name+'Count > 0) {'\
|
result += '\n if ('+arg_name+'Count > 0) {'\
|
||||||
'\n for (size_t i = 0; i < '+arg_name+'Count; ++i) {'\
|
'\n for (size_t i = 0; i < '+arg_name+'Count; ++i) {'\
|
||||||
'\n delete '+ptr_class+'CppToC::GetWrapper('+arg_name+'List[i]);'\
|
'\n delete '+ptr_class+'CppToC_GetWrapper('+arg_name+'List[i]);'\
|
||||||
'\n }'\
|
'\n }'\
|
||||||
'\n }'
|
'\n }'
|
||||||
result += '\n if ('+arg_name+'List) {'\
|
result += '\n if ('+arg_name+'List) {'\
|
||||||
@ -497,43 +512,59 @@ def make_ctocpp_function_impl_new(clsname, name, func, base_scoped):
|
|||||||
'\n return _retvalStr;'
|
'\n return _retvalStr;'
|
||||||
elif retval_type == 'refptr_same' or retval_type == 'ownptr_same':
|
elif retval_type == 'refptr_same' or retval_type == 'ownptr_same':
|
||||||
ptr_class = retval.get_type().get_ptr_type()
|
ptr_class = retval.get_type().get_ptr_type()
|
||||||
result += '\n return ' + ptr_class + 'CToCpp::Wrap(_retval);'
|
result += '\n return ' + ptr_class + 'CToCpp_Wrap(_retval);'
|
||||||
elif retval_type == 'refptr_diff':
|
elif retval_type == 'refptr_diff':
|
||||||
ptr_class = retval.get_type().get_ptr_type()
|
ptr_class = retval.get_type().get_ptr_type()
|
||||||
result += '\n return ' + ptr_class + 'CppToC::Unwrap(_retval);'
|
result += '\n return ' + ptr_class + 'CppToC_Unwrap(_retval);'
|
||||||
elif retval_type == 'ownptr_diff':
|
elif retval_type == 'ownptr_diff':
|
||||||
ptr_class = retval.get_type().get_ptr_type()
|
ptr_class = retval.get_type().get_ptr_type()
|
||||||
result += '\n return ' + ptr_class + 'CppToC::UnwrapOwn(_retval);'
|
result += '\n return ' + ptr_class + 'CppToC_UnwrapOwn(_retval);'
|
||||||
else:
|
else:
|
||||||
raise Exception('Unsupported return type %s in %s' % (retval_type, name))
|
raise Exception('Unsupported return type %s in %s' % (retval_type, name))
|
||||||
|
|
||||||
if len(result) != result_len:
|
if len(result) != result_len:
|
||||||
result += '\n'
|
result += '\n'
|
||||||
|
|
||||||
result += '}\n\n'
|
result += '}\n'
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def make_ctocpp_function_impl(clsname, funcs, existing, base_scoped):
|
def make_ctocpp_function_impl(cls, funcs, existing, base_scoped, version,
|
||||||
|
version_finder):
|
||||||
impl = ''
|
impl = ''
|
||||||
|
|
||||||
|
customized = False
|
||||||
|
|
||||||
for func in funcs:
|
for func in funcs:
|
||||||
name = func.get_name()
|
name = func.get_name()
|
||||||
value = get_next_function_impl(existing, name)
|
value = get_next_function_impl(existing, name)
|
||||||
|
|
||||||
|
if version is None:
|
||||||
|
pre, post = get_version_surround(func, long=True)
|
||||||
|
else:
|
||||||
|
pre = post = ''
|
||||||
|
|
||||||
if not value is None \
|
if not value is None \
|
||||||
and value['body'].find('// AUTO-GENERATED CONTENT') < 0:
|
and value['body'].find('// AUTO-GENERATED CONTENT') < 0:
|
||||||
# an implementation exists that was not auto-generated
|
# an implementation exists that was not auto-generated
|
||||||
impl += make_ctocpp_function_impl_existing(clsname, name, func, value)
|
customized = True
|
||||||
|
impl += pre + make_ctocpp_function_impl_existing(cls, name, func, value,
|
||||||
|
version) + post + '\n'
|
||||||
else:
|
else:
|
||||||
impl += make_ctocpp_function_impl_new(clsname, name, func, base_scoped)
|
impl += pre + make_ctocpp_function_impl_new(
|
||||||
|
cls, name, func, base_scoped, version, version_finder) + post + '\n'
|
||||||
|
|
||||||
return impl
|
if not customized and impl.find('// COULD NOT IMPLEMENT') >= 0:
|
||||||
|
customized = True
|
||||||
|
|
||||||
|
return (impl, customized)
|
||||||
|
|
||||||
|
|
||||||
def make_ctocpp_virtual_function_impl(header, cls, existing, base_scoped):
|
def make_ctocpp_virtual_function_impl(header, cls, existing, base_scoped,
|
||||||
impl = make_ctocpp_function_impl(cls.get_name(),
|
version, version_finder):
|
||||||
cls.get_virtual_funcs(), existing,
|
impl, customized = make_ctocpp_function_impl(
|
||||||
base_scoped)
|
cls,
|
||||||
|
cls.get_virtual_funcs(), existing, base_scoped, version, version_finder)
|
||||||
|
|
||||||
cur_cls = cls
|
cur_cls = cls
|
||||||
while True:
|
while True:
|
||||||
@ -544,18 +575,28 @@ def make_ctocpp_virtual_function_impl(header, cls, existing, base_scoped):
|
|||||||
parent_cls = header.get_class(parent_name)
|
parent_cls = header.get_class(parent_name)
|
||||||
if parent_cls is None:
|
if parent_cls is None:
|
||||||
raise Exception('Class does not exist: ' + parent_name)
|
raise Exception('Class does not exist: ' + parent_name)
|
||||||
impl += make_ctocpp_function_impl(cls.get_name(),
|
pimpl, pcustomized = make_ctocpp_function_impl(
|
||||||
parent_cls.get_virtual_funcs(),
|
cls,
|
||||||
existing, base_scoped)
|
parent_cls.get_virtual_funcs(), existing, base_scoped, version,
|
||||||
|
version_finder)
|
||||||
|
impl += pimpl
|
||||||
|
if pcustomized and not customized:
|
||||||
|
customized = True
|
||||||
cur_cls = header.get_class(parent_name)
|
cur_cls = header.get_class(parent_name)
|
||||||
|
|
||||||
return impl
|
return (impl, customized)
|
||||||
|
|
||||||
|
|
||||||
def make_ctocpp_unwrap_derived(header, cls, base_scoped):
|
def make_ctocpp_unwrap_derived(header, cls, base_scoped, version):
|
||||||
# identify all classes that derive from cls
|
# identify all classes that derive from cls
|
||||||
derived_classes = []
|
derived_classes = []
|
||||||
clsname = cls.get_name()
|
clsname = cls.get_name()
|
||||||
|
|
||||||
|
if version is None:
|
||||||
|
capiname = cls.get_capi_name()
|
||||||
|
else:
|
||||||
|
capiname = cls.get_capi_name(version=version)
|
||||||
|
|
||||||
allclasses = header.get_classes()
|
allclasses = header.get_classes()
|
||||||
for cur_cls in allclasses:
|
for cur_cls in allclasses:
|
||||||
if cur_cls.get_name() == clsname:
|
if cur_cls.get_name() == clsname:
|
||||||
@ -568,34 +609,156 @@ def make_ctocpp_unwrap_derived(header, cls, base_scoped):
|
|||||||
if base_scoped:
|
if base_scoped:
|
||||||
impl = ['', '']
|
impl = ['', '']
|
||||||
for clsname in derived_classes:
|
for clsname in derived_classes:
|
||||||
impl[0] += ' if (type == '+get_wrapper_type_enum(clsname)+') {\n'+\
|
derived_cls = header.get_class(clsname)
|
||||||
' return reinterpret_cast<'+get_capi_name(cls.get_name(), True)+'*>('+\
|
if version is None:
|
||||||
clsname+'CToCpp::UnwrapOwn(CefOwnPtr<'+clsname+'>(reinterpret_cast<'+clsname+'*>(c.release()))));\n'+\
|
pre, post = get_version_surround(derived_cls)
|
||||||
' }\n'
|
else:
|
||||||
impl[1] += ' if (type == '+get_wrapper_type_enum(clsname)+') {\n'+\
|
if not derived_cls.exists_at_version(version):
|
||||||
' return reinterpret_cast<'+get_capi_name(cls.get_name(), True)+'*>('+\
|
continue
|
||||||
clsname+'CToCpp::UnwrapRaw(CefRawPtr<'+clsname+'>(reinterpret_cast<'+clsname+'*>(c))));\n'+\
|
pre = post = ''
|
||||||
' }\n'
|
|
||||||
|
impl[0] += pre + ' if (type == '+get_wrapper_type_enum(clsname)+') {\n'+\
|
||||||
|
' return reinterpret_cast<'+capiname+'*>('+\
|
||||||
|
clsname+'CToCpp_UnwrapOwn(CefOwnPtr<'+clsname+'>(reinterpret_cast<'+clsname+'*>(c.release()))));\n'+\
|
||||||
|
' }\n' + post
|
||||||
|
impl[1] += pre + ' if (type == '+get_wrapper_type_enum(clsname)+') {\n'+\
|
||||||
|
' return reinterpret_cast<'+capiname+'*>('+\
|
||||||
|
clsname+'CToCpp_UnwrapRaw(CefRawPtr<'+clsname+'>(reinterpret_cast<'+clsname+'*>(c))));\n'+\
|
||||||
|
' }\n' + post
|
||||||
else:
|
else:
|
||||||
impl = ''
|
impl = ''
|
||||||
for clsname in derived_classes:
|
for clsname in derived_classes:
|
||||||
impl += ' if (type == '+get_wrapper_type_enum(clsname)+') {\n'+\
|
derived_cls = header.get_class(clsname)
|
||||||
' return reinterpret_cast<'+get_capi_name(cls.get_name(), True)+'*>('+\
|
if version is None:
|
||||||
clsname+'CToCpp::Unwrap(reinterpret_cast<'+clsname+'*>(c)));\n'+\
|
pre, post = get_version_surround(derived_cls)
|
||||||
' }\n'
|
else:
|
||||||
|
if not derived_cls.exists_at_version(version):
|
||||||
|
continue
|
||||||
|
pre = post = ''
|
||||||
|
|
||||||
|
impl += pre + ' if (type == '+get_wrapper_type_enum(clsname)+') {\n'+\
|
||||||
|
' return reinterpret_cast<'+capiname+'*>('+\
|
||||||
|
clsname+'CToCpp_Unwrap(reinterpret_cast<'+clsname+'*>(c)));\n'+\
|
||||||
|
' }\n' + post
|
||||||
return impl
|
return impl
|
||||||
|
|
||||||
|
|
||||||
|
def make_ctocpp_version_wrappers(header, cls, base_scoped, versions):
|
||||||
|
assert len(versions) > 0
|
||||||
|
|
||||||
|
clsname = cls.get_name()
|
||||||
|
typename = clsname + 'CToCpp'
|
||||||
|
structname = cls.get_capi_name(version=versions[0])
|
||||||
|
|
||||||
|
rversions = sorted(versions, reverse=True)
|
||||||
|
|
||||||
|
notreached = format_notreached(
|
||||||
|
True,
|
||||||
|
'" called with invalid version " << version',
|
||||||
|
default_retval='nullptr')
|
||||||
|
|
||||||
|
impl = ''
|
||||||
|
|
||||||
|
if base_scoped:
|
||||||
|
impl += 'CefOwnPtr<' + clsname + '> ' + typename + '_Wrap(' + structname + '* s) {\n' + \
|
||||||
|
' const int version = cef_api_version();\n'
|
||||||
|
|
||||||
|
for version in rversions:
|
||||||
|
vstr = str(version)
|
||||||
|
impl += ' if (version >= ' + vstr + ') {\n'
|
||||||
|
if versions[0] == version:
|
||||||
|
impl += ' return ' + clsname + '_' + vstr + '_CToCpp::Wrap(s);\n'
|
||||||
|
else:
|
||||||
|
impl += ' return ' + clsname + '_' + vstr + '_CToCpp::Wrap(reinterpret_cast<' + cls.get_capi_name(
|
||||||
|
version) + '*>(s));\n'
|
||||||
|
impl += ' }\n'
|
||||||
|
|
||||||
|
impl += ' ' + notreached + '\n'+ \
|
||||||
|
'}\n\n' + \
|
||||||
|
structname + '* ' + typename + '_UnwrapOwn(CefOwnPtr<' + clsname + '> c) {\n' + \
|
||||||
|
' const int version = cef_api_version();\n'
|
||||||
|
|
||||||
|
for version in rversions:
|
||||||
|
vstr = str(version)
|
||||||
|
impl += ' if (version >= ' + vstr + ') {\n'
|
||||||
|
if versions[0] == version:
|
||||||
|
impl += ' return ' + clsname + '_' + vstr + '_CToCpp::UnwrapOwn(std::move(c));\n'
|
||||||
|
else:
|
||||||
|
impl += ' return reinterpret_cast<' + structname + '*>(' + clsname + '_' + vstr + '_CToCpp::UnwrapOwn(std::move(c)));\n'
|
||||||
|
impl += ' }\n'
|
||||||
|
|
||||||
|
impl += ' ' + notreached + '\n'+ \
|
||||||
|
'}\n\n' + \
|
||||||
|
structname + '* ' + typename + '_UnwrapRaw(CefRawPtr<' + clsname + '> c) {\n' + \
|
||||||
|
' const int version = cef_api_version();\n'
|
||||||
|
|
||||||
|
for version in rversions:
|
||||||
|
vstr = str(version)
|
||||||
|
impl += ' if (version >= ' + vstr + ') {\n'
|
||||||
|
if versions[0] == version:
|
||||||
|
impl += ' return ' + clsname + '_' + vstr + '_CToCpp::UnwrapRaw(std::move(c));\n'
|
||||||
|
else:
|
||||||
|
impl += ' return reinterpret_cast<' + structname + '*>(' + clsname + '_' + vstr + '_CToCpp::UnwrapRaw(std::move(c)));\n'
|
||||||
|
impl += ' }\n'
|
||||||
|
|
||||||
|
impl += ' ' + notreached + '\n'+ \
|
||||||
|
'}\n'
|
||||||
|
else:
|
||||||
|
impl += 'CefRefPtr<' + clsname + '> ' + typename + '_Wrap(' + structname + '* s) {\n' + \
|
||||||
|
' const int version = cef_api_version();\n'
|
||||||
|
|
||||||
|
for version in rversions:
|
||||||
|
vstr = str(version)
|
||||||
|
impl += ' if (version >= ' + vstr + ') {\n'
|
||||||
|
if versions[0] == version:
|
||||||
|
impl += ' return ' + clsname + '_' + vstr + '_CToCpp::Wrap(s);\n'
|
||||||
|
else:
|
||||||
|
impl += ' return ' + clsname + '_' + vstr + '_CToCpp::Wrap(reinterpret_cast<' + cls.get_capi_name(
|
||||||
|
version) + '*>(s));\n'
|
||||||
|
impl += ' }\n'
|
||||||
|
|
||||||
|
impl += ' ' + notreached + '\n'+ \
|
||||||
|
'}\n\n' + \
|
||||||
|
structname + '* ' + typename + '_Unwrap(CefRefPtr<' + clsname + '> c) {\n' + \
|
||||||
|
' const int version = cef_api_version();\n'
|
||||||
|
|
||||||
|
for version in rversions:
|
||||||
|
vstr = str(version)
|
||||||
|
impl += ' if (version >= ' + vstr + ') {\n'
|
||||||
|
if versions[0] == version:
|
||||||
|
impl += ' return ' + clsname + '_' + vstr + '_CToCpp::Unwrap(c);\n'
|
||||||
|
else:
|
||||||
|
impl += ' return reinterpret_cast<' + structname + '*>(' + clsname + '_' + vstr + '_CToCpp::Unwrap(c));\n'
|
||||||
|
impl += ' }\n'
|
||||||
|
|
||||||
|
impl += ' ' + notreached + '\n'+ \
|
||||||
|
'}\n'
|
||||||
|
|
||||||
|
return impl + '\n'
|
||||||
|
|
||||||
|
|
||||||
|
def _version_finder(header, version, name):
|
||||||
|
assert version is None or isinstance(version, int), version
|
||||||
|
|
||||||
|
# normalize ptr values
|
||||||
|
if name[-1] == '*':
|
||||||
|
name = name[0:-1]
|
||||||
|
suffix = '*'
|
||||||
|
else:
|
||||||
|
suffix = ''
|
||||||
|
|
||||||
|
cls = header.get_capi_class(name)
|
||||||
|
if not cls is None:
|
||||||
|
name = cls.get_capi_name(first_version=True)
|
||||||
|
|
||||||
|
return name + suffix
|
||||||
|
|
||||||
|
|
||||||
def make_ctocpp_class_impl(header, clsname, impl):
|
def make_ctocpp_class_impl(header, clsname, impl):
|
||||||
cls = header.get_class(clsname)
|
cls = header.get_class(clsname)
|
||||||
if cls is None:
|
if cls is None:
|
||||||
raise Exception('Class does not exist: ' + clsname)
|
raise Exception('Class does not exist: ' + clsname)
|
||||||
|
|
||||||
capiname = cls.get_capi_name()
|
|
||||||
|
|
||||||
# retrieve the existing virtual function implementations
|
|
||||||
existing = get_function_impls(impl, clsname + 'CToCpp::')
|
|
||||||
|
|
||||||
base_class_name = header.get_base_class_name(clsname)
|
base_class_name = header.get_base_class_name(clsname)
|
||||||
base_scoped = True if base_class_name == 'CefBaseScoped' else False
|
base_scoped = True if base_class_name == 'CefBaseScoped' else False
|
||||||
if base_scoped:
|
if base_scoped:
|
||||||
@ -603,75 +766,135 @@ def make_ctocpp_class_impl(header, clsname, impl):
|
|||||||
else:
|
else:
|
||||||
template_class = 'CefCToCppRefCounted'
|
template_class = 'CefCToCppRefCounted'
|
||||||
|
|
||||||
# generate virtual functions
|
with_versions = cls.is_client_side()
|
||||||
virtualimpl = make_ctocpp_virtual_function_impl(header, cls, existing,
|
versions = list(cls.get_all_versions()) if with_versions else (None,)
|
||||||
base_scoped)
|
|
||||||
if len(virtualimpl) > 0:
|
|
||||||
virtualimpl = '\n// VIRTUAL METHODS - Body may be edited by hand.\n\n' + virtualimpl
|
|
||||||
|
|
||||||
# retrieve the existing static function implementations
|
# retrieve the existing static function implementations
|
||||||
existing = get_function_impls(impl, clsname + '::')
|
existing_static = get_function_impls(impl, clsname + '::')
|
||||||
|
|
||||||
|
staticout = virtualout = ''
|
||||||
|
customized = False
|
||||||
|
first = True
|
||||||
|
idx = 0
|
||||||
|
|
||||||
|
for version in versions:
|
||||||
|
version_finder = functools.partial(_version_finder, header,
|
||||||
|
version) if with_versions else None
|
||||||
|
|
||||||
|
if first:
|
||||||
|
first = False
|
||||||
|
|
||||||
# generate static functions
|
# generate static functions
|
||||||
staticimpl = make_ctocpp_function_impl(clsname,
|
staticimpl, scustomized = make_ctocpp_function_impl(
|
||||||
cls.get_static_funcs(), existing,
|
cls,
|
||||||
base_scoped)
|
cls.get_static_funcs(), existing_static, base_scoped, version,
|
||||||
|
version_finder)
|
||||||
if len(staticimpl) > 0:
|
if len(staticimpl) > 0:
|
||||||
staticimpl = '\n// STATIC METHODS - Body may be edited by hand.\n\n' + staticimpl
|
staticout += '\n// STATIC METHODS - Body may be edited by hand.\n\n' + staticimpl
|
||||||
|
if scustomized:
|
||||||
|
customized = True
|
||||||
|
|
||||||
resultingimpl = staticimpl + virtualimpl
|
if len(versions) > 1:
|
||||||
|
staticout += '// HELPER FUNCTIONS - Do not edit by hand.\n\n'
|
||||||
|
staticout += make_ctocpp_version_wrappers(header, cls, base_scoped,
|
||||||
|
versions)
|
||||||
|
|
||||||
|
comment = '' if version is None else (' FOR VERSION %d' % version)
|
||||||
|
typename = cls.get_name(version=version) + 'CToCpp'
|
||||||
|
|
||||||
|
# retrieve the existing virtual function implementations
|
||||||
|
existing_virtual = get_function_impls(impl, typename + '::')
|
||||||
|
|
||||||
|
# generate virtual functions
|
||||||
|
virtualimpl, vcustomized = make_ctocpp_virtual_function_impl(
|
||||||
|
header, cls, existing_virtual, base_scoped, version, version_finder)
|
||||||
|
if len(virtualimpl) > 0:
|
||||||
|
virtualout += '\n// VIRTUAL METHODS' + comment + ' - Body may be edited by hand.\n\n' + virtualimpl
|
||||||
|
if vcustomized:
|
||||||
|
customized = True
|
||||||
|
|
||||||
# any derived classes can be unwrapped
|
# any derived classes can be unwrapped
|
||||||
unwrapderived = make_ctocpp_unwrap_derived(header, cls, base_scoped)
|
unwrapderived = make_ctocpp_unwrap_derived(header, cls, base_scoped,
|
||||||
|
version)
|
||||||
|
|
||||||
const = '// CONSTRUCTOR - Do not edit by hand.\n\n'+ \
|
capiname = cls.get_capi_name(version=version)
|
||||||
clsname+'CToCpp::'+clsname+'CToCpp() {\n'+ \
|
|
||||||
'}\n\n'+ \
|
const = '// CONSTRUCTOR' + comment + ' - Do not edit by hand.\n\n'+ \
|
||||||
'// DESTRUCTOR - Do not edit by hand.\n\n'+ \
|
typename+'::'+typename+'() {\n'
|
||||||
clsname+'CToCpp::~'+clsname+'CToCpp() {\n'
|
|
||||||
|
if not version is None:
|
||||||
|
if idx < len(versions) - 1:
|
||||||
|
condition = 'version < %d || version >= %d' % (version, versions[idx
|
||||||
|
+ 1])
|
||||||
|
else:
|
||||||
|
condition = 'version < %d' % version
|
||||||
|
|
||||||
|
const += ' const int version = cef_api_version();\n' + \
|
||||||
|
' LOG_IF(FATAL, ' + condition + ') << __func__ << " called with invalid version " << version;\n'
|
||||||
|
|
||||||
|
const += '}\n\n'+ \
|
||||||
|
'// DESTRUCTOR' + comment + ' - Do not edit by hand.\n\n'+ \
|
||||||
|
typename+'::~'+typename+'() {\n'
|
||||||
|
|
||||||
if not cls.has_attrib('no_debugct_check') and not base_scoped:
|
if not cls.has_attrib('no_debugct_check') and not base_scoped:
|
||||||
const += ' shutdown_checker::AssertNotShutdown();\n'
|
const += ' shutdown_checker::AssertNotShutdown();\n'
|
||||||
|
|
||||||
const += '}\n\n'
|
const += '}\n\n'
|
||||||
|
|
||||||
# determine what includes are required by identifying what translation
|
parent_sig = template_class + '<' + typename + ', ' + clsname + ', ' + capiname + '>'
|
||||||
# classes are being used
|
notreached = format_notreached(
|
||||||
includes = format_translation_includes(header, const + resultingimpl +
|
with_versions,
|
||||||
(unwrapderived[0]
|
'" called with unexpected class type " << type',
|
||||||
if base_scoped else unwrapderived))
|
default_retval='nullptr')
|
||||||
|
|
||||||
# build the final output
|
|
||||||
result = get_copyright()
|
|
||||||
|
|
||||||
result += includes + '\n' + resultingimpl + '\n'
|
|
||||||
|
|
||||||
parent_sig = template_class + '<' + clsname + 'CToCpp, ' + clsname + ', ' + capiname + '>'
|
|
||||||
|
|
||||||
if base_scoped:
|
if base_scoped:
|
||||||
const += 'template<> '+capiname+'* '+parent_sig+'::UnwrapDerivedOwn(CefWrapperType type, CefOwnPtr<'+clsname+'> c) {\n'+ \
|
const += 'template<> '+capiname+'* '+parent_sig+'::UnwrapDerivedOwn(CefWrapperType type, CefOwnPtr<'+clsname+'> c) {\n'+ \
|
||||||
unwrapderived[0] + \
|
unwrapderived[0] + \
|
||||||
' DCHECK(false) << "Unexpected class type: " << type;\n'+ \
|
' ' + notreached + '\n'+ \
|
||||||
' return nullptr;\n'+ \
|
|
||||||
'}\n\n' + \
|
'}\n\n' + \
|
||||||
'template<> '+capiname+'* '+parent_sig+'::UnwrapDerivedRaw(CefWrapperType type, CefRawPtr<'+clsname+'> c) {\n'+ \
|
'template<> '+capiname+'* '+parent_sig+'::UnwrapDerivedRaw(CefWrapperType type, CefRawPtr<'+clsname+'> c) {\n'+ \
|
||||||
unwrapderived[1] + \
|
unwrapderived[1] + \
|
||||||
' DCHECK(false) << "Unexpected class type: " << type;\n'+ \
|
' ' + notreached + '\n'+ \
|
||||||
' return nullptr;\n'+ \
|
|
||||||
'}\n\n'
|
'}\n\n'
|
||||||
else:
|
else:
|
||||||
const += 'template<> '+capiname+'* '+parent_sig+'::UnwrapDerived(CefWrapperType type, '+clsname+'* c) {\n'+ \
|
const += 'template<> '+capiname+'* '+parent_sig+'::UnwrapDerived(CefWrapperType type, '+clsname+'* c) {\n'+ \
|
||||||
unwrapderived + \
|
unwrapderived + \
|
||||||
' DCHECK(false) << "Unexpected class type: " << type;\n'+ \
|
' ' + notreached + '\n'+ \
|
||||||
' return nullptr;\n'+ \
|
|
||||||
'}\n\n'
|
'}\n\n'
|
||||||
|
|
||||||
const += 'template<> CefWrapperType ' + parent_sig + '::kWrapperType = ' + get_wrapper_type_enum(
|
const += 'template<> CefWrapperType ' + parent_sig + '::kWrapperType = ' + get_wrapper_type_enum(
|
||||||
clsname) + ';'
|
clsname) + ';\n\n'
|
||||||
|
|
||||||
result += const
|
virtualout += const
|
||||||
|
idx += 1
|
||||||
|
|
||||||
return result
|
out = staticout + virtualout
|
||||||
|
|
||||||
|
# determine what includes are required by identifying what translation
|
||||||
|
# classes are being used
|
||||||
|
includes = format_translation_includes(
|
||||||
|
header,
|
||||||
|
out + (unwrapderived[0] if base_scoped else unwrapderived),
|
||||||
|
with_versions=with_versions)
|
||||||
|
|
||||||
|
# build the final output
|
||||||
|
result = get_copyright()
|
||||||
|
|
||||||
|
result += includes + '\n'
|
||||||
|
|
||||||
|
if with_versions:
|
||||||
|
pre = post = ''
|
||||||
|
else:
|
||||||
|
pre, post = get_version_surround(cls, long=True)
|
||||||
|
if len(pre) > 0:
|
||||||
|
result += pre + '\n'
|
||||||
|
|
||||||
|
result += out + '\n'
|
||||||
|
|
||||||
|
if len(post) > 0:
|
||||||
|
result += post + '\n'
|
||||||
|
|
||||||
|
return (result, customized)
|
||||||
|
|
||||||
|
|
||||||
def make_ctocpp_global_impl(header, impl):
|
def make_ctocpp_global_impl(header, impl):
|
||||||
@ -679,31 +902,31 @@ def make_ctocpp_global_impl(header, impl):
|
|||||||
existing = get_function_impls(impl, 'CEF_GLOBAL')
|
existing = get_function_impls(impl, 'CEF_GLOBAL')
|
||||||
|
|
||||||
# generate static functions
|
# generate static functions
|
||||||
impl = make_ctocpp_function_impl(None, header.get_funcs(), existing, False)
|
impl, customized = make_ctocpp_function_impl(None,
|
||||||
|
header.get_funcs(), existing,
|
||||||
|
False, None, None)
|
||||||
if len(impl) > 0:
|
if len(impl) > 0:
|
||||||
impl = '\n// GLOBAL METHODS - Body may be edited by hand.\n\n' + impl
|
impl = '\n// GLOBAL METHODS - Body may be edited by hand.\n\n' + impl
|
||||||
|
|
||||||
includes = ''
|
includes = ''
|
||||||
|
|
||||||
# include required headers for global functions
|
# include required headers for global functions
|
||||||
filenames = []
|
paths = set()
|
||||||
for func in header.get_funcs():
|
for func in header.get_funcs():
|
||||||
filename = func.get_file_name()
|
filename = func.get_file_name()
|
||||||
if not filename in filenames:
|
paths.add('include/' + func.get_file_name())
|
||||||
includes += '#include "include/'+func.get_file_name()+'"\n' \
|
paths.add('include/capi/' + func.get_capi_file_name())
|
||||||
'#include "include/capi/'+func.get_capi_file_name()+'"\n'
|
|
||||||
filenames.append(filename)
|
|
||||||
|
|
||||||
# determine what includes are required by identifying what translation
|
# determine what includes are required by identifying what translation
|
||||||
# classes are being used
|
# classes are being used
|
||||||
includes += format_translation_includes(header, impl)
|
includes += format_translation_includes(header, impl, other_includes=paths)
|
||||||
|
|
||||||
# build the final output
|
# build the final output
|
||||||
result = get_copyright()
|
result = get_copyright()
|
||||||
|
|
||||||
result += includes + '\n// Define used to facilitate parsing.\n#define CEF_GLOBAL\n\n' + impl
|
result += includes + '\n// Define used to facilitate parsing.\n#define CEF_GLOBAL\n\n' + impl
|
||||||
|
|
||||||
return result
|
return (result, customized)
|
||||||
|
|
||||||
|
|
||||||
def write_ctocpp_impl(header, clsname, dir):
|
def write_ctocpp_impl(header, clsname, dir):
|
||||||
@ -717,16 +940,22 @@ def write_ctocpp_impl(header, clsname, dir):
|
|||||||
dir = os.path.dirname(os.path.join(dir, cls.get_file_name()))
|
dir = os.path.dirname(os.path.join(dir, cls.get_file_name()))
|
||||||
file = os.path.join(dir, get_capi_name(clsname[3:], False) + '_ctocpp.cc')
|
file = os.path.join(dir, get_capi_name(clsname[3:], False) + '_ctocpp.cc')
|
||||||
|
|
||||||
|
set_notify_context(file)
|
||||||
|
|
||||||
if path_exists(file):
|
if path_exists(file):
|
||||||
oldcontents = read_file(file)
|
oldcontents = read_file(file)
|
||||||
else:
|
else:
|
||||||
oldcontents = ''
|
oldcontents = ''
|
||||||
|
|
||||||
if clsname is None:
|
if clsname is None:
|
||||||
newcontents = make_ctocpp_global_impl(header, oldcontents)
|
newcontents, customized = make_ctocpp_global_impl(header, oldcontents)
|
||||||
else:
|
else:
|
||||||
newcontents = make_ctocpp_class_impl(header, clsname, oldcontents)
|
newcontents, customized = make_ctocpp_class_impl(header, clsname,
|
||||||
return (file, newcontents)
|
oldcontents)
|
||||||
|
|
||||||
|
set_notify_context(None)
|
||||||
|
|
||||||
|
return (file, newcontents, customized)
|
||||||
|
|
||||||
|
|
||||||
# test the module
|
# test the module
|
||||||
|
@ -6,6 +6,7 @@ from __future__ import absolute_import
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
from bazel_util import bazel_substitute, bazel_last_error, bazel_set_quiet
|
from bazel_util import bazel_substitute, bazel_last_error, bazel_set_quiet
|
||||||
from cef_version import VersionFormatter
|
from cef_version import VersionFormatter
|
||||||
|
from clang_util import clang_format_inplace
|
||||||
from date_util import *
|
from date_util import *
|
||||||
from exec_util import exec_cmd
|
from exec_util import exec_cmd
|
||||||
from file_util import *
|
from file_util import *
|
||||||
@ -226,7 +227,12 @@ def transfer_doxyfile(dst_dir, quiet):
|
|||||||
sys.stdout.write('Creating Doxyfile file.\n')
|
sys.stdout.write('Creating Doxyfile file.\n')
|
||||||
|
|
||||||
|
|
||||||
def transfer_gypi_files(src_dir, gypi_paths, gypi_path_prefix, dst_dir, quiet):
|
def transfer_gypi_files(src_dir,
|
||||||
|
gypi_paths,
|
||||||
|
gypi_path_prefix,
|
||||||
|
dst_dir,
|
||||||
|
quiet,
|
||||||
|
format=False):
|
||||||
""" Transfer files from one location to another. """
|
""" Transfer files from one location to another. """
|
||||||
for path in gypi_paths:
|
for path in gypi_paths:
|
||||||
src = os.path.join(src_dir, path)
|
src = os.path.join(src_dir, path)
|
||||||
@ -235,6 +241,11 @@ def transfer_gypi_files(src_dir, gypi_paths, gypi_path_prefix, dst_dir, quiet):
|
|||||||
make_dir(dst_path, quiet)
|
make_dir(dst_path, quiet)
|
||||||
copy_file(src, dst, quiet)
|
copy_file(src, dst, quiet)
|
||||||
|
|
||||||
|
# Apply clang-format for C/C++ files.
|
||||||
|
if format and os.path.splitext(dst)[1][1:] in ('c', 'cc', 'cpp', 'h'):
|
||||||
|
print(dst)
|
||||||
|
clang_format_inplace(dst)
|
||||||
|
|
||||||
|
|
||||||
def extract_toolchain_cmd(build_dir,
|
def extract_toolchain_cmd(build_dir,
|
||||||
exe_name,
|
exe_name,
|
||||||
@ -925,17 +936,19 @@ if mode == 'standard' or mode == 'minimal':
|
|||||||
transfer_gypi_files(cef_dir, cef_paths2['includes_wrapper'], \
|
transfer_gypi_files(cef_dir, cef_paths2['includes_wrapper'], \
|
||||||
'include/', include_dir, options.quiet)
|
'include/', include_dir, options.quiet)
|
||||||
transfer_gypi_files(cef_dir, cef_paths['autogen_cpp_includes'], \
|
transfer_gypi_files(cef_dir, cef_paths['autogen_cpp_includes'], \
|
||||||
'include/', include_dir, options.quiet)
|
'include/', include_dir, options.quiet, format=True)
|
||||||
transfer_gypi_files(cef_dir, cef_paths['autogen_capi_includes'], \
|
transfer_gypi_files(cef_dir, cef_paths['autogen_capi_includes'], \
|
||||||
'include/', include_dir, options.quiet)
|
'include/', include_dir, options.quiet, format=True)
|
||||||
|
|
||||||
# Transfer generated include files.
|
# Transfer generated include files.
|
||||||
generated_includes = [
|
generated_includes = [
|
||||||
|
'cef_api_versions.h',
|
||||||
'cef_color_ids.h',
|
'cef_color_ids.h',
|
||||||
'cef_command_ids.h',
|
'cef_command_ids.h',
|
||||||
'cef_config.h',
|
'cef_config.h',
|
||||||
'cef_pack_resources.h',
|
'cef_pack_resources.h',
|
||||||
'cef_pack_strings.h',
|
'cef_pack_strings.h',
|
||||||
|
'cef_version.h',
|
||||||
]
|
]
|
||||||
for include in generated_includes:
|
for include in generated_includes:
|
||||||
# Debug and Release build should be the same so grab whichever exists.
|
# Debug and Release build should be the same so grab whichever exists.
|
||||||
@ -953,7 +966,7 @@ if mode == 'standard' or mode == 'minimal':
|
|||||||
transfer_gypi_files(cef_dir, cef_paths2['libcef_dll_wrapper_sources_common'], \
|
transfer_gypi_files(cef_dir, cef_paths2['libcef_dll_wrapper_sources_common'], \
|
||||||
'libcef_dll/', libcef_dll_dir, options.quiet)
|
'libcef_dll/', libcef_dll_dir, options.quiet)
|
||||||
transfer_gypi_files(cef_dir, cef_paths['autogen_client_side'], \
|
transfer_gypi_files(cef_dir, cef_paths['autogen_client_side'], \
|
||||||
'libcef_dll/', libcef_dll_dir, options.quiet)
|
'libcef_dll/', libcef_dll_dir, options.quiet, format=True)
|
||||||
|
|
||||||
if mode == 'standard' or mode == 'minimal':
|
if mode == 'standard' or mode == 'minimal':
|
||||||
# transfer additional files
|
# transfer additional files
|
||||||
|
@ -37,6 +37,13 @@ def make_gypi_file(header):
|
|||||||
result += " 'include/capi/" + get_capi_file_name(filename) + "',\n"
|
result += " 'include/capi/" + get_capi_file_name(filename) + "',\n"
|
||||||
result += " ],\n"
|
result += " ],\n"
|
||||||
|
|
||||||
|
# capi version includes
|
||||||
|
result += " 'autogen_capi_versions_includes': [\n"
|
||||||
|
for filename in filenames:
|
||||||
|
result += " 'include/capi/" + get_capi_file_name(
|
||||||
|
filename, versions=True) + "',\n"
|
||||||
|
result += " ],\n"
|
||||||
|
|
||||||
classes = sorted(header.get_class_names())
|
classes = sorted(header.get_class_names())
|
||||||
|
|
||||||
# library side includes
|
# library side includes
|
||||||
|
@ -10,7 +10,8 @@ import os
|
|||||||
# Other headers that export C API functions.
|
# Other headers that export C API functions.
|
||||||
OTHER_HEADERS = [
|
OTHER_HEADERS = [
|
||||||
'cef_api_hash.h',
|
'cef_api_hash.h',
|
||||||
'cef_version.h',
|
'cef_id_mappers.h',
|
||||||
|
'cef_version_info.h',
|
||||||
'internal/cef_dump_without_crashing_internal.h',
|
'internal/cef_dump_without_crashing_internal.h',
|
||||||
'internal/cef_logging_internal.h',
|
'internal/cef_logging_internal.h',
|
||||||
'internal/cef_string_list.h',
|
'internal/cef_string_list.h',
|
||||||
@ -37,12 +38,11 @@ def make_libcef_dll_dylib_impl_parts(name, retval, args):
|
|||||||
|
|
||||||
declare = 'decltype(&%s) %s;\n' % (name, name)
|
declare = 'decltype(&%s) %s;\n' % (name, name)
|
||||||
|
|
||||||
init = ' INIT_ENTRY(%s);' % name
|
init = 'INIT_ENTRY(%s);\n' % name
|
||||||
|
|
||||||
impl = """NO_SANITIZE("cfi-icall") %s %s(%s) {
|
impl = """NO_SANITIZE("cfi-icall") %s %s(%s) {
|
||||||
%sg_libcef_pointers.%s(%s);
|
%sg_libcef_pointers.%s(%s);
|
||||||
}
|
}
|
||||||
|
|
||||||
""" % (retval, name, ', '.join(args), 'return '
|
""" % (retval, name, ', '.join(args), 'return '
|
||||||
if retval != 'void' else '', name, arg_names)
|
if retval != 'void' else '', name, arg_names)
|
||||||
|
|
||||||
@ -70,9 +70,10 @@ def make_libcef_dll_dylib_impl(header):
|
|||||||
# Include required headers for global functions.
|
# Include required headers for global functions.
|
||||||
for func in header.get_funcs():
|
for func in header.get_funcs():
|
||||||
declare, init, impl = make_libcef_dll_dylib_impl_func(func)
|
declare, init, impl = make_libcef_dll_dylib_impl_func(func)
|
||||||
ptr_declare += declare
|
pre, post = get_version_surround(func)
|
||||||
ptr_init += init
|
ptr_declare += pre + declare + post
|
||||||
ptr_impl += impl
|
ptr_init += pre + init + post
|
||||||
|
ptr_impl += pre + impl + post + '\n'
|
||||||
|
|
||||||
filename = func.get_file_name()
|
filename = func.get_file_name()
|
||||||
if not filename in filenames:
|
if not filename in filenames:
|
||||||
@ -85,9 +86,13 @@ def make_libcef_dll_dylib_impl(header):
|
|||||||
funcs = cls.get_static_funcs()
|
funcs = cls.get_static_funcs()
|
||||||
for func in funcs:
|
for func in funcs:
|
||||||
declare, init, impl = make_libcef_dll_dylib_impl_func(func)
|
declare, init, impl = make_libcef_dll_dylib_impl_func(func)
|
||||||
ptr_declare += declare
|
pre1, post1 = get_version_surround(func)
|
||||||
ptr_init += init
|
pre2, post2 = get_version_surround(cls)
|
||||||
ptr_impl += impl
|
pre = pre1 + pre2
|
||||||
|
post = post1 + post2
|
||||||
|
ptr_declare += pre + declare + post
|
||||||
|
ptr_init += pre + init + post
|
||||||
|
ptr_impl += pre + impl + post + '\n'
|
||||||
|
|
||||||
if len(funcs) > 0:
|
if len(funcs) > 0:
|
||||||
filename = cls.get_file_name()
|
filename = cls.get_file_name()
|
||||||
@ -106,7 +111,7 @@ def make_libcef_dll_dylib_impl(header):
|
|||||||
func['name'], func['retval'], func['args'])
|
func['name'], func['retval'], func['args'])
|
||||||
ptr_declare += declare
|
ptr_declare += declare
|
||||||
ptr_init += init
|
ptr_init += init
|
||||||
ptr_impl += impl
|
ptr_impl += impl + '\n'
|
||||||
|
|
||||||
includes.append('#include "include/%s"' % other)
|
includes.append('#include "include/%s"' % other)
|
||||||
|
|
||||||
@ -202,7 +207,9 @@ if __name__ == "__main__":
|
|||||||
# Create the header object. Should match the logic in translator.py.
|
# Create the header object. Should match the logic in translator.py.
|
||||||
header = obj_header()
|
header = obj_header()
|
||||||
header.set_root_directory(cpp_header_dir)
|
header.set_root_directory(cpp_header_dir)
|
||||||
excluded_files = ['cef_api_hash.h', 'cef_application_mac.h', 'cef_version.h']
|
excluded_files = [
|
||||||
|
'cef_api_hash.h', 'cef_application_mac.h', 'cef_version_info.h'
|
||||||
|
]
|
||||||
header.add_directory(cpp_header_dir, excluded_files)
|
header.add_directory(cpp_header_dir, excluded_files)
|
||||||
header.add_directory(os.path.join(cpp_header_dir, 'test'))
|
header.add_directory(os.path.join(cpp_header_dir, 'test'))
|
||||||
header.add_directory(os.path.join(cpp_header_dir, 'views'))
|
header.add_directory(os.path.join(cpp_header_dir, 'views'))
|
||||||
|
@ -16,7 +16,7 @@ import string
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
def MakeFileSegment(input, all_names):
|
def _make_pack_header_segment(input, ids):
|
||||||
result = """
|
result = """
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -26,8 +26,93 @@ def MakeFileSegment(input, all_names):
|
|||||||
filename = os.path.split(input)[1]
|
filename = os.path.split(input)[1]
|
||||||
result = result.replace('$FILE$', filename)
|
result = result.replace('$FILE$', filename)
|
||||||
|
|
||||||
|
for name, id in ids.items():
|
||||||
|
result += "\n#define %s %s" % (name, id)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def make_pack_header(output, all_files):
|
||||||
|
# header string
|
||||||
|
result = get_copyright(full=True, translator=False) + \
|
||||||
|
"""//
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This file is generated by the make_pack_header.py tool.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef $GUARD$
|
||||||
|
#define $GUARD$
|
||||||
|
#pragma once"""
|
||||||
|
|
||||||
|
# generate the file segments
|
||||||
|
for file, ids in all_files.items():
|
||||||
|
result += _make_pack_header_segment(file, ids)
|
||||||
|
|
||||||
|
# footer string
|
||||||
|
result += \
|
||||||
|
"""
|
||||||
|
|
||||||
|
#endif // $GUARD$
|
||||||
|
"""
|
||||||
|
|
||||||
|
# add the guard string
|
||||||
|
filename = os.path.split(output)[1]
|
||||||
|
guard = 'CEF_INCLUDE_' + filename.replace('.', '_').upper() + '_'
|
||||||
|
result = result.replace('$GUARD$', guard)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def _get_cpp_var_name(output):
|
||||||
|
filename_no_ext = os.path.splitext(os.path.split(output)[1])[0]
|
||||||
|
|
||||||
|
# Convert to CamelCase after removing the 'cef_' prefix.
|
||||||
|
parts = filename_no_ext.split('_')[1:]
|
||||||
|
return "".join([p[0].upper() + p[1:] for p in parts])
|
||||||
|
|
||||||
|
|
||||||
|
def make_pack_inc(output, all_files):
|
||||||
|
var = 'IdNames' + _get_cpp_var_name(output)
|
||||||
|
|
||||||
|
result = get_copyright(full=False, translator=False) + \
|
||||||
|
"""//
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This file was generated by the make_pack_header.py tool.
|
||||||
|
//
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct $var$ {
|
||||||
|
int id;
|
||||||
|
const char* const name;
|
||||||
|
};
|
||||||
|
|
||||||
|
const $var$ k$var$[] = {""".replace('$var$', var)
|
||||||
|
|
||||||
|
for file, ids in all_files.items():
|
||||||
|
result += '\n // From %s:' % file
|
||||||
|
for name, id in ids.items():
|
||||||
|
result += '\n {%s, "%s"},' % (id, name)
|
||||||
|
|
||||||
|
result += \
|
||||||
|
"""
|
||||||
|
};
|
||||||
|
|
||||||
|
const size_t k$var$Size = std::size(k$var$);
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
""".replace('$var$', var)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def _get_defines(input, all_names):
|
||||||
contents = read_file(input)
|
contents = read_file(input)
|
||||||
|
|
||||||
|
ids = {}
|
||||||
|
|
||||||
# Format for Windows builds with resource whitelisting enabled [1]:
|
# Format for Windows builds with resource whitelisting enabled [1]:
|
||||||
# #define IDR_RESOURCE_NAME (::ui::WhitelistedResource<12345>(), 12345)
|
# #define IDR_RESOURCE_NAME (::ui::WhitelistedResource<12345>(), 12345)
|
||||||
# Format for other builds:
|
# Format for other builds:
|
||||||
@ -50,54 +135,48 @@ def MakeFileSegment(input, all_names):
|
|||||||
else:
|
else:
|
||||||
all_names[name] = 1
|
all_names[name] = 1
|
||||||
|
|
||||||
result += "\n#define %s %s" % (name, id)
|
ids[name] = id
|
||||||
|
|
||||||
return result
|
return ids
|
||||||
|
|
||||||
|
|
||||||
def MakeFile(output, input):
|
def write_pack_header(out_header_file, out_inc_file, inputs):
|
||||||
# header string
|
|
||||||
result = get_copyright(full=True, translator=False) + \
|
|
||||||
"""//
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// This file is generated by the make_pack_header.py tool.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef $GUARD$
|
|
||||||
#define $GUARD$
|
|
||||||
#pragma once"""
|
|
||||||
|
|
||||||
# sort the input files by name
|
# sort the input files by name
|
||||||
input = sorted(input, key=lambda path: os.path.split(path)[1])
|
inputs = sorted(inputs, key=lambda path: os.path.split(path)[1])
|
||||||
|
|
||||||
all_names = {}
|
all_names = {}
|
||||||
|
all_files = {}
|
||||||
|
|
||||||
# generate the file segments
|
# generate the file segments
|
||||||
for file in input:
|
for file in inputs:
|
||||||
result += MakeFileSegment(file, all_names)
|
filename = os.path.split(file)[1]
|
||||||
|
assert not filename in all_files, filename
|
||||||
|
all_files[filename] = _get_defines(file, all_names)
|
||||||
|
|
||||||
# footer string
|
out_file = os.path.abspath(out_header_file)
|
||||||
result += \
|
result = make_pack_header(out_file, all_files)
|
||||||
"""
|
if not bool(result):
|
||||||
|
sys.stderr.write('Failed to create %s\n' % out_file)
|
||||||
|
sys.exit(1)
|
||||||
|
retval1 = write_file_if_changed(out_file, result)
|
||||||
|
|
||||||
#endif // $GUARD$
|
out_file = os.path.abspath(out_inc_file)
|
||||||
"""
|
result = make_pack_inc(out_file, all_files)
|
||||||
|
if not bool(result):
|
||||||
|
sys.stderr.write('Failed to create %s\n' % out_file)
|
||||||
|
sys.exit(1)
|
||||||
|
retval2 = write_file_if_changed(out_file, result)
|
||||||
|
|
||||||
# add the guard string
|
return retval1 #or retval2
|
||||||
filename = os.path.split(output)[1]
|
|
||||||
guard = 'CEF_INCLUDE_' + filename.replace('.', '_').upper() + '_'
|
|
||||||
result = result.replace('$GUARD$', guard)
|
|
||||||
|
|
||||||
write_file_if_changed(output, result)
|
|
||||||
|
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
if len(argv) < 3:
|
if len(argv) < 4:
|
||||||
print(("Usage:\n %s <output_filename> <input_file1> [input_file2] ... " %
|
print(
|
||||||
argv[0]))
|
"Usage:\n %s <output_header_file> <output_inc_file> <input_file1> [input_file2] ... "
|
||||||
|
% argv[0])
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
MakeFile(argv[1], argv[2:])
|
write_pack_header(argv[1], argv[2], argv[3:])
|
||||||
|
|
||||||
|
|
||||||
if '__main__' == __name__:
|
if '__main__' == __name__:
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
@echo off
|
|
||||||
python3.bat tools\make_version_header.py include\cef_version.h
|
|
@ -12,9 +12,6 @@ import sys
|
|||||||
|
|
||||||
|
|
||||||
def make_version_header(header):
|
def make_version_header(header):
|
||||||
if not git.is_checkout('.'):
|
|
||||||
raise Exception('Not a valid checkout')
|
|
||||||
|
|
||||||
result = get_copyright(full=True, translator=False) + \
|
result = get_copyright(full=True, translator=False) + \
|
||||||
"""//
|
"""//
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -41,33 +38,6 @@ def make_version_header(header):
|
|||||||
#define DO_MAKE_STRING(p) #p
|
#define DO_MAKE_STRING(p) #p
|
||||||
#define MAKE_STRING(p) DO_MAKE_STRING(p)
|
#define MAKE_STRING(p) DO_MAKE_STRING(p)
|
||||||
|
|
||||||
#ifndef APSTUDIO_HIDDEN_SYMBOLS
|
|
||||||
|
|
||||||
#include "include/internal/cef_export.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Returns CEF version information for the libcef library. The |entry|
|
|
||||||
// parameter describes which version component will be returned:
|
|
||||||
// 0 - CEF_VERSION_MAJOR
|
|
||||||
// 1 - CEF_VERSION_MINOR
|
|
||||||
// 2 - CEF_VERSION_PATCH
|
|
||||||
// 3 - CEF_COMMIT_NUMBER
|
|
||||||
// 4 - CHROME_VERSION_MAJOR
|
|
||||||
// 5 - CHROME_VERSION_MINOR
|
|
||||||
// 6 - CHROME_VERSION_BUILD
|
|
||||||
// 7 - CHROME_VERSION_PATCH
|
|
||||||
///
|
|
||||||
CEF_EXPORT int cef_version_info(int entry);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // APSTUDIO_HIDDEN_SYMBOLS
|
|
||||||
|
|
||||||
#endif // CEF_INCLUDE_CEF_VERSION_H_
|
#endif // CEF_INCLUDE_CEF_VERSION_H_
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
python3 tools/make_version_header.py include/cef_version.h
|
|
@ -43,7 +43,9 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
# create the header object
|
# create the header object
|
||||||
header = obj_header()
|
header = obj_header()
|
||||||
excluded_files = ['cef_api_hash.h', 'cef_application_mac.h', 'cef_version.h']
|
excluded_files = [
|
||||||
|
'cef_api_hash.h', 'cef_application_mac.h', 'cef_version_info.h'
|
||||||
|
]
|
||||||
header.add_directory(sys.argv[1], excluded_files)
|
header.add_directory(sys.argv[1], excluded_files)
|
||||||
|
|
||||||
# dump the result to stdout
|
# dump the result to stdout
|
||||||
|
@ -285,10 +285,6 @@ follows.
|
|||||||
|
|
||||||
void CefClassCToCpp::Function(cpp_params)
|
void CefClassCToCpp::Function(cpp_params)
|
||||||
{
|
{
|
||||||
// Structure Verification
|
|
||||||
if (CEF_MEMBER_MISSING(struct_, function))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Parameter Verification (Optional)
|
// Parameter Verification (Optional)
|
||||||
// Verify the C++ parameter values.
|
// Verify the C++ parameter values.
|
||||||
// ...
|
// ...
|
||||||
@ -309,10 +305,6 @@ follows.
|
|||||||
|
|
||||||
cpp_retval CefClassCToCpp::Function(cpp_params)
|
cpp_retval CefClassCToCpp::Function(cpp_params)
|
||||||
{
|
{
|
||||||
// Structure Verification
|
|
||||||
if (CEF_MEMBER_MISSING(struct_, function))
|
|
||||||
return default_retval; // Configured or defaulted automatically.
|
|
||||||
|
|
||||||
// Parameter Verification (Optional)
|
// Parameter Verification (Optional)
|
||||||
// Verify the C++ parameter values.
|
// Verify the C++ parameter values.
|
||||||
// ...
|
// ...
|
||||||
|
@ -3,111 +3,66 @@
|
|||||||
# can be found in the LICENSE file.
|
# can be found in the LICENSE file.
|
||||||
|
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
import sys
|
from cef_parser import obj_header
|
||||||
from cef_parser import *
|
from cef_version import VersionFormatter
|
||||||
from clang_util import clang_format
|
from clang_util import clang_format
|
||||||
from file_util import *
|
from file_util import *
|
||||||
import hashlib
|
import hashlib
|
||||||
from make_api_hash_header import *
|
from make_capi_header import write_capi_header
|
||||||
from make_capi_header import *
|
from make_capi_versions_header import write_capi_versions_header
|
||||||
from make_cpptoc_header import *
|
from make_cpptoc_header import write_cpptoc_header
|
||||||
from make_cpptoc_impl import *
|
from make_cpptoc_impl import write_cpptoc_impl
|
||||||
from make_ctocpp_header import *
|
from make_ctocpp_header import write_ctocpp_header
|
||||||
from make_ctocpp_impl import *
|
from make_ctocpp_impl import write_ctocpp_impl
|
||||||
from make_gypi_file import *
|
from make_gypi_file import write_gypi_file
|
||||||
from make_libcef_dll_dylib_impl import *
|
from make_libcef_dll_dylib_impl import write_libcef_dll_dylib_impl
|
||||||
from make_wrapper_types_header import *
|
from make_wrapper_types_header import write_wrapper_types_header
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
|
import sys
|
||||||
|
|
||||||
# cannot be loaded as a module
|
FILE_HEADER = """#
|
||||||
if __name__ != "__main__":
|
# This file was generated by the CEF translator tool and should not edited
|
||||||
sys.stderr.write('This file cannot be loaded as a module!')
|
# by hand.
|
||||||
sys.exit()
|
#
|
||||||
|
# $hash=$$HASH$$$
|
||||||
|
#
|
||||||
|
|
||||||
# parse command-line options
|
|
||||||
disc = """
|
|
||||||
This utility generates files for the CEF C++ to C API translation layer.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
parser = OptionParser(description=disc)
|
|
||||||
parser.add_option(
|
|
||||||
'--root-dir',
|
|
||||||
dest='rootdir',
|
|
||||||
metavar='DIR',
|
|
||||||
help='CEF root directory [required]')
|
|
||||||
parser.add_option(
|
|
||||||
'--backup',
|
|
||||||
action='store_true',
|
|
||||||
dest='backup',
|
|
||||||
default=False,
|
|
||||||
help='create a backup of modified files')
|
|
||||||
parser.add_option(
|
|
||||||
'--force',
|
|
||||||
action='store_true',
|
|
||||||
dest='force',
|
|
||||||
default=False,
|
|
||||||
help='force rewrite of the file')
|
|
||||||
parser.add_option(
|
|
||||||
'-c',
|
|
||||||
'--classes',
|
|
||||||
dest='classes',
|
|
||||||
action='append',
|
|
||||||
help='only translate the specified classes')
|
|
||||||
parser.add_option(
|
|
||||||
'-q',
|
|
||||||
'--quiet',
|
|
||||||
action='store_true',
|
|
||||||
dest='quiet',
|
|
||||||
default=False,
|
|
||||||
help='do not output detailed status information')
|
|
||||||
(options, args) = parser.parse_args()
|
|
||||||
|
|
||||||
# the rootdir option is required
|
def _write_version():
|
||||||
if options.rootdir is None:
|
return FILE_HEADER + VersionFormatter().get_version_string()
|
||||||
parser.print_help(sys.stdout)
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
# determine the paths
|
|
||||||
root_dir = os.path.abspath(options.rootdir)
|
|
||||||
cpp_header_dir = os.path.join(root_dir, 'include')
|
|
||||||
cpp_header_test_dir = os.path.join(cpp_header_dir, 'test')
|
|
||||||
cpp_header_views_dir = os.path.join(cpp_header_dir, 'views')
|
|
||||||
capi_header_dir = os.path.join(cpp_header_dir, 'capi')
|
|
||||||
api_hash_header = os.path.join(cpp_header_dir, 'cef_api_hash.h')
|
|
||||||
libcef_dll_dir = os.path.join(root_dir, 'libcef_dll')
|
|
||||||
cpptoc_global_impl = os.path.join(libcef_dll_dir, 'libcef_dll.cc')
|
|
||||||
ctocpp_global_impl = os.path.join(libcef_dll_dir, 'wrapper',
|
|
||||||
'libcef_dll_wrapper.cc')
|
|
||||||
wrapper_types_header = os.path.join(libcef_dll_dir, 'wrapper_types.h')
|
|
||||||
cpptoc_dir = os.path.join(libcef_dll_dir, 'cpptoc')
|
|
||||||
ctocpp_dir = os.path.join(libcef_dll_dir, 'ctocpp')
|
|
||||||
gypi_file = os.path.join(root_dir, 'cef_paths.gypi')
|
|
||||||
libcef_dll_dylib_impl = os.path.join(libcef_dll_dir, 'wrapper',
|
|
||||||
'libcef_dll_dylib.cc')
|
|
||||||
|
|
||||||
# make sure the header directory exists
|
|
||||||
if not path_exists(cpp_header_dir):
|
|
||||||
sys.stderr.write('Directory ' + cpp_header_dir + ' does not exist.')
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
# create the header object
|
|
||||||
if not options.quiet:
|
|
||||||
sys.stdout.write('Parsing C++ headers from ' + cpp_header_dir + '...\n')
|
|
||||||
header = obj_header()
|
|
||||||
|
|
||||||
# add include files to be processed
|
|
||||||
header.set_root_directory(cpp_header_dir)
|
|
||||||
excluded_files = ['cef_api_hash.h', 'cef_application_mac.h', 'cef_version.h']
|
|
||||||
header.add_directory(cpp_header_dir, excluded_files)
|
|
||||||
header.add_directory(cpp_header_test_dir)
|
|
||||||
header.add_directory(cpp_header_views_dir)
|
|
||||||
|
|
||||||
# Track the number of files that were written.
|
|
||||||
writect = 0
|
|
||||||
|
|
||||||
|
|
||||||
def update_file(file, newcontents):
|
def _write_gitignore(gitignore, gitignore_file, root_dir):
|
||||||
|
contents = FILE_HEADER
|
||||||
|
|
||||||
|
in_file = gitignore_file + '.in'
|
||||||
|
if os.path.isfile(in_file):
|
||||||
|
contents += read_file(in_file)
|
||||||
|
|
||||||
|
# Include ourselves in generated files.
|
||||||
|
gitignore.append(gitignore_file)
|
||||||
|
|
||||||
|
root_dir_len = len(root_dir)
|
||||||
|
contents += '\n'.join(
|
||||||
|
[p[root_dir_len:].replace('\\', '/') for p in sorted(gitignore)])
|
||||||
|
|
||||||
|
return contents
|
||||||
|
|
||||||
|
|
||||||
|
def _update_file(file, newcontents, customized, force, clean, backup,
|
||||||
|
gitignore):
|
||||||
""" Replaces the contents of |file| with |newcontents| if necessary. """
|
""" Replaces the contents of |file| with |newcontents| if necessary. """
|
||||||
|
if clean:
|
||||||
|
if not customized:
|
||||||
|
return 1 if remove_file(file, quiet=False) else 0
|
||||||
|
print('File %s has customizations and will not be removed' % file)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if not customized and not gitignore is None:
|
||||||
|
gitignore.append(file)
|
||||||
|
|
||||||
oldcontents = ''
|
oldcontents = ''
|
||||||
oldhash = ''
|
oldhash = ''
|
||||||
|
|
||||||
@ -122,7 +77,7 @@ def update_file(file, newcontents):
|
|||||||
hash_end = "$"
|
hash_end = "$"
|
||||||
hash_token = "$$HASH$$"
|
hash_token = "$$HASH$$"
|
||||||
|
|
||||||
if not options.force and path_exists(file):
|
if not force and path_exists(file):
|
||||||
oldcontents = read_file(file)
|
oldcontents = read_file(file)
|
||||||
|
|
||||||
# Extract the existing hash.
|
# Extract the existing hash.
|
||||||
@ -137,106 +92,264 @@ def update_file(file, newcontents):
|
|||||||
|
|
||||||
if oldhash == newhash:
|
if oldhash == newhash:
|
||||||
# Pre-formatted contents have not changed.
|
# Pre-formatted contents have not changed.
|
||||||
return
|
return 0
|
||||||
|
|
||||||
newcontents = newcontents.replace(hash_token, newhash, 1)
|
newcontents = newcontents.replace(hash_token, newhash, 1)
|
||||||
|
|
||||||
# Apply clang-format for C/C++ files.
|
# Apply clang-format for C/C++ files. This is slow, so we only do it for
|
||||||
if os.path.splitext(file)[1][1:] in ('c', 'cc', 'cpp', 'h'):
|
# customized files.
|
||||||
|
if customized and os.path.splitext(file)[1][1:] in ('c', 'cc', 'cpp', 'h'):
|
||||||
result = clang_format(file, newcontents)
|
result = clang_format(file, newcontents)
|
||||||
if result != None:
|
if result != None:
|
||||||
newcontents = result
|
newcontents = result
|
||||||
else:
|
else:
|
||||||
raise Exception("Call to clang-format failed")
|
raise Exception("Call to clang-format failed for %s" % file)
|
||||||
|
|
||||||
if options.backup and oldcontents != '':
|
if backup and oldcontents != '':
|
||||||
backup_file(file)
|
backup_file(file)
|
||||||
|
|
||||||
filedir = os.path.split(file)[0]
|
filedir = os.path.split(file)[0]
|
||||||
if not os.path.isdir(filedir):
|
if not os.path.isdir(filedir):
|
||||||
make_dir(filedir)
|
make_dir(filedir)
|
||||||
|
|
||||||
|
print('Writing file %s' % file)
|
||||||
write_file(file, newcontents)
|
write_file(file, newcontents)
|
||||||
|
return 1
|
||||||
global writect
|
|
||||||
writect += 1
|
|
||||||
|
|
||||||
|
|
||||||
# output the C API header
|
def translate(cef_dir,
|
||||||
if not options.quiet:
|
force=False,
|
||||||
sys.stdout.write('In C API header directory ' + capi_header_dir + '...\n')
|
clean=False,
|
||||||
filenames = sorted(header.get_file_names())
|
backup=False,
|
||||||
for filename in filenames:
|
verbose=False,
|
||||||
if not options.quiet:
|
selected_classes=None):
|
||||||
sys.stdout.write('Generating ' + filename + ' C API header...\n')
|
# determine the paths
|
||||||
update_file(*write_capi_header(header, capi_header_dir, filename))
|
root_dir = os.path.abspath(cef_dir)
|
||||||
|
cpp_header_dir = os.path.join(root_dir, 'include')
|
||||||
|
cpp_header_test_dir = os.path.join(cpp_header_dir, 'test')
|
||||||
|
cpp_header_views_dir = os.path.join(cpp_header_dir, 'views')
|
||||||
|
capi_header_dir = os.path.join(cpp_header_dir, 'capi')
|
||||||
|
libcef_dll_dir = os.path.join(root_dir, 'libcef_dll')
|
||||||
|
cpptoc_global_impl = os.path.join(libcef_dll_dir, 'libcef_dll.cc')
|
||||||
|
ctocpp_global_impl = os.path.join(libcef_dll_dir, 'wrapper',
|
||||||
|
'libcef_dll_wrapper.cc')
|
||||||
|
wrapper_types_header = os.path.join(libcef_dll_dir, 'wrapper_types.h')
|
||||||
|
cpptoc_dir = os.path.join(libcef_dll_dir, 'cpptoc')
|
||||||
|
ctocpp_dir = os.path.join(libcef_dll_dir, 'ctocpp')
|
||||||
|
gypi_file = os.path.join(root_dir, 'cef_paths.gypi')
|
||||||
|
libcef_dll_dylib_impl = os.path.join(libcef_dll_dir, 'wrapper',
|
||||||
|
'libcef_dll_dylib.cc')
|
||||||
|
version_file = os.path.join(root_dir, 'VERSION.stamp')
|
||||||
|
gitignore_file = os.path.join(root_dir, '.gitignore')
|
||||||
|
|
||||||
# output the wrapper types header
|
# make sure the header directory exists
|
||||||
if not options.quiet:
|
if not path_exists(cpp_header_dir):
|
||||||
sys.stdout.write('Generating wrapper types header...\n')
|
sys.stderr.write('ERROR: Directory ' + cpp_header_dir +
|
||||||
update_file(*write_wrapper_types_header(header, wrapper_types_header))
|
' does not exist.\n')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
# build the list of classes to parse
|
# create the header object
|
||||||
allclasses = header.get_class_names()
|
if verbose:
|
||||||
if not options.classes is None:
|
print('Parsing C++ headers from ' + cpp_header_dir + '...')
|
||||||
for cls in options.classes:
|
header = obj_header()
|
||||||
|
|
||||||
|
# add include files to be processed
|
||||||
|
header.set_root_directory(cpp_header_dir)
|
||||||
|
excluded_files = [
|
||||||
|
'cef_api_hash.h', 'cef_application_mac.h', 'cef_version_info.h'
|
||||||
|
]
|
||||||
|
header.add_directory(cpp_header_dir, excluded_files)
|
||||||
|
header.add_directory(cpp_header_test_dir)
|
||||||
|
header.add_directory(cpp_header_views_dir)
|
||||||
|
|
||||||
|
# Track the number of files that were written.
|
||||||
|
writect = 0
|
||||||
|
|
||||||
|
# Track files that are not customized.
|
||||||
|
gitignore = []
|
||||||
|
|
||||||
|
debug_string = ''
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
# output the C API header
|
||||||
|
if verbose:
|
||||||
|
print('In C API header directory ' + capi_header_dir + '...')
|
||||||
|
filenames = sorted(header.get_file_names())
|
||||||
|
for filename in filenames:
|
||||||
|
if verbose:
|
||||||
|
print('Generating ' + filename + ' C API headers...')
|
||||||
|
debug_string = 'CAPI header for ' + filename
|
||||||
|
writect += _update_file(*write_capi_header(header, capi_header_dir,
|
||||||
|
filename), False, force, clean,
|
||||||
|
backup, gitignore)
|
||||||
|
debug_string = 'CAPI versions header for ' + filename
|
||||||
|
writect += _update_file(*write_capi_versions_header(
|
||||||
|
header, capi_header_dir, filename), False, force, clean, backup,
|
||||||
|
gitignore)
|
||||||
|
|
||||||
|
# output the wrapper types header
|
||||||
|
if verbose:
|
||||||
|
print('Generating wrapper types header...')
|
||||||
|
debug_string = 'wrapper types header'
|
||||||
|
writect += _update_file(*write_wrapper_types_header(
|
||||||
|
header, wrapper_types_header), False, force, clean, backup, gitignore)
|
||||||
|
|
||||||
|
# build the list of classes to parse
|
||||||
|
allclasses = header.get_class_names()
|
||||||
|
if not selected_classes is None:
|
||||||
|
for cls in selected_classes:
|
||||||
if not cls in allclasses:
|
if not cls in allclasses:
|
||||||
sys.stderr.write('ERROR: Unknown class: ' + cls)
|
sys.stderr.write('ERROR: Unknown class: %s\n' % cls)
|
||||||
sys.exit()
|
sys.exit(1)
|
||||||
classes = options.classes
|
classes = selected_classes
|
||||||
else:
|
else:
|
||||||
classes = allclasses
|
classes = allclasses
|
||||||
|
|
||||||
classes = sorted(classes)
|
classes = sorted(classes)
|
||||||
|
|
||||||
# output CppToC global file
|
# output CppToC global file
|
||||||
if not options.quiet:
|
if verbose:
|
||||||
sys.stdout.write('Generating CppToC global implementation...\n')
|
print('Generating CppToC global implementation...')
|
||||||
update_file(*write_cpptoc_impl(header, None, cpptoc_global_impl))
|
debug_string = 'CppToC global implementation'
|
||||||
|
writect += _update_file(*write_cpptoc_impl(
|
||||||
|
header, None, cpptoc_global_impl), force, clean, backup, gitignore)
|
||||||
|
|
||||||
# output CToCpp global file
|
# output CToCpp global file
|
||||||
if not options.quiet:
|
if verbose:
|
||||||
sys.stdout.write('Generating CToCpp global implementation...\n')
|
print('Generating CToCpp global implementation...')
|
||||||
update_file(*write_ctocpp_impl(header, None, ctocpp_global_impl))
|
debug_string = 'CToCpp global implementation'
|
||||||
|
writect += _update_file(*write_ctocpp_impl(
|
||||||
|
header, None, ctocpp_global_impl), force, clean, backup, gitignore)
|
||||||
|
|
||||||
# output CppToC class files
|
# output CppToC class files
|
||||||
if not options.quiet:
|
if verbose:
|
||||||
sys.stdout.write('In CppToC directory ' + cpptoc_dir + '...\n')
|
print('In CppToC directory ' + cpptoc_dir + '...')
|
||||||
for cls in classes:
|
for cls in classes:
|
||||||
if not options.quiet:
|
if verbose:
|
||||||
sys.stdout.write('Generating ' + cls + 'CppToC class header...\n')
|
print('Generating ' + cls + 'CppToC class header...')
|
||||||
update_file(*write_cpptoc_header(header, cls, cpptoc_dir))
|
debug_string = 'CppToC class header for ' + cls
|
||||||
if not options.quiet:
|
writect += _update_file(*write_cpptoc_header(header, cls, cpptoc_dir),
|
||||||
sys.stdout.write('Generating ' + cls + 'CppToC class implementation...\n')
|
False, force, clean, backup, gitignore)
|
||||||
update_file(*write_cpptoc_impl(header, cls, cpptoc_dir))
|
|
||||||
|
|
||||||
# output CppToC class files
|
if verbose:
|
||||||
if not options.quiet:
|
print('Generating ' + cls + 'CppToC class implementation...')
|
||||||
sys.stdout.write('In CToCpp directory ' + ctocpp_dir + '...\n')
|
debug_string = 'CppToC class implementation for ' + cls
|
||||||
for cls in classes:
|
writect += _update_file(*write_cpptoc_impl(header, cls, cpptoc_dir),
|
||||||
if not options.quiet:
|
force, clean, backup, gitignore)
|
||||||
sys.stdout.write('Generating ' + cls + 'CToCpp class header...\n')
|
|
||||||
update_file(*write_ctocpp_header(header, cls, ctocpp_dir))
|
|
||||||
if not options.quiet:
|
|
||||||
sys.stdout.write('Generating ' + cls + 'CToCpp class implementation...\n')
|
|
||||||
update_file(*write_ctocpp_impl(header, cls, ctocpp_dir))
|
|
||||||
|
|
||||||
# output the gypi file
|
# output CppToC class files
|
||||||
if not options.quiet:
|
if verbose:
|
||||||
sys.stdout.write('Generating ' + gypi_file + ' file...\n')
|
print('In CToCpp directory ' + ctocpp_dir + '...')
|
||||||
update_file(*write_gypi_file(header, gypi_file))
|
for cls in classes:
|
||||||
|
if verbose:
|
||||||
|
print('Generating ' + cls + 'CToCpp class header...')
|
||||||
|
debug_string = 'CToCpp class header for ' + cls
|
||||||
|
writect += _update_file(*write_ctocpp_header(header, cls, ctocpp_dir),
|
||||||
|
False, force, clean, backup, gitignore)
|
||||||
|
if verbose:
|
||||||
|
print('Generating ' + cls + 'CToCpp class implementation...')
|
||||||
|
debug_string = 'CToCpp class implementation for ' + cls
|
||||||
|
writect += _update_file(*write_ctocpp_impl(header, cls, ctocpp_dir),
|
||||||
|
force, clean, backup, gitignore)
|
||||||
|
|
||||||
# output the libcef dll dylib file
|
# output the gypi file
|
||||||
if not options.quiet:
|
if verbose:
|
||||||
sys.stdout.write('Generating ' + libcef_dll_dylib_impl + ' file...\n')
|
print('Generating ' + gypi_file + ' file...')
|
||||||
update_file(*write_libcef_dll_dylib_impl(header, libcef_dll_dylib_impl))
|
debug_string = gypi_file
|
||||||
|
writect += _update_file(*write_gypi_file(header, gypi_file), False, force,
|
||||||
|
clean, backup, gitignore)
|
||||||
|
|
||||||
# Update the API hash header file if necessary. This must be done last because
|
# output the libcef dll dylib file
|
||||||
# it reads files that were potentially written by proceeding operations.
|
if verbose:
|
||||||
if not options.quiet:
|
print('Generating ' + libcef_dll_dylib_impl + ' file...')
|
||||||
sys.stdout.write('Generating API hash header...\n')
|
debug_string = libcef_dll_dylib_impl
|
||||||
if write_api_hash_header(api_hash_header, cpp_header_dir):
|
writect += _update_file(*write_libcef_dll_dylib_impl(
|
||||||
writect += 1
|
header, libcef_dll_dylib_impl), False, force, clean, backup, gitignore)
|
||||||
|
|
||||||
if not options.quiet:
|
# output the VERSION.stamp file that triggers cef_version.h regen at build time
|
||||||
sys.stdout.write('Done - Wrote ' + str(writect) + ' files.\n')
|
if verbose:
|
||||||
|
print('Generating ' + version_file + ' file...')
|
||||||
|
debug_string = version_file
|
||||||
|
writect += _update_file(version_file,
|
||||||
|
_write_version(), False, force, clean, backup,
|
||||||
|
gitignore)
|
||||||
|
|
||||||
|
# output the top-level .gitignore file that lists uncustomized files
|
||||||
|
if verbose:
|
||||||
|
print('Generating ' + gitignore_file + ' file...')
|
||||||
|
debug_string = gitignore_file
|
||||||
|
writect += _update_file(gitignore_file,
|
||||||
|
_write_gitignore(gitignore, gitignore_file,
|
||||||
|
root_dir), False, force, clean,
|
||||||
|
backup, None)
|
||||||
|
|
||||||
|
except (AssertionError, Exception) as e:
|
||||||
|
sys.stderr.write('ERROR: while processing %s\n' % debug_string)
|
||||||
|
raise
|
||||||
|
|
||||||
|
if verbose or writect > 0:
|
||||||
|
print('Done translating - %s %d files.' % ('Removed'
|
||||||
|
if clean else 'Wrote', writect))
|
||||||
|
|
||||||
|
return writect
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
from optparse import OptionParser
|
||||||
|
|
||||||
|
# parse command-line options
|
||||||
|
disc = """
|
||||||
|
This utility generates files for the CEF C++ to C API translation layer.
|
||||||
|
"""
|
||||||
|
|
||||||
|
parser = OptionParser(description=disc)
|
||||||
|
parser.add_option(
|
||||||
|
'--root-dir',
|
||||||
|
dest='rootdir',
|
||||||
|
metavar='DIR',
|
||||||
|
help='CEF root directory [required]')
|
||||||
|
parser.add_option(
|
||||||
|
'--backup',
|
||||||
|
action='store_true',
|
||||||
|
dest='backup',
|
||||||
|
default=False,
|
||||||
|
help='create a backup of modified files')
|
||||||
|
parser.add_option(
|
||||||
|
'--force',
|
||||||
|
action='store_true',
|
||||||
|
dest='force',
|
||||||
|
default=False,
|
||||||
|
help='force rewrite of the file')
|
||||||
|
parser.add_option(
|
||||||
|
'--clean',
|
||||||
|
action='store_true',
|
||||||
|
dest='clean',
|
||||||
|
default=False,
|
||||||
|
help='clean all files without custom modifications')
|
||||||
|
parser.add_option(
|
||||||
|
'-c',
|
||||||
|
'--classes',
|
||||||
|
dest='classes',
|
||||||
|
action='append',
|
||||||
|
help='only translate the specified classes')
|
||||||
|
parser.add_option(
|
||||||
|
'-v',
|
||||||
|
'--verbose',
|
||||||
|
action='store_true',
|
||||||
|
dest='verbose',
|
||||||
|
default=False,
|
||||||
|
help='output detailed status information')
|
||||||
|
(options, args) = parser.parse_args()
|
||||||
|
|
||||||
|
# the rootdir option is required
|
||||||
|
if options.rootdir is None:
|
||||||
|
parser.print_help(sys.stdout)
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
if translate(options.rootdir, options.force, options.clean, options.backup,
|
||||||
|
options.verbose, options.classes) == 0:
|
||||||
|
if not options.verbose:
|
||||||
|
print('Nothing to do.')
|
||||||
|
elif not options.clean:
|
||||||
|
print('WARNING: You must run version_manager.py to update API hashes.')
|
||||||
|
549
tools/version_manager.py
Normal file
549
tools/version_manager.py
Normal file
@ -0,0 +1,549 @@
|
|||||||
|
# Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
|
||||||
|
# reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
# can be found in the LICENSE file.
|
||||||
|
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from __future__ import print_function
|
||||||
|
from cef_api_hash import cef_api_hash
|
||||||
|
from cef_version import VersionFormatter
|
||||||
|
from date_util import get_date
|
||||||
|
from file_util import read_file, read_json_file, write_file, write_json_file
|
||||||
|
from git_util import exec_git_cmd
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from translator import translate
|
||||||
|
from version_util import *
|
||||||
|
|
||||||
|
|
||||||
|
def get_next_api_revision(api_versions_file, major_version):
|
||||||
|
""" Returns the next available API revision for |major_version|.
|
||||||
|
"""
|
||||||
|
json = read_json_file(api_versions_file)
|
||||||
|
if not bool(json):
|
||||||
|
return 0
|
||||||
|
|
||||||
|
assert 'last' in json, api_versions_file
|
||||||
|
last_version, last_revision = version_parse(json['last'])
|
||||||
|
|
||||||
|
if major_version < last_version:
|
||||||
|
sys.stderr.write(
|
||||||
|
'ERROR: Cannot add new API versions on old branches/checkouts '
|
||||||
|
'(found %d, expected >= %d)\b' % (major_version, last_version))
|
||||||
|
return -1
|
||||||
|
|
||||||
|
if major_version == last_version:
|
||||||
|
# Increment the revision for the current major version.
|
||||||
|
new_revision = last_revision + 1
|
||||||
|
assert new_revision <= 99, new_revision
|
||||||
|
return new_revision
|
||||||
|
|
||||||
|
# Reset the revision for a new major version.
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
_CALC = None
|
||||||
|
|
||||||
|
|
||||||
|
def compute_api_hashes(cpp_header_dir, api_version, next_allowed, debug_dir,
|
||||||
|
verbose):
|
||||||
|
""" Computes API hashes for the specified |api_version|.
|
||||||
|
"""
|
||||||
|
if not debug_dir is None:
|
||||||
|
debug_dir = os.path.join(debug_dir, api_version)
|
||||||
|
|
||||||
|
if not next_allowed:
|
||||||
|
# Next usage is banned with explicit API versions.
|
||||||
|
assert not api_version in UNTRACKED_VERSIONS, api_version
|
||||||
|
added_defines = [
|
||||||
|
# Using CEF_API_VERSION_NEXT is an error.
|
||||||
|
'CEF_API_VERSION_NEXT="Please_specify_an_exact_CEF_version"',
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
added_defines = None
|
||||||
|
|
||||||
|
global _CALC
|
||||||
|
if _CALC is None:
|
||||||
|
_CALC = cef_api_hash(cpp_header_dir, verbose=verbose)
|
||||||
|
|
||||||
|
hashes = _CALC.calculate(api_version, debug_dir, added_defines)
|
||||||
|
if bool(hashes):
|
||||||
|
if api_version in UNTRACKED_VERSIONS:
|
||||||
|
label = version_label(api_version)
|
||||||
|
label = label[0:1].upper() + label[1:]
|
||||||
|
hashes['comment'] = '%s last updated %s.' % (label, get_date())
|
||||||
|
else:
|
||||||
|
hashes['comment'] = 'Added %s.' % get_date()
|
||||||
|
return hashes
|
||||||
|
|
||||||
|
|
||||||
|
def same_api_hashes(hashes1, hashes2):
|
||||||
|
for key in ('universal', 'linux', 'mac', 'windows'):
|
||||||
|
if hashes1[key] != hashes2[key]:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def compute_next_api_verson(api_versions_file):
|
||||||
|
""" Computes the next available API version number.
|
||||||
|
"""
|
||||||
|
major_version = int(VersionFormatter().get_chrome_major_version())
|
||||||
|
next_revision = get_next_api_revision(api_versions_file, major_version)
|
||||||
|
if next_revision < 0:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return version_make(major_version, next_revision)
|
||||||
|
|
||||||
|
|
||||||
|
def git_grep_next(cef_dir):
|
||||||
|
cmd = "grep --no-color -n -E (CEF_NEXT|CEF_NEXT)|=next -- :!include/cef_api_hash.h *.h"
|
||||||
|
return exec_git_cmd(cmd, cef_dir)
|
||||||
|
|
||||||
|
|
||||||
|
def find_next_usage(cpp_header_dir):
|
||||||
|
cef_dir = os.path.abspath(os.path.join(cpp_header_dir, os.pardir))
|
||||||
|
result = git_grep_next(cef_dir)
|
||||||
|
if result is None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
sys.stderr.write('ERROR: NEXT usage found in CEF headers:\n\n' + result +
|
||||||
|
'\n\nFix manually or run with --replace-next.\n')
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def replace_next_usage(file, linenums, as_variable, as_metadata):
|
||||||
|
assert len(linenums) > 0
|
||||||
|
|
||||||
|
contents = read_file(file)
|
||||||
|
if contents is None:
|
||||||
|
sys.stderr.write('ERROR: Failed to read file %s\n' % file)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
lines = contents.split('\n')
|
||||||
|
changect = 0
|
||||||
|
|
||||||
|
messages = []
|
||||||
|
|
||||||
|
for num in linenums:
|
||||||
|
idx = num - 1
|
||||||
|
if idx < 0 or idx >= len(lines):
|
||||||
|
sys.stderr.write('ERROR: Invalid line number %d in file %s\n' % (num,
|
||||||
|
file))
|
||||||
|
return 0
|
||||||
|
|
||||||
|
line = lines[idx]
|
||||||
|
|
||||||
|
replaced = False
|
||||||
|
if line.find('CEF_NEXT') >= 0:
|
||||||
|
line = line.replace('CEF_NEXT', as_variable)
|
||||||
|
replaced = True
|
||||||
|
if line.find('=next') >= 0:
|
||||||
|
line = line.replace('=next', '=' + as_metadata)
|
||||||
|
replaced = True
|
||||||
|
|
||||||
|
if replaced:
|
||||||
|
lines[idx] = line
|
||||||
|
changect += 1
|
||||||
|
else:
|
||||||
|
messages.append(
|
||||||
|
'WARNING: No NEXT instances found on line number %d' % num)
|
||||||
|
|
||||||
|
if changect > 0 and write_file(file, '\n'.join(lines)):
|
||||||
|
messages.append('Replaced %d of %d NEXT instances' % (changect,
|
||||||
|
len(linenums)))
|
||||||
|
else:
|
||||||
|
changect = 0
|
||||||
|
|
||||||
|
if len(messages) > 0:
|
||||||
|
print('For file %s:' % file)
|
||||||
|
for msg in messages:
|
||||||
|
print(' %s' % msg)
|
||||||
|
print()
|
||||||
|
|
||||||
|
return changect
|
||||||
|
|
||||||
|
|
||||||
|
def find_replace_next_usage(cpp_header_dir, next_version):
|
||||||
|
cef_dir = os.path.abspath(os.path.join(cpp_header_dir, os.pardir))
|
||||||
|
result = git_grep_next(cef_dir)
|
||||||
|
if result is None:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
print('Attempting to replace NEXT usage with %s in CEF headers:\n' %
|
||||||
|
next_version)
|
||||||
|
print(result + '\n')
|
||||||
|
|
||||||
|
as_variable = version_as_variable(next_version)
|
||||||
|
as_metadata = version_as_metadata(next_version)
|
||||||
|
|
||||||
|
files = {}
|
||||||
|
|
||||||
|
# Parse values like:
|
||||||
|
# include/test/cef_translator_test.h:879:#if CEF_API_ADDED(CEF_NEXT)
|
||||||
|
# include/test/cef_translator_test.h:883: /*--cef(added=next)--*/
|
||||||
|
for line in result.split('\n'):
|
||||||
|
parts = line.split(':', maxsplit=2)
|
||||||
|
name = parts[0]
|
||||||
|
linenum = int(parts[1])
|
||||||
|
if not name in files:
|
||||||
|
files[name] = [linenum]
|
||||||
|
else:
|
||||||
|
files[name].append(linenum)
|
||||||
|
|
||||||
|
for file, linenums in files.items():
|
||||||
|
if replace_next_usage(
|
||||||
|
os.path.join(cef_dir, file), linenums, as_variable,
|
||||||
|
as_metadata) != len(linenums):
|
||||||
|
sys.stderr.write('ERROR: Failed to replace all NEXT usage in %s\n' % file)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
# Sanity-check that all instances were fixed.
|
||||||
|
if find_next_usage(cpp_header_dir):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
print('All NEXT instances successfully replaced.')
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def exec_apply(cpp_header_dir, api_versions_file, api_untracked_file,
|
||||||
|
next_version, debug_dir, apply_next, verbose):
|
||||||
|
""" Updates untracked API hashes if necessary.
|
||||||
|
Saves the hash for the next API version if |apply_next| is true.
|
||||||
|
"""
|
||||||
|
json_versions, json_untracked, initialized = \
|
||||||
|
read_version_files(api_versions_file, api_untracked_file, True)
|
||||||
|
if initialized:
|
||||||
|
# Also need to generate hashes for the first version.
|
||||||
|
apply_next = True
|
||||||
|
json_versions['min'] = next_version
|
||||||
|
|
||||||
|
untracked_changed = False
|
||||||
|
for version in UNTRACKED_VERSIONS:
|
||||||
|
label = version_label(version)
|
||||||
|
hashes = compute_api_hashes(cpp_header_dir, version, True, debug_dir,
|
||||||
|
verbose)
|
||||||
|
if not bool(hashes):
|
||||||
|
sys.stderr.write('ERROR: Failed to process %s\n' % label)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
if version in json_untracked['hashes'] and same_api_hashes(
|
||||||
|
hashes, json_untracked['hashes'][version]):
|
||||||
|
print('Hashes for %s are unchanged.' % label)
|
||||||
|
else:
|
||||||
|
untracked_changed = True
|
||||||
|
print('Updating hashes for %s.' % label)
|
||||||
|
json_untracked['hashes'][version] = hashes
|
||||||
|
|
||||||
|
next_changed = apply_next
|
||||||
|
if apply_next:
|
||||||
|
next_label = version_label(next_version)
|
||||||
|
|
||||||
|
hashes = compute_api_hashes(cpp_header_dir, next_version, False, debug_dir,
|
||||||
|
verbose)
|
||||||
|
if not bool(hashes):
|
||||||
|
sys.stderr.write('ERROR: Failed to process %s\n' % next_label)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
last_version = json_versions.get('last', None)
|
||||||
|
if not last_version is None and last_version in json_versions['hashes']:
|
||||||
|
if same_api_hashes(hashes, json_versions['hashes'][last_version]):
|
||||||
|
print('Hashes for last %s are unchanged.' % version_label(last_version))
|
||||||
|
next_changed = False
|
||||||
|
|
||||||
|
if next_changed:
|
||||||
|
print('Adding hashes for %s.' % next_label)
|
||||||
|
json_versions['last'] = next_version
|
||||||
|
json_versions['hashes'][next_version] = hashes
|
||||||
|
|
||||||
|
if NEXT_VERSION in json_untracked['hashes'] and not \
|
||||||
|
same_api_hashes(hashes, json_untracked['hashes'][NEXT_VERSION]):
|
||||||
|
print('NOTE: Additional versions are available to generate.')
|
||||||
|
|
||||||
|
write_versions = next_changed or not os.path.isfile(api_versions_file)
|
||||||
|
write_untracked = untracked_changed or not os.path.isfile(api_untracked_file)
|
||||||
|
|
||||||
|
if not write_versions and not write_untracked:
|
||||||
|
print('No hash updates required.')
|
||||||
|
return -1
|
||||||
|
|
||||||
|
if write_versions and not write_json_file(
|
||||||
|
api_versions_file, json_versions, quiet=False):
|
||||||
|
return 1
|
||||||
|
if write_untracked and not write_json_file(
|
||||||
|
api_untracked_file, json_untracked, quiet=False):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def exec_check(cpp_header_dir, api_versions_file, api_untracked_file, debug_dir,
|
||||||
|
fast_check, force_update, skip_untracked, verbose):
|
||||||
|
""" Checks existing API version hashes.
|
||||||
|
Resaves all API hashes if |force_update| is true. Otherwise, hash
|
||||||
|
changes are considered an error.
|
||||||
|
"""
|
||||||
|
assert not (fast_check and force_update)
|
||||||
|
|
||||||
|
json_versions, json_untracked, initialized = \
|
||||||
|
read_version_files(api_versions_file, api_untracked_file, False)
|
||||||
|
assert not initialized
|
||||||
|
|
||||||
|
versions = []
|
||||||
|
len_versioned_existing = len_versioned_checked = len_versioned_failed = 0
|
||||||
|
len_untracked_existing = len_untracked_checked = len_untracked_failed = 0
|
||||||
|
|
||||||
|
if not json_versions is None:
|
||||||
|
keys = json_versions['hashes'].keys()
|
||||||
|
len_versioned_existing = len(keys)
|
||||||
|
if len_versioned_existing > 0:
|
||||||
|
if fast_check:
|
||||||
|
# Only checking a subset of versions.
|
||||||
|
for key in ('last', 'min'):
|
||||||
|
if key in json_versions:
|
||||||
|
version = json_versions[key]
|
||||||
|
assert version in json_versions['hashes'], version
|
||||||
|
versions.append(version)
|
||||||
|
len_versioned_checked += 1
|
||||||
|
else:
|
||||||
|
versions.extend(keys)
|
||||||
|
len_versioned_checked = len_versioned_existing
|
||||||
|
|
||||||
|
if not json_untracked is None:
|
||||||
|
keys = json_untracked['hashes'].keys()
|
||||||
|
len_untracked_existing = len(keys)
|
||||||
|
if len_untracked_existing > 0 and not skip_untracked:
|
||||||
|
versions.extend(keys)
|
||||||
|
len_untracked_checked = len_untracked_existing
|
||||||
|
|
||||||
|
if len(versions) == 0:
|
||||||
|
print('No hashes to check.')
|
||||||
|
return 0
|
||||||
|
|
||||||
|
write_versions = False
|
||||||
|
write_untracked = False
|
||||||
|
|
||||||
|
for version in versions:
|
||||||
|
untracked = version in UNTRACKED_VERSIONS
|
||||||
|
if untracked:
|
||||||
|
stored_hashes = json_untracked['hashes'][version]
|
||||||
|
else:
|
||||||
|
stored_hashes = json_versions['hashes'][version]
|
||||||
|
label = version_label(version)
|
||||||
|
computed_hashes = compute_api_hashes(cpp_header_dir, version, True,
|
||||||
|
debug_dir, verbose)
|
||||||
|
if not bool(computed_hashes):
|
||||||
|
sys.stderr.write('ERROR: Failed to process %s\n' % label)
|
||||||
|
return 1
|
||||||
|
if not same_api_hashes(computed_hashes, stored_hashes):
|
||||||
|
if force_update:
|
||||||
|
print('Updating hashes for %s' % label)
|
||||||
|
if untracked:
|
||||||
|
json_untracked['hashes'][version] = computed_hashes
|
||||||
|
write_untracked = True
|
||||||
|
else:
|
||||||
|
json_versions['hashes'][version] = computed_hashes
|
||||||
|
write_versions = True
|
||||||
|
else:
|
||||||
|
sys.stderr.write('ERROR: Hashes for %s do not match!\n' % label)
|
||||||
|
if untracked:
|
||||||
|
len_untracked_failed += 1
|
||||||
|
else:
|
||||||
|
len_versioned_failed += 1
|
||||||
|
|
||||||
|
len_failed = len_untracked_failed + len_versioned_failed
|
||||||
|
if len_failed == 0:
|
||||||
|
if write_versions and not write_json_file(
|
||||||
|
api_versions_file, json_versions, quiet=False):
|
||||||
|
return 1
|
||||||
|
if write_untracked and not write_json_file(
|
||||||
|
api_untracked_file, json_untracked, quiet=False):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
if write_versions:
|
||||||
|
print('WARNING: This change can break back/forward binary compatibility.')
|
||||||
|
else:
|
||||||
|
sys.stderr.write('ERROR: %d hashes checked and failed\n' % len_failed)
|
||||||
|
|
||||||
|
print('%d hashes checked and match (%d/%d versioned, %d/%d untracked).' %
|
||||||
|
(len(versions) - len_failed,
|
||||||
|
len_versioned_checked - len_versioned_failed, len_versioned_existing,
|
||||||
|
len_untracked_checked - len_untracked_failed, len_untracked_existing))
|
||||||
|
|
||||||
|
return 0 if len_failed == 0 else 1
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
from optparse import OptionParser
|
||||||
|
|
||||||
|
desc = """
|
||||||
|
This utility manages CEF API versions.
|
||||||
|
"""
|
||||||
|
|
||||||
|
epilog = """
|
||||||
|
Call this utility without arguments after modifying header files in the CEF
|
||||||
|
include/ directory. Translated files will be updated if necessary.
|
||||||
|
|
||||||
|
If translated files have changed, or when running with -u, unversioned API
|
||||||
|
hashes (next and experimental) will be checked and potentially updated.
|
||||||
|
|
||||||
|
If translated files have changed, or when running with -c, versioned and
|
||||||
|
unversioned API hashes will be checked. Any changes to versioned API hashes
|
||||||
|
can break back/forward binary compatibility and are considered an error.
|
||||||
|
|
||||||
|
API under development will use placeholder values like CEF_NEXT, added=next,
|
||||||
|
removed=next in CEF header files. This utility can replace those placeholders
|
||||||
|
with an actual new version and generate the associated versioned API hashes.
|
||||||
|
|
||||||
|
Run with -n to output the next available API version.
|
||||||
|
|
||||||
|
Run with -a to apply the next available API version.
|
||||||
|
|
||||||
|
For complete usage details see
|
||||||
|
https://bitbucket.org/chromiumembedded/cef/wiki/ApiVersioning.md
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
class CustomParser(OptionParser):
|
||||||
|
|
||||||
|
def format_epilog(self, formatter):
|
||||||
|
return self.epilog
|
||||||
|
|
||||||
|
parser = CustomParser(description=desc, epilog=epilog)
|
||||||
|
parser.add_option(
|
||||||
|
'--debug-dir',
|
||||||
|
dest='debugdir',
|
||||||
|
metavar='DIR',
|
||||||
|
help='intermediate directory for easy debugging')
|
||||||
|
parser.add_option(
|
||||||
|
'-v',
|
||||||
|
'--verbose',
|
||||||
|
action='store_true',
|
||||||
|
dest='verbose',
|
||||||
|
default=False,
|
||||||
|
help='output detailed status information')
|
||||||
|
parser.add_option(
|
||||||
|
'-u',
|
||||||
|
'--update',
|
||||||
|
action='store_true',
|
||||||
|
dest='update',
|
||||||
|
default=False,
|
||||||
|
help='update next and unversioned API hashes')
|
||||||
|
parser.add_option(
|
||||||
|
'-n',
|
||||||
|
'--next',
|
||||||
|
action='store_true',
|
||||||
|
dest='next',
|
||||||
|
default=False,
|
||||||
|
help='output the next available API version')
|
||||||
|
parser.add_option(
|
||||||
|
'-a',
|
||||||
|
'--apply-next',
|
||||||
|
action='store_true',
|
||||||
|
dest='apply',
|
||||||
|
default=False,
|
||||||
|
help='add a hash for the next available API version')
|
||||||
|
parser.add_option(
|
||||||
|
'-c',
|
||||||
|
'--check',
|
||||||
|
action='store_true',
|
||||||
|
dest='check',
|
||||||
|
default=False,
|
||||||
|
help='check hashes for existing API versions')
|
||||||
|
parser.add_option(
|
||||||
|
'--fast-check',
|
||||||
|
action='store_true',
|
||||||
|
dest='fastcheck',
|
||||||
|
default=False,
|
||||||
|
help=
|
||||||
|
'only check minimum, last, next and experimental API hashes (use with -u, -a or -c)'
|
||||||
|
)
|
||||||
|
parser.add_option(
|
||||||
|
'--replace-next',
|
||||||
|
action='store_true',
|
||||||
|
dest='replacenext',
|
||||||
|
default=False,
|
||||||
|
help='replace NEXT usage in CEF headers (use with -a)')
|
||||||
|
parser.add_option(
|
||||||
|
'--replace-next-version',
|
||||||
|
dest='replacenextversion',
|
||||||
|
metavar='VERSION',
|
||||||
|
help='replace NEXT usage with this value (use with --replace-next)')
|
||||||
|
parser.add_option(
|
||||||
|
'--force-update',
|
||||||
|
action='store_true',
|
||||||
|
dest='forceupdate',
|
||||||
|
default=False,
|
||||||
|
help='force update all API hashes (use with -c)')
|
||||||
|
(options, args) = parser.parse_args()
|
||||||
|
|
||||||
|
script_dir = os.path.dirname(__file__)
|
||||||
|
cef_dir = os.path.abspath(os.path.join(script_dir, os.pardir))
|
||||||
|
|
||||||
|
cpp_header_dir = os.path.join(cef_dir, 'include')
|
||||||
|
if not os.path.isdir(cpp_header_dir):
|
||||||
|
sys.stderr.write(
|
||||||
|
'ERROR: Missing %s directory is required\n' % cpp_header_dir)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
api_versions_file = os.path.join(cef_dir, VERSIONS_JSON_FILE)
|
||||||
|
api_untracked_file = os.path.join(cef_dir, UNTRACKED_JSON_FILE)
|
||||||
|
|
||||||
|
mode_ct = options.update + options.next + options.apply + options.check
|
||||||
|
if mode_ct > 1:
|
||||||
|
sys.stderr.write(
|
||||||
|
'ERROR: Choose a single execution mode (-u, -n, -a or -c)\n')
|
||||||
|
parser.print_help(sys.stdout)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
next_version = compute_next_api_verson(api_versions_file)
|
||||||
|
if next_version is None:
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if options.next:
|
||||||
|
print(next_version)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
will_apply_next = options.apply or not os.path.isfile(api_versions_file)
|
||||||
|
if will_apply_next:
|
||||||
|
if options.replacenext:
|
||||||
|
replace_version = options.replacenextversion
|
||||||
|
if replace_version is None:
|
||||||
|
replace_version = next_version
|
||||||
|
elif not version_valid_for_next(replace_version, next_version):
|
||||||
|
sys.stderr.write('ERROR: Invalid value for --replace-next-version\n')
|
||||||
|
sys.exit(1)
|
||||||
|
result = find_replace_next_usage(cpp_header_dir, replace_version)
|
||||||
|
if result != 0:
|
||||||
|
sys.exit(result)
|
||||||
|
elif find_next_usage(cpp_header_dir):
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
changed = translate(cef_dir, verbose=options.verbose) > 0
|
||||||
|
skip_untracked = False
|
||||||
|
|
||||||
|
if options.update or will_apply_next or changed or not os.path.isfile(
|
||||||
|
api_untracked_file):
|
||||||
|
skip_untracked = True
|
||||||
|
if exec_apply(
|
||||||
|
cpp_header_dir,
|
||||||
|
api_versions_file,
|
||||||
|
api_untracked_file,
|
||||||
|
next_version,
|
||||||
|
options.debugdir,
|
||||||
|
apply_next=options.apply,
|
||||||
|
verbose=options.verbose) > 0:
|
||||||
|
# Apply failed.
|
||||||
|
sys.exit(1)
|
||||||
|
elif not options.check:
|
||||||
|
print('Nothing to do.')
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
sys.exit(
|
||||||
|
exec_check(
|
||||||
|
cpp_header_dir,
|
||||||
|
api_versions_file,
|
||||||
|
api_untracked_file,
|
||||||
|
options.debugdir,
|
||||||
|
options.fastcheck and not options.forceupdate,
|
||||||
|
options.check and options.forceupdate,
|
||||||
|
skip_untracked,
|
||||||
|
verbose=options.verbose))
|
154
tools/version_util.py
Normal file
154
tools/version_util.py
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
# Copyright (c) 2024 The Chromium Embedded Framework Authors. All rights
|
||||||
|
# reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
# can be found in the LICENSE file.
|
||||||
|
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from __future__ import print_function
|
||||||
|
from file_util import read_json_file
|
||||||
|
|
||||||
|
# Experimental version. Always the last value.
|
||||||
|
EXP_VERSION = '999999'
|
||||||
|
EXP_NAME = 'EXPERIMENTAL'
|
||||||
|
|
||||||
|
# Next version. Always the next to last value.
|
||||||
|
NEXT_VERSION = '999998'
|
||||||
|
NEXT_NAME = 'NEXT'
|
||||||
|
|
||||||
|
UNTRACKED_VERSIONS = (EXP_VERSION, NEXT_VERSION)
|
||||||
|
UNTRACKED_NAMES = (EXP_NAME, NEXT_NAME)
|
||||||
|
|
||||||
|
VERSIONS_JSON_FILE = 'cef_api_versions.json'
|
||||||
|
UNTRACKED_JSON_FILE = 'cef_api_untracked.json'
|
||||||
|
|
||||||
|
|
||||||
|
def version_make(major_version, revision):
|
||||||
|
""" Make a tracked version from components. """
|
||||||
|
# 9999 is reserved for untracked placeholder values. This allows for ~898 years
|
||||||
|
# of Chromium major versions at the current (end of 2024) rate of 11 per year.
|
||||||
|
# If this breaks for you please file an issue via Ouija board and/or psychic medium.
|
||||||
|
assert major_version > 0 and major_version < 9999, major_version
|
||||||
|
assert revision >= 0 and revision <= 99, revision
|
||||||
|
if major_version < 1000:
|
||||||
|
return '%03d%02d' % (major_version, revision)
|
||||||
|
return '%d%02d' % (major_version, revision)
|
||||||
|
|
||||||
|
|
||||||
|
def version_tracked(version):
|
||||||
|
""" Returns true if version is in tracked format. """
|
||||||
|
return (len(version) == 5 or len(version) == 6) and version.isnumeric() and \
|
||||||
|
not version in UNTRACKED_VERSIONS
|
||||||
|
|
||||||
|
|
||||||
|
def version_parse(version):
|
||||||
|
""" Parse a tracked version into components. """
|
||||||
|
assert version_tracked(version), version
|
||||||
|
split = 3 if len(version) == 5 else 4
|
||||||
|
return (int(version[0:split]), int(version[split:]))
|
||||||
|
|
||||||
|
|
||||||
|
def version_valid(version):
|
||||||
|
""" Returns true if version is valid. """
|
||||||
|
# Untracked versions must be referenced by name instead of number.
|
||||||
|
return version in UNTRACKED_NAMES or version_tracked(version)
|
||||||
|
|
||||||
|
|
||||||
|
def version_valid_for_next(version, ref_version, allow_exp=True):
|
||||||
|
""" Returns true if version is valid as a replacement for NEXT. """
|
||||||
|
version = version.upper()
|
||||||
|
if allow_exp and version == EXP_NAME:
|
||||||
|
return True
|
||||||
|
# Must be valid and not NEXT.
|
||||||
|
if not version_valid(version) or version == NEXT_NAME:
|
||||||
|
return False
|
||||||
|
# Must be >= ref_version.
|
||||||
|
if version_as_numeric(version) < int(ref_version):
|
||||||
|
return False
|
||||||
|
# Must have the same major version number as ref_version.
|
||||||
|
return version_parse(version)[0] == version_parse(ref_version)[0]
|
||||||
|
|
||||||
|
|
||||||
|
def read_version_last(api_versions_file):
|
||||||
|
json_versions = read_json_file(api_versions_file)
|
||||||
|
if not bool(json_versions):
|
||||||
|
return None
|
||||||
|
assert 'last' in json_versions, api_versions_file
|
||||||
|
return json_versions['last']
|
||||||
|
|
||||||
|
|
||||||
|
def read_version_files(api_versions_file,
|
||||||
|
api_untracked_file,
|
||||||
|
initialize,
|
||||||
|
combine=False):
|
||||||
|
initialized = False
|
||||||
|
|
||||||
|
if combine:
|
||||||
|
initialize = True
|
||||||
|
|
||||||
|
json_versions = read_json_file(api_versions_file)
|
||||||
|
if not bool(json_versions):
|
||||||
|
if initialize:
|
||||||
|
json_versions = {
|
||||||
|
'hashes': {},
|
||||||
|
}
|
||||||
|
initialized = True
|
||||||
|
else:
|
||||||
|
json_version = None
|
||||||
|
else:
|
||||||
|
assert 'hashes' in json_versions, api_versions_file
|
||||||
|
assert 'last' in json_versions, api_versions_file
|
||||||
|
assert 'min' in json_versions, api_versions_file
|
||||||
|
|
||||||
|
json_untracked = read_json_file(api_untracked_file)
|
||||||
|
if not bool(json_untracked):
|
||||||
|
if initialize:
|
||||||
|
json_untracked = {
|
||||||
|
'hashes': {},
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
json_untracked = None
|
||||||
|
else:
|
||||||
|
assert 'hashes' in json_untracked, api_untracked_file
|
||||||
|
for version in json_untracked['hashes']:
|
||||||
|
assert version in UNTRACKED_VERSIONS, api_untracked_file
|
||||||
|
|
||||||
|
if combine:
|
||||||
|
if bool(json_untracked['hashes']):
|
||||||
|
json_versions['hashes'].update(json_untracked['hashes'])
|
||||||
|
return (json_versions, initialized)
|
||||||
|
|
||||||
|
return (json_versions, json_untracked, initialized)
|
||||||
|
|
||||||
|
|
||||||
|
def version_label(version):
|
||||||
|
if version == EXP_VERSION or version == EXP_NAME:
|
||||||
|
return 'experimental version'
|
||||||
|
if version == NEXT_VERSION or version == NEXT_NAME:
|
||||||
|
return 'next version'
|
||||||
|
return 'version ' + version
|
||||||
|
|
||||||
|
|
||||||
|
def version_as_numeric(version):
|
||||||
|
""" Returns version as a numeric value. """
|
||||||
|
version = version.upper()
|
||||||
|
assert version_valid(version), version
|
||||||
|
if version == EXP_NAME:
|
||||||
|
version = EXP_VERSION
|
||||||
|
elif version == NEXT_NAME:
|
||||||
|
version = NEXT_VERSION
|
||||||
|
return int(version)
|
||||||
|
|
||||||
|
|
||||||
|
def version_as_variable(version):
|
||||||
|
""" Returns version as a variable for use in C/C++ files. """
|
||||||
|
version = version.upper()
|
||||||
|
assert version_valid(version), version
|
||||||
|
if not version.isnumeric():
|
||||||
|
return 'CEF_' + version
|
||||||
|
return version
|
||||||
|
|
||||||
|
|
||||||
|
def version_as_metadata(version):
|
||||||
|
""" Returns version as metadata for comments in C++ header files. """
|
||||||
|
version = version.upper()
|
||||||
|
assert version_valid(version), version
|
||||||
|
return version.lower()
|
Reference in New Issue
Block a user