package.xml0000644000175000001440000000604412647401166012052 0ustar mikeusers propro pecl.php.net Property proxy A reusable split-off of pecl_http's property proxy API. Michael Wallner mike mike@php.net yes 2016-01-19 2.0.0 2.0.0 stable stable BSD-2-Clause * Internals documentation at http://m6w6.github.io/ext-propro/master/ * Travis support * PHP7 compatible version 7.0.0 1.4.0 propro propro-2.0.0/src/php_propro_api.h0000644000175000001440000000736612647401166015702 0ustar mikeusers/* +--------------------------------------------------------------------+ | PECL :: propro | +--------------------------------------------------------------------+ | Redistribution and use in source and binary forms, with or without | | modification, are permitted provided that the conditions mentioned | | in the accompanying LICENSE file are met. | +--------------------------------------------------------------------+ | Copyright (c) 2013 Michael Wallner | +--------------------------------------------------------------------+ */ #ifndef PHP_PROPRO_API_H #define PHP_PROPRO_API_H #include "php_propro.h" /** * The internal property proxy. * * Container for the object/array holding the proxied property. */ struct php_property_proxy { /** The container holding the property */ zval container; /** The name of the proxied property */ zend_string *member; }; typedef struct php_property_proxy php_property_proxy_t; /** * The userland object. * * Return an object instance of php\\PropertyProxy to make your C-struct * member accessible by reference from PHP userland. * * Example: * \code{.c} * static zval *my_read_prop(zval *object, zval *member, int type, void **cache_slot, zval *tmp) * { * zval *return_value; * zend_string *member_name = zval_get_string(member); * my_prophandler_t *handler = my_get_prophandler(member_name); * * if (!handler || type == BP_VAR_R || type == BP_VAR_IS) { * return_value = zend_get_std_object_handlers()->read_property(object, member, type, cache_slot, tmp); * * if (handler) { * handler->read(object, tmp); * * zval_ptr_dtor(return_value); * ZVAL_COPY_VALUE(return_value, tmp); * } * } else { * return_value = php_property_proxy_zval(object, member_name); * } * * zend_string_release(member_name); * * return return_value; * } * \endcode */ struct php_property_proxy_object { /** The actual property proxy */ php_property_proxy_t *proxy; /** Any parent property proxy object */ zval parent; /** The std zend_object */ zend_object zo; }; typedef struct php_property_proxy_object php_property_proxy_object_t; /** * Create a property proxy * * The property proxy will forward reads and writes to itself to the * proxied property with name \a member_str of \a container. * * @param container the container holding the property * @param member the name of the proxied property * @return a new property proxy */ PHP_PROPRO_API php_property_proxy_t *php_property_proxy_init(zval *container, zend_string *member); /** * Destroy and free a property proxy. * * The destruction of the property proxy object calls this. * * @param proxy a pointer to the allocated property proxy */ PHP_PROPRO_API void php_property_proxy_free(php_property_proxy_t **proxy); /** * Get the zend_class_entry of php\\PropertyProxy * @return the class entry pointer */ PHP_PROPRO_API zend_class_entry *php_property_proxy_get_class_entry(void); /** * Instantiate a new php\\PropertyProxy * @param ce the property proxy or derived class entry * @return the zend object */ PHP_PROPRO_API zend_object *php_property_proxy_object_new(zend_class_entry *ce); /** * Instantiate a new php\\PropertyProxy with \a proxy * @param ce the property proxy or derived class entry * @param proxy the internal property proxy * @return the property proxy */ PHP_PROPRO_API php_property_proxy_object_t *php_property_proxy_object_new_ex( zend_class_entry *ce, php_property_proxy_t *proxy); #endif /* PHP_PROPRO_API_H */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ propro-2.0.0/src/php_propro_api.c0000644000175000001440000003406012647401166015664 0ustar mikeusers/* +--------------------------------------------------------------------+ | PECL :: propro | +--------------------------------------------------------------------+ | Redistribution and use in source and binary forms, with or without | | modification, are permitted provided that the conditions mentioned | | in the accompanying LICENSE file are met. | +--------------------------------------------------------------------+ | Copyright (c) 2013 Michael Wallner | +--------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include "php_propro_api.h" #define DEBUG_PROPRO 0 static inline zval *get_referenced_zval(zval *ref) { while (Z_ISREF_P(ref)) { ref = Z_REFVAL_P(ref); } return ref; } php_property_proxy_t *php_property_proxy_init(zval *container, zend_string *member) { php_property_proxy_t *proxy = ecalloc(1, sizeof(*proxy)); ZVAL_COPY(&proxy->container, get_referenced_zval(container)); proxy->member = zend_string_copy(member); return proxy; } void php_property_proxy_free(php_property_proxy_t **proxy) { if (*proxy) { zval_ptr_dtor(&(*proxy)->container); zend_string_release((*proxy)->member); efree(*proxy); *proxy = NULL; } } static zend_class_entry *php_property_proxy_class_entry; static zend_object_handlers php_property_proxy_object_handlers; zend_class_entry *php_property_proxy_get_class_entry(void) { return php_property_proxy_class_entry; } static inline php_property_proxy_object_t *get_propro(zval *object); static zval *get_parent_proxied_value(zval *object, zval *return_value); static zval *get_proxied_value(zval *object, zval *return_value); static zval *read_dimension(zval *object, zval *offset, int type, zval *return_value); static ZEND_RESULT_CODE cast_proxied_value(zval *object, zval *return_value, int type); static void write_dimension(zval *object, zval *offset, zval *value); static void set_proxied_value(zval *object, zval *value); #if DEBUG_PROPRO /* we do not really care about TS when debugging */ static int level = 1; static const char space[] = " "; static const char *inoutstr[] = {"< return","="," > enter"}; static void _walk(php_property_proxy_object_t *obj) { if (obj) { if (!Z_ISUNDEF(obj->parent)) { _walk(get_propro(&obj->parent)); } if (obj->proxy) { fprintf(stderr, ".%s", obj->proxy->member->val); } } } static void debug_propro(int inout, const char *f, php_property_proxy_object_t *obj, zval *offset, zval *value TSRMLS_DC) { fprintf(stderr, "#PP %p %s %s %s ", obj, &space[sizeof(space)-level], inoutstr[inout+1], f); level += inout; _walk(obj); if (*f++=='d' && *f++=='i' && *f++=='m' ) { char *offset_str = "[]"; zval *o = offset; if (o) { convert_to_string_ex(o); offset_str = Z_STRVAL_P(o); } fprintf(stderr, ".%s", offset_str); if (o && o != offset) { zval_ptr_dtor(o); } } if (value && !Z_ISUNDEF_P(value)) { const char *t[] = { "UNDEF", "NULL", "FALSE", "TRUE", "int", "float", "string", "Array", "Object", "resource", "reference", "constant", "constant AST", "_BOOL", "callable", "indirect", "---", "pointer" }; fprintf(stderr, " = (%s) ", t[Z_TYPE_P(value)&0xf]); if (!Z_ISUNDEF_P(value) && Z_TYPE_P(value) != IS_INDIRECT) { zend_print_flat_zval_r(value TSRMLS_CC); } } fprintf(stderr, "\n"); } #else #define debug_propro(l, f, obj, off, val) #endif php_property_proxy_object_t *php_property_proxy_object_new_ex( zend_class_entry *ce, php_property_proxy_t *proxy) { php_property_proxy_object_t *o; if (!ce) { ce = php_property_proxy_class_entry; } o = ecalloc(1, sizeof(*o) + sizeof(zval) * (ce->default_properties_count - 1)); zend_object_std_init(&o->zo, ce); object_properties_init(&o->zo, ce); o->proxy = proxy; o->zo.handlers = &php_property_proxy_object_handlers; debug_propro(0, "init", o, NULL, NULL); return o; } zend_object *php_property_proxy_object_new(zend_class_entry *ce) { return &php_property_proxy_object_new_ex(ce, NULL)->zo; } static void destroy_obj(zend_object *object) { php_property_proxy_object_t *o = PHP_PROPRO_PTR(object); debug_propro(0, "dtor", o, NULL, NULL); if (o->proxy) { php_property_proxy_free(&o->proxy); } if (!Z_ISUNDEF(o->parent)) { zval_ptr_dtor(&o->parent); ZVAL_UNDEF(&o->parent); } zend_object_std_dtor(object); } static inline php_property_proxy_object_t *get_propro(zval *object) { object = get_referenced_zval(object); switch (Z_TYPE_P(object)) { case IS_OBJECT: break; EMPTY_SWITCH_DEFAULT_CASE(); } return PHP_PROPRO_PTR(Z_OBJ_P(object)); } static inline zend_bool got_value(zval *container, zval *value) { zval identical; if (!Z_ISUNDEF_P(value)) { if (SUCCESS == is_identical_function(&identical, value, container)) { if (Z_TYPE(identical) != IS_TRUE) { return 1; } } } return 0; } static zval *get_parent_proxied_value(zval *object, zval *return_value) { php_property_proxy_object_t *obj; obj = get_propro(object); debug_propro(1, "parent_get", obj, NULL, NULL); if (obj->proxy) { if (!Z_ISUNDEF(obj->parent)) { get_proxied_value(&obj->parent, return_value); } } debug_propro(-1, "parent_get", obj, NULL, return_value); return return_value; } static zval *get_proxied_value(zval *object, zval *return_value) { zval *hash_value, *ref, prop_tmp; php_property_proxy_object_t *obj; obj = get_propro(object); debug_propro(1, "get", obj, NULL, NULL); if (obj->proxy) { if (!Z_ISUNDEF(obj->parent)) { zval parent_value; ZVAL_UNDEF(&parent_value); get_parent_proxied_value(object, &parent_value); if (got_value(&obj->proxy->container, &parent_value)) { zval_ptr_dtor(&obj->proxy->container); ZVAL_COPY(&obj->proxy->container, &parent_value); } } ref = get_referenced_zval(&obj->proxy->container); switch (Z_TYPE_P(ref)) { case IS_OBJECT: RETVAL_ZVAL(zend_read_property(Z_OBJCE_P(ref), ref, obj->proxy->member->val, obj->proxy->member->len, 0, &prop_tmp), 0, 0); break; case IS_ARRAY: hash_value = zend_symtable_find(Z_ARRVAL_P(ref), obj->proxy->member); if (hash_value) { RETVAL_ZVAL(hash_value, 0, 0); } break; } } debug_propro(-1, "get", obj, NULL, return_value); return return_value; } static ZEND_RESULT_CODE cast_proxied_value(zval *object, zval *return_value, int type) { get_proxied_value(object, return_value); debug_propro(0, "cast", get_propro(object), NULL, return_value); if (!Z_ISUNDEF_P(return_value)) { convert_to_explicit_type_ex(return_value, type); return SUCCESS; } return FAILURE; } static void set_proxied_value(zval *object, zval *value) { php_property_proxy_object_t *obj; zval *ref; obj = get_propro(object); debug_propro(1, "set", obj, NULL, value TSRMLS_CC); if (obj->proxy) { if (!Z_ISUNDEF(obj->parent)) { zval parent_value; ZVAL_UNDEF(&parent_value); get_parent_proxied_value(object, &parent_value); if (got_value(&obj->proxy->container, &parent_value)) { zval_ptr_dtor(&obj->proxy->container); ZVAL_COPY(&obj->proxy->container, &parent_value); } } ref = get_referenced_zval(&obj->proxy->container); switch (Z_TYPE_P(ref)) { case IS_OBJECT: zend_update_property(Z_OBJCE_P(ref), ref, obj->proxy->member->val, obj->proxy->member->len, value); break; default: convert_to_array(ref); /* no break */ case IS_ARRAY: Z_TRY_ADDREF_P(value); zend_symtable_update(Z_ARRVAL_P(ref), obj->proxy->member, value); break; } if (!Z_ISUNDEF(obj->parent)) { set_proxied_value(&obj->parent, &obj->proxy->container); } } debug_propro(-1, "set", obj, NULL, NULL); } static zval *read_dimension(zval *object, zval *offset, int type, zval *return_value) { zval proxied_value; zend_string *member = offset ? zval_get_string(offset) : NULL; debug_propro(1, type == BP_VAR_R ? "dim_read" : "dim_read_ref", get_propro(object), offset, NULL); ZVAL_UNDEF(&proxied_value); get_proxied_value(object, &proxied_value); if (BP_VAR_R == type && member && !Z_ISUNDEF(proxied_value)) { if (Z_TYPE(proxied_value) == IS_ARRAY) { zval *hash_value = zend_symtable_find(Z_ARRVAL(proxied_value), member); if (hash_value) { RETVAL_ZVAL(hash_value, 1, 0); } } } else { php_property_proxy_t *proxy; php_property_proxy_object_t *proxy_obj; if (!Z_ISUNDEF(proxied_value)) { convert_to_array(&proxied_value); Z_ADDREF(proxied_value); } else { array_init(&proxied_value); set_proxied_value(object, &proxied_value); } if (!member) { member = zend_long_to_str(zend_hash_next_free_element( Z_ARRVAL(proxied_value))); } proxy = php_property_proxy_init(&proxied_value, member); zval_ptr_dtor(&proxied_value); proxy_obj = php_property_proxy_object_new_ex(NULL, proxy); ZVAL_COPY(&proxy_obj->parent, object); RETVAL_OBJ(&proxy_obj->zo); } if (member) { zend_string_release(member); } debug_propro(-1, type == BP_VAR_R ? "dim_read" : "dim_read_ref", get_propro(object), offset, return_value); return return_value; } static int has_dimension(zval *object, zval *offset, int check_empty) { zval proxied_value; int exists = 0; debug_propro(1, "dim_exists", get_propro(object), offset, NULL); ZVAL_UNDEF(&proxied_value); get_proxied_value(object, &proxied_value); if (Z_ISUNDEF(proxied_value)) { exists = 0; } else { zend_string *zs = zval_get_string(offset); if (Z_TYPE(proxied_value) == IS_ARRAY) { zval *zentry = zend_symtable_find(Z_ARRVAL(proxied_value), zs); if (!zentry) { exists = 0; } else { if (check_empty) { exists = !Z_ISNULL_P(zentry); } else { exists = 1; } } } zend_string_release(zs); } debug_propro(-1, "dim_exists", get_propro(object), offset, NULL); return exists; } static void write_dimension(zval *object, zval *offset, zval *value) { zval proxied_value; debug_propro(1, "dim_write", get_propro(object), offset, value); ZVAL_UNDEF(&proxied_value); get_proxied_value(object, &proxied_value); if (!Z_ISUNDEF(proxied_value)) { if (Z_TYPE(proxied_value) == IS_ARRAY) { Z_ADDREF(proxied_value); } else { convert_to_array(&proxied_value); } } else { array_init(&proxied_value); } SEPARATE_ZVAL(value); Z_TRY_ADDREF_P(value); if (offset) { zend_string *zs = zval_get_string(offset); zend_symtable_update(Z_ARRVAL(proxied_value), zs, value); zend_string_release(zs); } else { zend_hash_next_index_insert(Z_ARRVAL(proxied_value), value); } set_proxied_value(object, &proxied_value); debug_propro(-1, "dim_write", get_propro(object), offset, &proxied_value); zval_ptr_dtor(&proxied_value); } static void unset_dimension(zval *object, zval *offset) { zval proxied_value; debug_propro(1, "dim_unset", get_propro(object), offset, NULL); ZVAL_UNDEF(&proxied_value); get_proxied_value(object, &proxied_value); if (Z_TYPE(proxied_value) == IS_ARRAY) { zval *o = offset; ZEND_RESULT_CODE rv; convert_to_string_ex(o); rv = zend_symtable_del(Z_ARRVAL(proxied_value), Z_STR_P(o)); if (SUCCESS == rv) { set_proxied_value(object, &proxied_value); } if (o != offset) { zval_ptr_dtor(o); } } debug_propro(-1, "dim_unset", get_propro(object), offset, &proxied_value); } ZEND_BEGIN_ARG_INFO_EX(ai_propro_construct, 0, 0, 2) ZEND_ARG_INFO(1, object) ZEND_ARG_INFO(0, member) ZEND_ARG_OBJ_INFO(0, parent, php\\PropertyProxy, 1) ZEND_END_ARG_INFO(); static PHP_METHOD(propro, __construct) { zend_error_handling zeh; zval *container, *parent = NULL; zend_string *member; zend_replace_error_handling(EH_THROW, NULL, &zeh); if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "zS|O!", &container, &member, &parent, php_property_proxy_class_entry)) { php_property_proxy_object_t *obj; zval *ref = get_referenced_zval(container); switch (Z_TYPE_P(ref)) { case IS_OBJECT: case IS_ARRAY: break; default: convert_to_array(ref); } obj = get_propro(getThis()); obj->proxy = php_property_proxy_init(container, member); if (parent) { ZVAL_COPY(&obj->parent, parent); } } zend_restore_error_handling(&zeh); } static const zend_function_entry php_property_proxy_method_entry[] = { PHP_ME(propro, __construct, ai_propro_construct, ZEND_ACC_PUBLIC) {0} }; static PHP_MINIT_FUNCTION(propro) { zend_class_entry ce = {0}; INIT_NS_CLASS_ENTRY(ce, "php", "PropertyProxy", php_property_proxy_method_entry); php_property_proxy_class_entry = zend_register_internal_class(&ce); php_property_proxy_class_entry->create_object = php_property_proxy_object_new; php_property_proxy_class_entry->ce_flags |= ZEND_ACC_FINAL; memcpy(&php_property_proxy_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); php_property_proxy_object_handlers.offset = XtOffsetOf(php_property_proxy_object_t, zo); php_property_proxy_object_handlers.free_obj = destroy_obj; php_property_proxy_object_handlers.set = set_proxied_value; php_property_proxy_object_handlers.get = get_proxied_value; php_property_proxy_object_handlers.cast_object = cast_proxied_value; php_property_proxy_object_handlers.read_dimension = read_dimension; php_property_proxy_object_handlers.write_dimension = write_dimension; php_property_proxy_object_handlers.has_dimension = has_dimension; php_property_proxy_object_handlers.unset_dimension = unset_dimension; return SUCCESS; } PHP_MINFO_FUNCTION(propro) { php_info_print_table_start(); php_info_print_table_header(2, "Property proxy support", "enabled"); php_info_print_table_row(2, "Extension version", PHP_PROPRO_VERSION); php_info_print_table_end(); } static const zend_function_entry propro_functions[] = { {0} }; zend_module_entry propro_module_entry = { STANDARD_MODULE_HEADER, "propro", propro_functions, PHP_MINIT(propro), NULL, NULL, NULL, PHP_MINFO(propro), PHP_PROPRO_VERSION, STANDARD_MODULE_PROPERTIES }; #ifdef COMPILE_DL_PROPRO ZEND_GET_MODULE(propro) #endif /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ propro-2.0.0/scripts/gen_travis_yml.php0000755000175000001440000000075312647401166017137 0ustar mikeusers#!/usr/bin/env php # autogenerated file; do not edit sudo: false language: c addons: apt: packages: - php5-cli - php-pear env: matrix: ["7.0", "master"], "enable_debug", "enable_maintainer_zts", ]); foreach ($env as $e) { printf(" - %s\n", $e); } ?> before_script: - make -f travis/pecl/Makefile php - make -f travis/pecl/Makefile ext PECL=propro script: - make -f travis/pecl/Makefile test propro-2.0.0/tests/001.phpt0000644000175000001440000000147112647401166014247 0ustar mikeusers--TEST-- property proxy --SKIPIF-- --FILE-- prop; $a = $c->anon; var_dump($c); echo "set\n"; $a = 123; echo "get\n"; echo $a,"\n"; $p["foo"] = 123; $p["bar"]["baz"]["a"]["b"]=987; var_dump($c); ?> DONE --EXPECTF-- Test object(c)#%d (2) { ["prop":"c":private]=> NULL ["anon":"c":private]=> NULL } set get 123 object(c)#%d (2) { ["prop":"c":private]=> array(2) { ["foo"]=> int(123) ["bar"]=> array(1) { ["baz"]=> array(1) { ["a"]=> array(1) { ["b"]=> int(987) } } } } ["anon":"c":private]=> int(123) } DONE propro-2.0.0/tests/002.phpt0000644000175000001440000000247012647401166014250 0ustar mikeusers--TEST-- property proxy --SKIPIF-- --FILE-- storage, $p); } function __set($p, $v) { $this->storage[$p] = $v; } } $c = new c; $c->data["foo"] = 1; var_dump( isset($c->data["foo"]), isset($c->data["bar"]) ); var_dump($c); $c->data[] = 1; $c->data[] = 2; $c->data[] = 3; $c->data["bar"][] = 123; $c->data["bar"][] = 456; var_dump($c); unset($c->data["bar"][0]); var_dump($c); ?> DONE --EXPECTF-- Test bool(true) bool(false) object(c)#%d (1) { ["storage":"c":private]=> array(1) { ["data"]=> array(1) { ["foo"]=> int(1) } } } object(c)#%d (1) { ["storage":"c":private]=> array(1) { ["data"]=> array(5) { ["foo"]=> int(1) [0]=> int(1) [1]=> int(2) [2]=> int(3) ["bar"]=> array(2) { [0]=> int(123) [1]=> int(456) } } } } object(c)#%d (1) { ["storage":"c":private]=> array(1) { ["data"]=> array(5) { ["foo"]=> int(1) [0]=> int(1) [1]=> int(2) [2]=> int(3) ["bar"]=> array(1) { [1]=> int(456) } } } } DONE propro-2.0.0/tests/003.phpt0000644000175000001440000000075712647401166014257 0ustar mikeusers--TEST-- property proxy --SKIPIF-- --FILE-- ref; $r = 1; var_dump($t); $t->ref[] = 2; var_dump($t); ?> ===DONE=== --EXPECTF-- Test object(t)#%d (1) { ["ref":"t":private]=> int(1) } object(t)#%d (1) { ["ref":"t":private]=> array(2) { [0]=> int(1) [1]=> int(2) } } ===DONE===propro-2.0.0/AUTHORS0000644000175000001440000000003712647401166012755 0ustar mikeusersMichael Wallner propro-2.0.0/BUGS0000644000175000001440000000005212647401166012365 0ustar mikeusersYay, now known and unresolved issues yet! propro-2.0.0/CONTRIBUTING.md0000644000175000001440000000361612647401166014144 0ustar mikeusers# Contributor Code of Conduct As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery * Personal attacks * Trolling or insulting/derogatory comments * Public or private harassment * Publishing other's private information, such as physical or electronic addresses, without explicit permission * Other unethical or unprofessional conduct. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at http://contributor-covenant.org/version/1/2/0/. propro-2.0.0/CREDITS0000644000175000001440000000002712647401166012724 0ustar mikeuserspropro Michael Wallner propro-2.0.0/LICENSE0000644000175000001440000000250112647401166012710 0ustar mikeusersCopyright (c) 2013, Michael Wallner . 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. 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. propro-2.0.0/README.md0000644000175000001440000000244512647401166013171 0ustar mikeusers# ext-propro [![Build Status](https://travis-ci.org/m6w6/ext-propro.svg?branch=master)](https://travis-ci.org/m6w6/ext-propro) The "Property Proxy" extension provides a fairly transparent proxy for internal object properties hidden in custom non-zval implementations. ## Documentation See the [online markdown reference](https://mdref.m6w6.name/propro). Known issues are listed in [BUGS](./BUGS) and future ideas can be found in [TODO](./TODO). ## Installing ### PECL pecl install propro ### PHARext Watch out for [PECL replicates](https://replicator.pharext.org?propro) and pharext packages attached to [releases](./releases). ### Checkout git clone github.com:m6w6/ext-propro cd ext-propro /path/to/phpize ./configure --with-php-config=/path/to/php-config make sudo make install ## ChangeLog A comprehensive list of changes can be obtained from the [PECL website](https://pecl.php.net/package-changelog.php?package=propro). ## License ext-propro is licensed under the 2-Clause-BSD license, which can be found in the accompanying [LICENSE](./LICENSE) file. ## Contributing All forms of contribution are welcome! Please see the bundled [CONTRIBUTING](./CONTRIBUTING.md) note for the general principles followed. The list of past and current contributors is maintained in [THANKS](./THANKS). propro-2.0.0/THANKS0000644000175000001440000000014412647401166012617 0ustar mikeusersThanks go to the following people, who have contributed to this project: Anatol Belski Remi Collet propro-2.0.0/TODO0000644000175000001440000000000012647401166012363 0ustar mikeuserspropro-2.0.0/Doxyfile0000644000175000001440000002611712647401166013422 0ustar mikeusers# Doxyfile 1.8.10 #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = "Property proxy API" PROJECT_NUMBER = PROJECT_BRIEF = "A facility to manage extension object properties tied to C-struct members" PROJECT_LOGO = OUTPUT_DIRECTORY = CREATE_SUBDIRS = NO ALLOW_UNICODE_NAMES = NO OUTPUT_LANGUAGE = English BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES ABBREVIATE_BRIEF = ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO FULL_PATH_NAMES = YES STRIP_FROM_PATH = STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = YES QT_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO INHERIT_DOCS = YES SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 4 ALIASES = TCL_SUBST = OPTIMIZE_OUTPUT_FOR_C = YES OPTIMIZE_OUTPUT_JAVA = NO OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO EXTENSION_MAPPING = no_extension=md MARKDOWN_SUPPORT = YES AUTOLINK_SUPPORT = YES BUILTIN_STL_SUPPORT = NO CPP_CLI_SUPPORT = NO SIP_SUPPORT = NO IDL_PROPERTY_SUPPORT = YES DISTRIBUTE_GROUP_DOC = NO GROUP_NESTED_COMPOUNDS = NO SUBGROUPING = YES INLINE_GROUPED_CLASSES = NO INLINE_SIMPLE_STRUCTS = YES TYPEDEF_HIDES_STRUCT = NO LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- EXTRACT_ALL = YES EXTRACT_PRIVATE = NO EXTRACT_PACKAGE = NO EXTRACT_STATIC = NO EXTRACT_LOCAL_CLASSES = NO EXTRACT_LOCAL_METHODS = NO EXTRACT_ANON_NSPACES = NO HIDE_UNDOC_MEMBERS = NO HIDE_UNDOC_CLASSES = NO HIDE_FRIEND_COMPOUNDS = NO HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO CASE_SENSE_NAMES = YES HIDE_SCOPE_NAMES = NO HIDE_COMPOUND_REFERENCE= NO SHOW_INCLUDE_FILES = YES SHOW_GROUPED_MEMB_INC = NO FORCE_LOCAL_INCLUDES = NO INLINE_INFO = YES SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO SORT_MEMBERS_CTORS_1ST = NO SORT_GROUP_NAMES = NO SORT_BY_SCOPE_NAME = NO STRICT_PROTO_MATCHING = NO GENERATE_TODOLIST = YES GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES SHOW_FILES = YES SHOW_NAMESPACES = YES FILE_VERSION_FILTER = LAYOUT_FILE = CITE_BIB_FILES = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- QUIET = NO WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = NO WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- INPUT = README.md CONTRIBUTING.md php_propro.h src INPUT_ENCODING = UTF-8 FILE_PATTERNS = RECURSIVE = NO EXCLUDE = EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = EXCLUDE_SYMBOLS = EXAMPLE_PATH = EXAMPLE_PATTERNS = EXAMPLE_RECURSIVE = NO IMAGE_PATH = INPUT_FILTER = FILTER_PATTERNS = FILTER_SOURCE_FILES = NO FILTER_SOURCE_PATTERNS = USE_MDFILE_AS_MAINPAGE = README.md #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- SOURCE_BROWSER = NO INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES REFERENCED_BY_RELATION = YES REFERENCES_RELATION = NO REFERENCES_LINK_SOURCE = YES SOURCE_TOOLTIPS = YES USE_HTAGS = NO VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = YES COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output #--------------------------------------------------------------------------- GENERATE_HTML = YES HTML_OUTPUT = HTML_FILE_EXTENSION = .html HTML_HEADER = HTML_FOOTER = HTML_STYLESHEET = HTML_EXTRA_STYLESHEET = HTML_EXTRA_FILES = BUGS CONTRIBUTING.md LICENSE THANKS TODO HTML_COLORSTYLE_HUE = 220 HTML_COLORSTYLE_SAT = 100 HTML_COLORSTYLE_GAMMA = 80 HTML_TIMESTAMP = NO HTML_DYNAMIC_SECTIONS = NO HTML_INDEX_NUM_ENTRIES = 100 GENERATE_DOCSET = NO DOCSET_FEEDNAME = "Doxygen generated docs" DOCSET_BUNDLE_ID = org.doxygen.Project DOCSET_PUBLISHER_ID = org.doxygen.Publisher DOCSET_PUBLISHER_NAME = Publisher GENERATE_HTMLHELP = NO CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO CHM_INDEX_ENCODING = BINARY_TOC = NO TOC_EXPAND = NO GENERATE_QHP = NO QCH_FILE = QHP_NAMESPACE = org.doxygen.Project QHP_VIRTUAL_FOLDER = doc QHP_CUST_FILTER_NAME = QHP_CUST_FILTER_ATTRS = QHP_SECT_FILTER_ATTRS = QHG_LOCATION = GENERATE_ECLIPSEHELP = NO ECLIPSE_DOC_ID = org.doxygen.Project DISABLE_INDEX = NO GENERATE_TREEVIEW = YES ENUM_VALUES_PER_LINE = 4 TREEVIEW_WIDTH = 250 EXT_LINKS_IN_WINDOW = NO FORMULA_FONTSIZE = 10 FORMULA_TRANSPARENT = YES USE_MATHJAX = NO MATHJAX_FORMAT = HTML-CSS MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest MATHJAX_EXTENSIONS = MATHJAX_CODEFILE = SEARCHENGINE = YES SERVER_BASED_SEARCH = NO EXTERNAL_SEARCH = NO SEARCHENGINE_URL = SEARCHDATA_FILE = searchdata.xml EXTERNAL_SEARCH_ID = EXTRA_SEARCH_MAPPINGS = #--------------------------------------------------------------------------- # Configuration options related to the LaTeX output #--------------------------------------------------------------------------- GENERATE_LATEX = NO LATEX_OUTPUT = latex LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO PAPER_TYPE = a4 EXTRA_PACKAGES = LATEX_HEADER = LATEX_FOOTER = LATEX_EXTRA_STYLESHEET = LATEX_EXTRA_FILES = PDF_HYPERLINKS = YES USE_PDFLATEX = YES LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO LATEX_SOURCE_CODE = NO LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # Configuration options related to the RTF output #--------------------------------------------------------------------------- GENERATE_RTF = NO RTF_OUTPUT = rtf COMPACT_RTF = NO RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = RTF_SOURCE_CODE = NO #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- GENERATE_MAN = NO MAN_OUTPUT = man MAN_EXTENSION = .3 MAN_SUBDIR = MAN_LINKS = NO #--------------------------------------------------------------------------- # Configuration options related to the XML output #--------------------------------------------------------------------------- GENERATE_XML = NO XML_OUTPUT = xml XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # Configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- GENERATE_DOCBOOK = NO DOCBOOK_OUTPUT = docbook DOCBOOK_PROGRAMLISTING = NO #--------------------------------------------------------------------------- # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # Configuration options related to the Perl module output #--------------------------------------------------------------------------- GENERATE_PERLMOD = NO PERLMOD_LATEX = NO PERLMOD_PRETTY = YES PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES MACRO_EXPANSION = YES EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = PREDEFINED = DOXYGEN \ TSRMLS_C= \ TSRMLS_D= \ TSRMLS_CC= \ TSRMLS_DC= \ PHP_PROPRO_API= EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration options related to external references #--------------------------------------------------------------------------- TAGFILES = GENERATE_TAGFILE = ALLEXTERNALS = NO EXTERNAL_GROUPS = YES EXTERNAL_PAGES = YES PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- CLASS_DIAGRAMS = YES MSCGEN_PATH = DIA_PATH = HIDE_UNDOC_RELATIONS = YES HAVE_DOT = YES DOT_NUM_THREADS = 0 DOT_FONTNAME = Helvetica DOT_FONTSIZE = 10 DOT_FONTPATH = CLASS_GRAPH = NO COLLABORATION_GRAPH = YES GROUP_GRAPHS = YES UML_LOOK = NO UML_LIMIT_NUM_FIELDS = 10 TEMPLATE_RELATIONS = NO INCLUDE_GRAPH = YES INCLUDED_BY_GRAPH = YES CALL_GRAPH = YES CALLER_GRAPH = YES GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png INTERACTIVE_SVG = NO DOT_PATH = DOTFILE_DIRS = MSCFILE_DIRS = DIAFILE_DIRS = PLANTUML_JAR_PATH = PLANTUML_INCLUDE_PATH = DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 0 DOT_TRANSPARENT = NO DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES DOT_CLEANUP = YES propro-2.0.0/config.m40000644000175000001440000000002512647401166013411 0ustar mikeuserssinclude(config0.m4) propro-2.0.0/config0.m40000644000175000001440000000135312647401166013476 0ustar mikeusersPHP_ARG_ENABLE(propro, whether to enable property proxy support, [ --enable-propro Enable property proxy support]) if test "$PHP_PROPRO" != "no"; then PHP_PROPRO_SRCDIR=PHP_EXT_SRCDIR(propro) PHP_PROPRO_BUILDDIR=PHP_EXT_BUILDDIR(propro) PHP_ADD_INCLUDE($PHP_PROPRO_SRCDIR/src) PHP_ADD_BUILD_DIR($PHP_PROPRO_BUILDDIR/src) PHP_PROPRO_HEADERS=`(cd $PHP_PROPRO_SRCDIR/src && echo *.h)` PHP_PROPRO_SOURCES=`(cd $PHP_PROPRO_SRCDIR && echo src/*.c)` PHP_NEW_EXTENSION(propro, $PHP_PROPRO_SOURCES, $ext_shared) PHP_INSTALL_HEADERS(ext/propro, php_propro.h $PHP_PROPRO_HEADERS) PHP_SUBST(PHP_PROPRO_HEADERS) PHP_SUBST(PHP_PROPRO_SOURCES) PHP_SUBST(PHP_PROPRO_SRCDIR) PHP_SUBST(PHP_PROPRO_BUILDDIR) PHP_ADD_MAKEFILE_FRAGMENT fi propro-2.0.0/config.w320000644000175000001440000000100112647401166013477 0ustar mikeusers ARG_ENABLE("propro", "for propro support", "no"); if (PHP_PROPRO == "yes") { var PHP_PROPRO_HEADERS=glob("src/*.h"), PHP_PROPRO_SOURCES=glob("src/*.c"); EXTENSION("propro", PHP_PROPRO_SOURCES); PHP_INSTALL_HEADERS("ext/propro", "php_propro.h"); for (var i=0; i$@ <$< $(all_targets): propro-build-headers clean: propro-clean-headers .PHONY: propro-build-headers propro-build-headers: $(PHP_PROPRO_HEADERS) .PHONY: propro-clean-headers propro-clean-headers: -rm -f $(PHP_PROPRO_HEADERS) propro-2.0.0/php_propro.h0000644000175000001440000000251412647401166014250 0ustar mikeusers/* +--------------------------------------------------------------------+ | PECL :: propro | +--------------------------------------------------------------------+ | Redistribution and use in source and binary forms, with or without | | modification, are permitted provided that the conditions mentioned | | in the accompanying LICENSE file are met. | +--------------------------------------------------------------------+ | Copyright (c) 2013 Michael Wallner | +--------------------------------------------------------------------+ */ #ifndef PHP_PROPRO_H #define PHP_PROPRO_H extern zend_module_entry propro_module_entry; #define phpext_propro_ptr &propro_module_entry #define PHP_PROPRO_VERSION "2.0.0" #ifdef PHP_WIN32 # define PHP_PROPRO_API __declspec(dllexport) #elif defined(__GNUC__) && __GNUC__ >= 4 # define PHP_PROPRO_API extern __attribute__ ((visibility("default"))) #else # define PHP_PROPRO_API extern #endif #ifdef ZTS # include #endif #define PHP_PROPRO_PTR(zo) (void*)(((char*)(zo))-(zo)->handlers->offset) #endif /* PHP_PROPRO_H */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */