From 5eaaa70cf128e43e7319126d6a88ba84f62708a1 Mon Sep 17 00:00:00 2001 From: Justin Boswell Date: Wed, 24 Feb 2021 10:16:32 -0800 Subject: [PATCH] Added aws_error* functions to native extension (#12) * Added aws_crt_error_str and test, removed awscrt_version test function * Added aws_crt_error_name * Added aws_crt_error_debug_str * Use PHP's own tools to generate arginfo * Only re-generate arginfo on php7+ * Added a definition for ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX for php5 * Ignore generated files for clang-format --- .clang-format-ignore | 4 ++ .github/workflows/clang-format.yml | 4 +- Makefile.frag | 23 ++++++-- ext/awscrt.stub.php | 11 ++++ ext/awscrt_arginfo.h | 28 +++++++++ ext/crt.c | 59 ++++++++++++------- ext/php_aws_crt.h | 7 +++ format-check.sh | 2 +- tests/aws_crt_error_debug_str.phpt | 14 +++++ tests/aws_crt_error_name.phpt | 14 +++++ ...awscrt_000.phpt => aws_crt_error_str.phpt} | 6 +- ...wscrt_001.phpt => aws_crt_last_error.phpt} | 0 12 files changed, 138 insertions(+), 34 deletions(-) create mode 100644 .clang-format-ignore create mode 100644 ext/awscrt.stub.php create mode 100644 ext/awscrt_arginfo.h create mode 100644 tests/aws_crt_error_debug_str.phpt create mode 100644 tests/aws_crt_error_name.phpt rename tests/{awscrt_000.phpt => aws_crt_error_str.phpt} (71%) rename tests/{awscrt_001.phpt => aws_crt_last_error.phpt} (100%) diff --git a/.clang-format-ignore b/.clang-format-ignore new file mode 100644 index 0000000..65c5a2b --- /dev/null +++ b/.clang-format-ignore @@ -0,0 +1,4 @@ +# ignore generated files +ext/api.h +ext/*_arginfo.h +src/api.h diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index c784771..c3b8c20 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -10,9 +10,9 @@ jobs: steps: - name: Checkout Sources uses: actions/checkout@v1 - + - name: clang-format lint uses: DoozyX/clang-format-lint-action@v0.3.1 with: # List of extensions to check - extensions: c,h + extensions: c diff --git a/Makefile.frag b/Makefile.frag index be152ea..b469976 100644 --- a/Makefile.frag +++ b/Makefile.frag @@ -3,6 +3,7 @@ BUILD_DIR=$(shell pwd)/build DEPS_DIR=$(BUILD_DIR)/deps INT_DIR=$(BUILD_DIR)/install INSTALL_DIR=$(shell pwd) +AT_LEAST_PHP7=$(shell expr `php --version | head -1 | cut -f 2 -d' '` \>= 7) CMAKE = cmake3 ifeq (, $(shell which cmake3)) @@ -26,7 +27,6 @@ $(INT_DIR)/lib/libcrypto.a: $(DEPS_DIR)/openssl mkdir -p $(INT_DIR)/lib ln -s $(INT_DIR)/lib64/libcrypto.a $(INT_DIR)/lib/libcrypto.a || true - CMAKE_CONFIGURE = $(CMAKE) -DCMAKE_INSTALL_PREFIX=$(INT_DIR) -DCMAKE_PREFIX_PATH=$(INT_DIR) -DBUILD_TESTING=OFF CMAKE_BUILD = $(CMAKE) --build CMAKE_BUILD_TYPE ?= RelWithDebInfo @@ -52,15 +52,26 @@ $(BUILD_DIR)/aws-crt-ffi-static/libaws-crt-ffi.a: $(BUILD_DIR)/aws-crt-ffi-stati extension: ext/crt.lo # Force the crt object target to depend on the CRT static library -ext/crt.lo: $(BUILD_DIR)/aws-crt-ffi-static/libaws-crt-ffi.a ext/api.h +ext/crt.lo: $(BUILD_DIR)/aws-crt-ffi-static/libaws-crt-ffi.a ext/api.h ext/awscrt_arginfo.h + +ifeq ($(AT_LEAST_PHP7),1) + GEN_STUB=build/gen_stub.php + # generate awscrt_arginfo.h + ext/awscrt_arginfo.h: ext/awscrt.stub.php $(GEN_STUB) + php $(GEN_STUB) ext/awscrt.stub.php + + # borrow the gen_stub script from PHP's build process + $(GEN_STUB): + curl -o $(GEN_STUB) -sSL https://raw.githubusercontent.com/php/php-src/bbb86ba7e2fe8ae365294d1834c6a392570a9dcd/build/gen_stub.php +endif # transform/install api.h from FFI lib -$(INSTALL_DIR)/src/api.h: crt/aws-crt-ffi/src/api.h - cat crt/aws-crt-ffi/src/api.h | grep -v AWS_EXTERN_C | sed -e 's/AWS_CRT_API //' | grep -ve '^#' > $(INSTALL_DIR)/src/api.h +src/api.h: crt/aws-crt-ffi/src/api.h + cat crt/aws-crt-ffi/src/api.h | grep -v AWS_EXTERN_C | sed -e 's/AWS_CRT_API //' | grep -ve '^#' > src/api.h # install api.h to ext/ as well -ext/api.h : $(INSTALL_DIR)/src/api.h - cp -v $(INSTALL_DIR)/src/api.h ext/api.h +ext/api.h : src/api.h + cp -v src/api.h ext/api.h # FFI target ffi: src/libaws-crt-ffi.so diff --git a/ext/awscrt.stub.php b/ext/awscrt.stub.php new file mode 100644 index 0000000..72184db --- /dev/null +++ b/ext/awscrt.stub.php @@ -0,0 +1,11 @@ +log_level = 0; } -/* awscrt_version */ -ZEND_BEGIN_ARG_INFO(awscrt_version_arginfo, 0) -ZEND_END_ARG_INFO() - -PHP_FUNCTION(awscrt_version) { - static const char *version = "1.0.0-dev"; - AWS_RETURN_STRING(version); -} - /* aws_crt_last_error() */ -ZEND_BEGIN_ARG_INFO(aws_crt_last_error_arginfo, 0) -ZEND_END_ARG_INFO() - PHP_FUNCTION(aws_crt_last_error) { RETURN_LONG(aws_crt_last_error()); } -/* clang-format off */ -const zend_function_entry awscrt_functions[] = { - PHP_FE(awscrt_version, awscrt_version_arginfo) - PHP_FE(aws_crt_last_error, aws_crt_last_error_arginfo) - PHP_FE_END -}; +/* aws_crt_error_str(int error_code) */ +PHP_FUNCTION(aws_crt_error_str) { + zend_ulong error_code = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &error_code) == FAILURE) { + RETURN_NULL(); + } + + AWS_RETURN_STRING(aws_crt_error_str(error_code)); +} + +/* aws_crt_error_name(int error_code) */ +PHP_FUNCTION(aws_crt_error_name) { + zend_ulong error_code = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &error_code) == FAILURE) { + RETURN_NULL(); + } + + AWS_RETURN_STRING(aws_crt_error_name(error_code)); +} + +/* aws_crt_error_debug_str(int error_code) */ +PHP_FUNCTION(aws_crt_error_debug_str) { + zend_ulong error_code = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &error_code) == FAILURE) { + RETURN_NULL(); + } + + AWS_RETURN_STRING(aws_crt_error_debug_str(error_code)); +} zend_module_entry awscrt_module_entry = { STANDARD_MODULE_HEADER, "awscrt", - awscrt_functions, /* functions */ + ext_functions, /* functions */ PHP_MINIT(awscrt), PHP_MSHUTDOWN(awscrt), NULL, /* RINIT */ @@ -79,9 +95,8 @@ zend_module_entry awscrt_module_entry = { PHP_GINIT(awscrt), NULL, /* GSHUTDOWN */ NULL, /* RPOSTSHUTDOWN */ - STANDARD_MODULE_PROPERTIES_EX}; - -/* clang-format on */ + STANDARD_MODULE_PROPERTIES_EX, +}; #ifdef COMPILE_DL_AWSCRT ZEND_GET_MODULE(awscrt) diff --git a/ext/php_aws_crt.h b/ext/php_aws_crt.h index 6136ae8..4e8ad25 100644 --- a/ext/php_aws_crt.h +++ b/ext/php_aws_crt.h @@ -34,6 +34,13 @@ ZEND_EXTERN_MODULE_GLOBALS(awscrt) # define AWS_RETURN_STRING(s) RETURN_STRING(s) #else # define AWS_RETURN_STRING(s) RETURN_STRING(s, 1) +/* definitions for ZEND API macros taken from PHP7 and backported to 5.6 */ +# define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, allow_null) \ + static const zend_arg_info name[] = {{NULL, 0, NULL, required_num_args, return_reference, 0, 0}, + +/* PHP5 doesn't really handle type hints well, so elide them */ +# define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) \ + {#name, sizeof(#name) - 1, NULL, 0, 0, pass_by_ref, allow_null, 0}, #endif #endif /* PHP_AWS_CRT_H */ diff --git a/format-check.sh b/format-check.sh index 9783241..b0f86dd 100755 --- a/format-check.sh +++ b/format-check.sh @@ -10,7 +10,7 @@ if NOT type $CLANG_FORMAT 2> /dev/null ; then fi FAIL=0 -SOURCE_FILES=`find ext -type f \( -name '*.h' -o -name '*.c' \)` +SOURCE_FILES=`find src ext -type f \( -name '*.h' -o -name '*.c' \)` for i in $SOURCE_FILES do $CLANG_FORMAT -output-replacements-xml $i | grep -c " /dev/null diff --git a/tests/aws_crt_error_debug_str.phpt b/tests/aws_crt_error_debug_str.phpt new file mode 100644 index 0000000..15fb5df --- /dev/null +++ b/tests/aws_crt_error_debug_str.phpt @@ -0,0 +1,14 @@ +--TEST-- +aws_crt_error_debug_str +--SKIPIF-- + +--FILE-- + +--EXPECT-- +aws-c-common: AWS_ERROR_SUCCESS, Success. diff --git a/tests/aws_crt_error_name.phpt b/tests/aws_crt_error_name.phpt new file mode 100644 index 0000000..1d1c779 --- /dev/null +++ b/tests/aws_crt_error_name.phpt @@ -0,0 +1,14 @@ +--TEST-- +aws_crt_error_name +--SKIPIF-- + +--FILE-- + +--EXPECT-- +AWS_ERROR_SUCCESS diff --git a/tests/awscrt_000.phpt b/tests/aws_crt_error_str.phpt similarity index 71% rename from tests/awscrt_000.phpt rename to tests/aws_crt_error_str.phpt index b5c610b..ba9703f 100644 --- a/tests/awscrt_000.phpt +++ b/tests/aws_crt_error_str.phpt @@ -1,5 +1,5 @@ --TEST-- -Version: Simple function call +aws_crt_error_str --SKIPIF-- --EXPECT-- -1.0.0-dev +Success. diff --git a/tests/awscrt_001.phpt b/tests/aws_crt_last_error.phpt similarity index 100% rename from tests/awscrt_001.phpt rename to tests/aws_crt_last_error.phpt