Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #1 from racklin/dev/extension

Rewritten PHP ValidationKit to C extension baseon phalcon kernel.
  • Loading branch information...
commit e8b06d66c157ca7635b425192962304a534e0332 2 parents 1760703 + a77a333
@c9s authored
Showing with 6,976 additions and 0 deletions.
  1. +49 −0 ext/README.md
  2. +6 −0 ext/config.m4
  3. +850 −0 ext/kernel/array.c
  4. +67 −0 ext/kernel/array.h
  5. +47 −0 ext/kernel/assert.c
  6. +24 −0 ext/kernel/assert.h
  7. +769 −0 ext/kernel/concat.c
  8. +71 −0 ext/kernel/concat.h
  9. +332 −0 ext/kernel/debug.c
  10. +69 −0 ext/kernel/debug.h
  11. +96 −0 ext/kernel/exception.c
  12. +25 −0 ext/kernel/exception.h
  13. +1,175 −0 ext/kernel/fcall.c
  14. +144 −0 ext/kernel/fcall.h
  15. +458 −0 ext/kernel/main.c
  16. +175 −0 ext/kernel/main.h
  17. +238 −0 ext/kernel/memory.c
  18. +147 −0 ext/kernel/memory.h
  19. +433 −0 ext/kernel/object.c
  20. +56 −0 ext/kernel/object.h
  21. +227 −0 ext/kernel/operators.c
  22. +46 −0 ext/kernel/operators.h
  23. +32 −0 ext/kernel/output.c
  24. +20 −0 ext/kernel/output.h
  25. +134 −0 ext/kernel/require.c
  26. +20 −0 ext/kernel/require.h
  27. +81 −0 ext/php_phalcon.h
  28. +44 −0 ext/tests/bench_stringlength.php
  29. +118 −0 ext/validationkit.c
  30. +124 −0 ext/validationkit.h
  31. +367 −0 ext/validator.c
  32. +59 −0 ext/validator/email.c
  33. +343 −0 ext/validator/string.c
  34. +83 −0 ext/validator/string_length.c
  35. +47 −0 ext/validator/template.c
View
49 ext/README.md
@@ -0,0 +1,49 @@
+ValidationKit C extension baseon Phalcon kernel
+=====================
+
+ValidationKit C extension is rewritten in C with phalcon kernel, providing high
+performance and lower resource consumption.
+
+* NOT All Validators are porting to C extension.
+
+Get Started
+-----------
+
+### Linux/Unix/Mac
+
+On a Unix based platform you can easily compile and install the extension from
+sources.
+
+#### Requirements
+We need some packages previously installed.
+
+* PHP 5.x development resources
+* GCC compiler
+
+Ubuntu:
+
+ sudo apt-get install php5-devel php5-mysql gcc make
+
+Suse:
+
+ yast2 -i php5-pear php5-dev libmysqlclient gcc make autoconf2.13
+
+Compilation
+-----------
+
+Follow these instructions to generate a binary extension for your platform:
+
+ # git clone git@github.com:racklin/ValidationKit.git
+ # cd ValidationKit/ext
+ # export CFLAGS="-O2 -fno-delete-null-pointer-checks"
+ # phpize
+ # ./configure --enable-validationkit
+ # make
+ # sudo make install
+
+Add extension to your php.ini
+
+ extension=validationkit.so
+
+Finally restart the webserver
+
View
6 ext/config.m4
@@ -0,0 +1,6 @@
+PHP_ARG_ENABLE(validationkit, whether to enable validation kit, [ --enable-validationkit Enable Validation kit])
+
+if test "$PHP_VALIDATIONKIT" = "yes"; then
+ AC_DEFINE(HAVE_VALIDATIONKIT, 1, [Whether you have Validation Kit])
+ PHP_NEW_EXTENSION(validationkit, validationkit.c kernel/main.c kernel/fcall.c kernel/require.c kernel/debug.c kernel/assert.c kernel/object.c kernel/array.c kernel/operators.c kernel/concat.c kernel/exception.c kernel/memory.c validator.c validator/email.c validator/string_length.c validator/string.c, $ext_shared)
+fi
View
850 ext/kernel/array.c
@@ -0,0 +1,850 @@
+
+/*
+ +------------------------------------------------------------------------+
+ | Phalcon Framework |
+ +------------------------------------------------------------------------+
+ | Copyright (c) 2011-2012 Phalcon Team (http://www.phalconphp.com) |
+ +------------------------------------------------------------------------+
+ | This source file is subject to the New BSD License that is bundled |
+ | with this package in the file docs/LICENSE.txt. |
+ | |
+ | If you did not receive a copy of the license and are unable to |
+ | obtain it through the world-wide-web, please send an email |
+ | to license@phalconphp.com so we can send you a copy immediately. |
+ +------------------------------------------------------------------------+
+ | Authors: Andres Gutierrez <andres@phalconphp.com> |
+ | Eduar Carvajal <eduar@phalconphp.com> |
+ +------------------------------------------------------------------------+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_phalcon.h"
+#include "kernel/main.h"
+#include "kernel/debug.h"
+#include "kernel/array.h"
+
+/**
+ * Check if index exists on an array zval
+ */
+int PHALCON_FASTCALL phalcon_array_isset(const zval *arr, zval *index){
+
+ zval *copy;
+ int exists, copied = 0;
+
+ if (Z_TYPE_P(arr) != IS_ARRAY) {
+ return 0;
+ }
+
+ if (Z_TYPE_P(index) == IS_NULL) {
+ ALLOC_INIT_ZVAL(copy);
+ ZVAL_ZVAL(copy, index, 1, 0);
+ convert_to_string(copy);
+ index = copy;
+ copied = 1;
+ } else {
+ if (Z_TYPE_P(index) == IS_BOOL || Z_TYPE_P(index) == IS_DOUBLE) {
+ ALLOC_INIT_ZVAL(copy);
+ ZVAL_ZVAL(copy, index, 1, 0);
+ convert_to_long(copy);
+ index = copy;
+ copied = 1;
+ }
+ }
+
+ if (Z_TYPE_P(index) == IS_STRING) {
+ exists = zend_hash_exists(Z_ARRVAL_P(arr), Z_STRVAL_P(index), Z_STRLEN_P(index)+1);
+ } else {
+ exists = zend_hash_index_exists(Z_ARRVAL_P(arr), Z_LVAL_P(index));
+ }
+
+ if (copied) {
+ zval_ptr_dtor(&copy);
+ }
+
+ return exists;
+}
+
+/**
+ * Check if char index exists on an array zval
+ */
+int PHALCON_FASTCALL phalcon_array_isset_string(const zval *arr, char *index, uint index_length){
+ if (Z_TYPE_P(arr) != IS_ARRAY) {
+ return 0;
+ }
+ return zend_hash_exists(Z_ARRVAL_P(arr), index, index_length);
+}
+
+/**
+ * Check if char index exists on an array zval
+ */
+int PHALCON_FASTCALL phalcon_array_isset_long(const zval *arr, ulong index){
+ if (Z_TYPE_P(arr) != IS_ARRAY) {
+ return 0;
+ }
+ return zend_hash_index_exists(Z_ARRVAL_P(arr), index);
+}
+
+/**
+ * Unsets zval index from array
+ */
+int PHALCON_FASTCALL phalcon_array_unset(zval *arr, zval *index){
+
+ zval *copy;
+ int exists, copied = 0;
+
+ if (Z_TYPE_P(arr) != IS_ARRAY) {
+ return 0;
+ }
+
+ if (Z_TYPE_P(index) == IS_NULL) {
+ ALLOC_INIT_ZVAL(copy);
+ ZVAL_ZVAL(copy, index, 1, 0);
+ convert_to_string(copy);
+ index = copy;
+ copied = 1;
+ } else {
+ if (Z_TYPE_P(index) == IS_BOOL || Z_TYPE_P(index) == IS_DOUBLE) {
+ ALLOC_INIT_ZVAL(copy);
+ ZVAL_ZVAL(copy, index, 1, 0);
+ convert_to_long(copy);
+ index = copy;
+ copied = 1;
+ }
+ }
+
+ if (Z_TYPE_P(index) == IS_STRING) {
+ exists = zend_hash_del(Z_ARRVAL_P(arr), Z_STRVAL_P(index), Z_STRLEN_P(index)+1);
+ } else {
+ exists = zend_hash_index_del(Z_ARRVAL_P(arr), Z_LVAL_P(index));
+ }
+
+ if (copied) {
+ zval_ptr_dtor(&copy);
+ }
+
+ return exists;
+}
+
+/**
+ * Unsets string index from array
+ */
+int PHALCON_FASTCALL phalcon_array_unset_string(zval *arr, char *index, uint index_length){
+ if (Z_TYPE_P(arr) != IS_ARRAY) {
+ return 0;
+ }
+ return zend_hash_del(Z_ARRVAL_P(arr), index, index_length);
+}
+
+/**
+ * Unsets long index from array
+ */
+int PHALCON_FASTCALL phalcon_array_unset_long(zval *arr, ulong index){
+ if (Z_TYPE_P(arr) != IS_ARRAY) {
+ return 0;
+ }
+ return zend_hash_index_del(Z_ARRVAL_P(arr), index);
+}
+
+/**
+ * Push one or more elements onto the end of an array
+ */
+int phalcon_array_append(zval **arr, zval *value, int flags TSRMLS_DC){
+ if (Z_TYPE_PP(arr) == IS_ARRAY) {
+ if ((flags & PH_SEPARATE) == PH_SEPARATE) {
+ if (Z_REFCOUNT_PP(arr) > 1) {
+ zval *new_zv;
+ Z_DELREF_PP(arr);
+ ALLOC_ZVAL(new_zv);
+ INIT_PZVAL_COPY(new_zv, *arr);
+ *arr = new_zv;
+ zval_copy_ctor(new_zv);
+ }
+ }
+ Z_ADDREF_P(value);
+ return add_next_index_zval(*arr, value);
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot use a scalar value as an array");
+ }
+ return FAILURE;
+}
+
+int phalcon_array_append_long(zval **arr, long value, int separate TSRMLS_DC){
+
+ zval *zvalue;
+
+ ALLOC_INIT_ZVAL(zvalue);
+ Z_SET_REFCOUNT_P(zvalue, 0);
+ ZVAL_LONG(zvalue, value);
+
+ return phalcon_array_append(arr, zvalue, separate TSRMLS_CC);
+}
+
+int phalcon_array_append_string(zval **arr, char *value, uint value_length, int separate TSRMLS_DC){
+
+ zval *zvalue;
+
+ ALLOC_INIT_ZVAL(zvalue);
+ Z_SET_REFCOUNT_P(zvalue, 0);
+ ZVAL_STRINGL(zvalue, value, value_length, 1);
+
+ return phalcon_array_append(arr, zvalue, separate TSRMLS_CC);
+}
+
+/**
+ * Updates values on arrays by string or long indexes
+ */
+int phalcon_array_update_zval(zval **arr, zval *index, zval **value, int flags TSRMLS_DC){
+
+ if (Z_TYPE_PP(arr) != IS_ARRAY) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot use a scalar value as an array");
+ return FAILURE;
+ }
+
+ if (Z_TYPE_P(index) == IS_NULL) {
+ convert_to_string(index);
+ } else {
+ if (Z_TYPE_P(index) == IS_BOOL || Z_TYPE_P(index) == IS_DOUBLE) {
+ convert_to_long(index);
+ }
+ }
+
+ if ((flags & PH_CTOR) == PH_CTOR) {
+ zval *new_zv;
+ Z_DELREF_PP(value);
+ ALLOC_ZVAL(new_zv);
+ INIT_PZVAL_COPY(new_zv, *value);
+ *value = new_zv;
+ zval_copy_ctor(new_zv);
+ }
+
+ if ((flags & PH_SEPARATE) == PH_SEPARATE) {
+ if (Z_REFCOUNT_PP(arr) > 1) {
+ zval *new_zv;
+ Z_DELREF_PP(arr);
+ ALLOC_ZVAL(new_zv);
+ INIT_PZVAL_COPY(new_zv, *arr);
+ *arr = new_zv;
+ zval_copy_ctor(new_zv);
+ }
+ }
+
+ if ((flags & PH_COPY) == PH_COPY) {
+ Z_ADDREF_PP(value);
+ }
+
+ if(Z_TYPE_P(index) == IS_STRING){
+ return zend_hash_update(Z_ARRVAL_PP(arr), Z_STRVAL_P(index), Z_STRLEN_P(index)+1, value, sizeof(zval *), NULL);
+ } else {
+ if (Z_TYPE_P(index) == IS_LONG) {
+ return zend_hash_index_update(Z_ARRVAL_PP(arr), Z_LVAL_P(index), value, sizeof(zval *), NULL);
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Illegal offset type");
+ }
+ }
+
+ return FAILURE;
+}
+
+int phalcon_array_update_zval_bool(zval **arr, zval *index, int value, int flags TSRMLS_DC){
+
+ zval *zvalue;
+
+ ALLOC_INIT_ZVAL(zvalue);
+ ZVAL_BOOL(zvalue, value);
+
+ return phalcon_array_update_zval(arr, index, &zvalue, flags TSRMLS_CC);
+}
+
+int phalcon_array_update_zval_string(zval **arr, zval *index, char *value, uint value_length, int flags TSRMLS_DC){
+
+ zval *zvalue;
+
+ ALLOC_INIT_ZVAL(zvalue);
+ ZVAL_STRINGL(zvalue, value, value_length, 1);
+
+ return phalcon_array_update_zval(arr, index, &zvalue, flags TSRMLS_CC);
+}
+
+/**
+ * Updates values on arrays by string indexes only
+ */
+int phalcon_array_update_string(zval **arr, char *index, uint index_length, zval **value, int flags TSRMLS_DC){
+
+ if (Z_TYPE_PP(arr) != IS_ARRAY) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot use a scalar value as an array");
+ return FAILURE;
+ }
+
+ if ((flags & PH_CTOR) == PH_CTOR) {
+ zval *new_zv;
+ Z_DELREF_PP(value);
+ ALLOC_ZVAL(new_zv);
+ INIT_PZVAL_COPY(new_zv, *value);
+ *value = new_zv;
+ zval_copy_ctor(new_zv);
+ }
+
+ if ((flags & PH_SEPARATE) == PH_SEPARATE) {
+ if (Z_REFCOUNT_PP(arr) > 1) {
+ zval *new_zv;
+ Z_DELREF_PP(arr);
+ ALLOC_ZVAL(new_zv);
+ INIT_PZVAL_COPY(new_zv, *arr);
+ *arr = new_zv;
+ zval_copy_ctor(new_zv);
+ }
+ }
+
+ if ((flags & PH_COPY) == PH_COPY) {
+ Z_ADDREF_PP(value);
+ }
+
+ return zend_hash_update(Z_ARRVAL_PP(arr), index, index_length+1, value, sizeof(zval *), NULL);
+}
+
+int phalcon_array_update_string_bool(zval **arr, char *index, uint index_length, int value, int flags TSRMLS_DC){
+
+ zval *zvalue;
+
+ ALLOC_INIT_ZVAL(zvalue);
+ ZVAL_BOOL(zvalue, value);
+
+ return phalcon_array_update_string(arr, index, index_length, &zvalue, flags TSRMLS_CC);
+}
+
+int phalcon_array_update_string_long(zval **arr, char *index, uint index_length, long value, int flags TSRMLS_DC){
+
+ zval *zvalue;
+
+ ALLOC_INIT_ZVAL(zvalue);
+ ZVAL_LONG(zvalue, value);
+
+ return phalcon_array_update_string(arr, index, index_length, &zvalue, flags TSRMLS_CC);
+}
+
+int phalcon_array_update_string_string(zval **arr, char *index, uint index_length, char *value, uint value_length, int flags TSRMLS_DC){
+
+ zval *zvalue;
+
+ ALLOC_INIT_ZVAL(zvalue);
+ ZVAL_STRINGL(zvalue, value, value_length, 1);
+
+ return phalcon_array_update_string(arr, index, index_length, &zvalue, flags TSRMLS_CC);
+}
+
+/**
+ * Updates values on arrays by long indexes only
+ */
+int phalcon_array_update_long(zval **arr, ulong index, zval **value, int flags TSRMLS_DC){
+
+ if (Z_TYPE_PP(arr) != IS_ARRAY) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot use a scalar value as an array");
+ return FAILURE;
+ }
+
+ if ((flags & PH_CTOR) == PH_CTOR) {
+ zval *new_zv;
+ Z_DELREF_PP(value);
+ ALLOC_ZVAL(new_zv);
+ INIT_PZVAL_COPY(new_zv, *value);
+ *value = new_zv;
+ zval_copy_ctor(new_zv);
+ }
+
+ if ((flags & PH_SEPARATE) == PH_SEPARATE) {
+ if (Z_REFCOUNT_PP(arr) > 1) {
+ zval *new_zv;
+ Z_DELREF_PP(arr);
+ ALLOC_ZVAL(new_zv);
+ INIT_PZVAL_COPY(new_zv, *arr);
+ *arr = new_zv;
+ zval_copy_ctor(new_zv);
+ }
+ }
+
+ if ((flags & PH_COPY) == PH_COPY) {
+ Z_ADDREF_PP(value);
+ }
+
+ return zend_hash_index_update(Z_ARRVAL_PP(arr), index, value, sizeof(zval *), NULL);
+}
+
+int phalcon_array_update_long_string(zval **arr, ulong index, char *value, uint value_length, int flags TSRMLS_DC){
+
+ zval *zvalue;
+
+ ALLOC_INIT_ZVAL(zvalue);
+ ZVAL_STRINGL(zvalue, value, value_length, 1);
+
+ return phalcon_array_update_long(arr, index, &zvalue, flags TSRMLS_CC);
+}
+
+int phalcon_array_update_long_bool(zval **arr, ulong index, int value, int flags TSRMLS_DC){
+
+ zval *zvalue;
+
+ ALLOC_INIT_ZVAL(zvalue);
+ ZVAL_BOOL(zvalue, value);
+
+ return phalcon_array_update_long(arr, index, &zvalue, flags TSRMLS_CC);
+}
+
+/**
+ * Reads an item from an array using a zval as index
+ */
+int phalcon_array_fetch(zval **return_value, zval *arr, zval *index, int silent TSRMLS_DC){
+
+ zval **zv;
+ int result = FAILURE, type;
+
+ if (Z_TYPE_P(index) == IS_ARRAY || Z_TYPE_P(index) == IS_OBJECT) {
+ ZVAL_NULL(*return_value);
+ if (silent == PH_NOISY) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Illegal offset type");
+ }
+ return FAILURE;
+ }
+
+ if (Z_TYPE_P(index) == IS_NULL) {
+ convert_to_string(index);
+ }
+
+ ZVAL_NULL(*return_value);
+
+ if (Z_TYPE_P(arr) == IS_NULL || Z_TYPE_P(arr) == IS_BOOL) {
+ return FAILURE;
+ }
+
+ if (Z_TYPE_P(index) != IS_STRING && Z_TYPE_P(index) != IS_LONG && Z_TYPE_P(index) != IS_DOUBLE) {
+ if (silent == PH_NOISY) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Illegal offset type");
+ }
+ return FAILURE;
+ }
+
+ if (Z_TYPE_P(index) == IS_STRING) {
+ if((type = is_numeric_string(Z_STRVAL_P(index), Z_STRLEN_P(index), NULL, NULL, 0))){
+ if (type == IS_LONG) {
+ convert_to_long(index);
+ }
+ }
+ } else {
+ if (Z_TYPE_P(index) == IS_DOUBLE) {
+ convert_to_long(index);
+ }
+ }
+
+ if (Z_TYPE_P(index) == IS_STRING) {
+ if((result = zend_hash_find(Z_ARRVAL_P(arr), Z_STRVAL_P(index), Z_STRLEN_P(index)+1, (void**) &zv)) == SUCCESS){
+ zval_ptr_dtor(return_value);
+ *return_value = *zv;
+ Z_ADDREF_PP(return_value);
+ return SUCCESS;
+ }
+ }
+
+ if (Z_TYPE_P(index) == IS_LONG) {
+ if ((result = zend_hash_index_find(Z_ARRVAL_P(arr), Z_LVAL_P(index), (void**) &zv)) == SUCCESS) {
+ zval_ptr_dtor(return_value);
+ *return_value = *zv;
+ Z_ADDREF_PP(return_value);
+ return SUCCESS;
+ }
+ }
+
+ if (silent == PH_NOISY) {
+ if (Z_TYPE_P(index) == IS_LONG) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Undefined index: %ld", Z_LVAL_P(index));
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Undefined index: %s", Z_STRVAL_P(index));
+ }
+ }
+
+ return FAILURE;
+}
+
+/**
+ * Reads an item from an array using a string as index
+ */
+int phalcon_array_fetch_string(zval **return_value, zval *arr, char *index, uint index_length, int silent TSRMLS_DC){
+
+ zval **zv;
+ int result = FAILURE;
+
+ ZVAL_NULL(*return_value);
+
+ if (Z_TYPE_P(arr) != IS_ARRAY) {
+ ZVAL_NULL(*return_value);
+ if (silent == PH_NOISY) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot use a scalar value as an array");
+ }
+ return FAILURE;
+ }
+
+ if ((result = zend_hash_find(Z_ARRVAL_P(arr), index, index_length+1, (void**)&zv)) == SUCCESS) {
+ zval_ptr_dtor(return_value);
+ *return_value = *zv;
+ Z_ADDREF_PP(return_value);
+ return SUCCESS;
+ }
+
+ if (silent == PH_NOISY) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Undefined index: %s", index);
+ }
+
+ return FAILURE;
+
+}
+
+/**
+ * Reads an item from an array using a long as index
+ */
+int phalcon_array_fetch_long(zval **return_value, zval *arr, ulong index, int silent TSRMLS_DC){
+
+ zval **zv;
+ int result = FAILURE;
+
+ ZVAL_NULL(*return_value);
+
+ if (Z_TYPE_P(arr) != IS_ARRAY) {
+ if (silent == PH_NOISY) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot use a scalar value as an array");
+ }
+ return FAILURE;
+ }
+
+ if ((result = zend_hash_index_find(Z_ARRVAL_P(arr), index, (void**)&zv)) == SUCCESS) {
+ zval_ptr_dtor(return_value);
+ *return_value = *zv;
+ Z_ADDREF_PP(return_value);
+ return SUCCESS;
+ }
+
+ if (silent == PH_NOISY) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Undefined index: %ld", index);
+ }
+
+ return FAILURE;
+
+}
+
+/**
+ * Append a zval to a multi-dimensional array with two indexes
+ */
+void phalcon_array_append_multi_2(zval **arr, zval *index, zval *value, int flags TSRMLS_DC){
+
+ zval *temp;
+
+ ALLOC_INIT_ZVAL(temp);
+
+ if (Z_TYPE_PP(arr) == IS_ARRAY) {
+ phalcon_array_fetch(&temp, *arr, index, PH_SILENT_CC);
+ if (Z_REFCOUNT_P(temp) > 1) {
+ phalcon_array_update_zval(arr, index, &temp, PH_COPY | PH_CTOR TSRMLS_CC);
+ }
+ if (Z_TYPE_P(temp) != IS_ARRAY) {
+ convert_to_array(temp);
+ phalcon_array_update_zval(arr, index, &temp, PH_COPY TSRMLS_CC);
+ }
+ phalcon_array_append(&temp, value, flags TSRMLS_CC);
+ }
+
+ zval_ptr_dtor(&temp);
+
+}
+
+/**
+ * Updates multi-dimensional array with two zval indexes
+ */
+void phalcon_array_update_multi_2(zval **arr, zval *index1, zval *index2, zval **value, int flags TSRMLS_DC){
+
+ zval *temp;
+
+ ALLOC_INIT_ZVAL(temp);
+
+ if (Z_TYPE_PP(arr) == IS_ARRAY) {
+ phalcon_array_fetch(&temp, *arr, index1, PH_SILENT_CC);
+ if (Z_REFCOUNT_P(temp) > 1) {
+ phalcon_array_update_zval(arr, index1, &temp, PH_COPY | PH_CTOR TSRMLS_CC);
+ }
+ if (Z_TYPE_P(temp) != IS_ARRAY) {
+ convert_to_array(temp);
+ phalcon_array_update_zval(arr, index1, &temp, PH_COPY TSRMLS_CC);
+ }
+ phalcon_array_update_zval(&temp, index2, value, flags | PH_COPY TSRMLS_CC);
+ }
+
+ zval_ptr_dtor(&temp);
+
+}
+
+/**
+ * Updates multi-dimensional array with two zval indexes
+ */
+void phalcon_array_update_string_multi_2(zval **arr, zval *index1, char *index2, uint index2_length, zval **value, int flags TSRMLS_DC){
+
+ zval *temp;
+
+ ALLOC_INIT_ZVAL(temp);
+
+ if (Z_TYPE_PP(arr) == IS_ARRAY) {
+ phalcon_array_fetch(&temp, *arr, index1, PH_SILENT_CC);
+ if (Z_REFCOUNT_P(temp) > 1) {
+ phalcon_array_update_zval(arr, index1, &temp, PH_COPY | PH_CTOR TSRMLS_CC);
+ }
+ if (Z_TYPE_P(temp) != IS_ARRAY) {
+ convert_to_array(temp);
+ phalcon_array_update_zval(arr, index1, &temp, PH_COPY TSRMLS_CC);
+ }
+ phalcon_array_update_string(&temp, index2, index2_length, value, flags | PH_COPY TSRMLS_CC);
+ }
+
+ zval_ptr_dtor(&temp);
+
+}
+
+/**
+ * Updates multi-dimensional arrays with two long indices
+ *
+ * $foo[10][4] = $x
+ */
+void phalcon_array_update_long_long_multi_2(zval **arr, long index1, long index2, zval **value, int flags TSRMLS_DC){
+
+ zval *temp;
+
+ ALLOC_INIT_ZVAL(temp);
+
+ if (Z_TYPE_PP(arr) == IS_ARRAY) {
+ phalcon_array_fetch_long(&temp, *arr, index1, PH_SILENT_CC);
+ if (Z_REFCOUNT_P(temp) > 1) {
+ phalcon_array_update_long(arr, index1, &temp, PH_COPY | PH_CTOR TSRMLS_CC);
+ }
+ if (Z_TYPE_P(temp) != IS_ARRAY) {
+ convert_to_array(temp);
+ phalcon_array_update_long(arr, index1, &temp, PH_COPY TSRMLS_CC);
+ }
+ phalcon_array_update_long(&temp, index2, value, flags | PH_COPY TSRMLS_CC);
+ }
+
+ zval_ptr_dtor(&temp);
+
+}
+
+/**
+ * Updates multi-dimensional arrays with one long index and other string
+ *
+ * $foo[10]["lol"] = $x
+ */
+void phalcon_array_update_long_string_multi_2(zval **arr, long index1, char *index2, uint index2_length, zval **value, int flags TSRMLS_DC){
+
+ zval *temp;
+
+ ALLOC_INIT_ZVAL(temp);
+
+ if (Z_TYPE_PP(arr) == IS_ARRAY) {
+ phalcon_array_fetch_long(&temp, *arr, index1, PH_SILENT_CC);
+ if (Z_REFCOUNT_P(temp) > 1) {
+ phalcon_array_update_long(arr, index1, &temp, PH_COPY | PH_CTOR TSRMLS_CC);
+ }
+ if (Z_TYPE_P(temp) != IS_ARRAY) {
+ convert_to_array(temp);
+ phalcon_array_update_long(arr, index1, &temp, PH_COPY TSRMLS_CC);
+ }
+ phalcon_array_update_string(&temp, index2, index2_length, value, flags | PH_COPY TSRMLS_CC);
+ }
+
+ zval_ptr_dtor(&temp);
+
+}
+
+/**
+ * $x[$a][] = 1
+ */
+void phalcon_array_update_append_multi_2(zval **arr, zval *index1, zval *value, int flags TSRMLS_DC){
+
+ zval *temp;
+
+ ALLOC_INIT_ZVAL(temp);
+
+ if (Z_TYPE_PP(arr) == IS_ARRAY) {
+ phalcon_array_fetch(&temp, *arr, index1, PH_SILENT_CC);
+ if (Z_REFCOUNT_P(temp) > 1) {
+ phalcon_array_update_zval(arr, index1, &temp, PH_COPY | PH_CTOR TSRMLS_CC);
+ }
+ if (Z_TYPE_P(temp) != IS_ARRAY) {
+ convert_to_array(temp);
+ phalcon_array_update_zval(arr, index1, &temp, PH_COPY TSRMLS_CC);
+ }
+ phalcon_array_append(&temp, value, flags TSRMLS_CC);
+ }
+
+ zval_ptr_dtor(&temp);
+
+}
+
+/**
+ * $x[$a]["hello"][] = $v
+ */
+void phalcon_array_update_zval_string_append_multi_3(zval **arr, zval *index1, char *index2, uint index2_length, zval **value, int flags TSRMLS_DC){
+
+ zval *temp1 = NULL, *temp2 = NULL;
+
+ if (Z_TYPE_PP(arr) == IS_ARRAY) {
+
+ ALLOC_INIT_ZVAL(temp1);
+ phalcon_array_fetch(&temp1, *arr, index1, PH_SILENT_CC);
+ if (Z_REFCOUNT_P(temp1) > 1) {
+ phalcon_array_update_zval(arr, index1, &temp1, PH_COPY | PH_CTOR TSRMLS_CC);
+ }
+ if (Z_TYPE_P(temp1) != IS_ARRAY) {
+ convert_to_array(temp1);
+ phalcon_array_update_zval(arr, index1, &temp1, PH_COPY TSRMLS_CC);
+ }
+
+ ALLOC_INIT_ZVAL(temp2);
+ phalcon_array_fetch_string(&temp2, temp1, index2, index2_length, PH_SILENT_CC);
+ if (Z_REFCOUNT_P(temp2) > 1) {
+ phalcon_array_update_string(&temp1, index2, index2_length, &temp2, PH_COPY | PH_CTOR TSRMLS_CC);
+ }
+ if (Z_TYPE_P(temp2) != IS_ARRAY) {
+ convert_to_array(temp2);
+ phalcon_array_update_string(&temp1, index2, index2_length, &temp2, PH_COPY TSRMLS_CC);
+ }
+
+ phalcon_array_append(&temp2, *value, flags TSRMLS_CC);
+ }
+
+ if (temp1 != NULL) {
+ zval_ptr_dtor(&temp1);
+ }
+ if (temp2 != NULL) {
+ zval_ptr_dtor(&temp2);
+ }
+
+}
+
+/**
+ * $x[$a][$b][$c] = $v
+ */
+void phalcon_array_update_zval_zval_zval_multi_3(zval **arr, zval *index1, zval *index2, zval *index3, zval **value, int flags TSRMLS_DC){
+
+ zval *temp1 = NULL, *temp2 = NULL;
+
+ if (Z_TYPE_PP(arr) == IS_ARRAY) {
+
+ ALLOC_INIT_ZVAL(temp1);
+ phalcon_array_fetch(&temp1, *arr, index1, PH_SILENT_CC);
+ if (Z_REFCOUNT_P(temp1) > 1) {
+ phalcon_array_update_zval(arr, index1, &temp1, PH_COPY | PH_CTOR TSRMLS_CC);
+ }
+ if (Z_TYPE_P(temp1) != IS_ARRAY) {
+ convert_to_array(temp1);
+ phalcon_array_update_zval(arr, index1, &temp1, PH_COPY TSRMLS_CC);
+ }
+
+ ALLOC_INIT_ZVAL(temp2);
+ phalcon_array_fetch(&temp2, temp1, index2, PH_SILENT_CC);
+ if (Z_REFCOUNT_P(temp2) > 1) {
+ phalcon_array_update_zval(&temp1, index2, &temp2, PH_COPY | PH_CTOR TSRMLS_CC);
+ }
+ if (Z_TYPE_P(temp2) != IS_ARRAY) {
+ convert_to_array(temp2);
+ phalcon_array_update_zval(&temp1, index2, &temp2, PH_COPY TSRMLS_CC);
+ }
+
+ phalcon_array_update_zval(&temp2, index3, value, PH_COPY TSRMLS_CC);
+ }
+
+ if (temp1 != NULL) {
+ zval_ptr_dtor(&temp1);
+ }
+ if (temp2 != NULL) {
+ zval_ptr_dtor(&temp2);
+ }
+
+}
+
+/**
+ * $x[$a][$b]["str"] = $v
+ */
+void phalcon_array_update_string_zval_zval_multi_3(zval **arr, zval *index1, zval *index2, char *index3, uint index3_length, zval **value, int flags TSRMLS_DC){
+
+ zval *temp1 = NULL, *temp2 = NULL;
+
+ if (Z_TYPE_PP(arr) == IS_ARRAY) {
+
+ ALLOC_INIT_ZVAL(temp1);
+ phalcon_array_fetch(&temp1, *arr, index1, PH_SILENT_CC);
+ if (Z_REFCOUNT_P(temp1) > 1) {
+ phalcon_array_update_zval(arr, index1, &temp1, PH_COPY | PH_CTOR TSRMLS_CC);
+ }
+ if (Z_TYPE_P(temp1) != IS_ARRAY) {
+ convert_to_array(temp1);
+ phalcon_array_update_zval(arr, index1, &temp1, PH_COPY TSRMLS_CC);
+ }
+
+ ALLOC_INIT_ZVAL(temp2);
+ phalcon_array_fetch(&temp2, temp1, index2, PH_SILENT_CC);
+ if (Z_REFCOUNT_P(temp2) > 1) {
+ phalcon_array_update_zval(&temp1, index2, &temp2, PH_COPY | PH_CTOR TSRMLS_CC);
+ }
+ if (Z_TYPE_P(temp2) != IS_ARRAY) {
+ convert_to_array(temp2);
+ phalcon_array_update_zval(&temp1, index2, &temp2, PH_COPY TSRMLS_CC);
+ }
+
+ phalcon_array_update_string(&temp2, index3, index3_length, value, PH_COPY TSRMLS_CC);
+ }
+
+ if (temp1 != NULL) {
+ zval_ptr_dtor(&temp1);
+ }
+ if (temp2 != NULL) {
+ zval_ptr_dtor(&temp2);
+ }
+
+}
+
+/**
+ * $x[$a]["a-str"]["str"] = 1
+ */
+void phalcon_array_update_zval_string_string_multi_3(zval **arr, zval *index1, char *index2, uint index2_length, char *index3, uint index3_length, zval **value, int flags TSRMLS_DC){
+
+ zval *temp1 = NULL, *temp2 = NULL;
+
+ if (Z_TYPE_PP(arr) == IS_ARRAY) {
+
+ ALLOC_INIT_ZVAL(temp1);
+ phalcon_array_fetch(&temp1, *arr, index1, PH_SILENT_CC);
+ if (Z_REFCOUNT_P(temp1) > 1) {
+ phalcon_array_update_zval(arr, index1, &temp1, PH_COPY | PH_CTOR TSRMLS_CC);
+ }
+ if (Z_TYPE_P(temp1) != IS_ARRAY) {
+ convert_to_array(temp1);
+ phalcon_array_update_zval(arr, index1, &temp1, PH_COPY TSRMLS_CC);
+ }
+
+ ALLOC_INIT_ZVAL(temp2);
+ phalcon_array_fetch_string(&temp2, temp1, index2, index2_length, PH_SILENT_CC);
+ if (Z_REFCOUNT_P(temp2) > 1) {
+ phalcon_array_update_string(&temp1, index2, index2_length, &temp2, PH_COPY | PH_CTOR TSRMLS_CC);
+ }
+ if (Z_TYPE_P(temp2) != IS_ARRAY) {
+ convert_to_array(temp2);
+ phalcon_array_update_string(&temp1, index2, index2_length, &temp2, PH_COPY TSRMLS_CC);
+ }
+
+ phalcon_array_update_string(&temp2, index3, index3_length, value, PH_COPY TSRMLS_CC);
+ }
+
+ if (temp1 != NULL) {
+ zval_ptr_dtor(&temp1);
+ }
+ if (temp2 != NULL) {
+ zval_ptr_dtor(&temp2);
+ }
+}
View
67 ext/kernel/array.h
@@ -0,0 +1,67 @@
+
+/*
+ +------------------------------------------------------------------------+
+ | Phalcon Framework |
+ +------------------------------------------------------------------------+
+ | Copyright (c) 2011-2012 Phalcon Team (http://www.phalconphp.com) |
+ +------------------------------------------------------------------------+
+ | This source file is subject to the New BSD License that is bundled |
+ | with this package in the file docs/LICENSE.txt. |
+ | |
+ | If you did not receive a copy of the license and are unable to |
+ | obtain it through the world-wide-web, please send an email |
+ | to license@phalconphp.com so we can send you a copy immediately. |
+ +------------------------------------------------------------------------+
+ | Authors: Andres Gutierrez <andres@phalconphp.com> |
+ | Eduar Carvajal <eduar@phalconphp.com> |
+ +------------------------------------------------------------------------+
+*/
+
+/** Check for index existence */
+extern int PHALCON_FASTCALL phalcon_array_isset(const zval *arr, zval *index);
+extern int PHALCON_FASTCALL phalcon_array_isset_long(const zval *arr, ulong index);
+extern int PHALCON_FASTCALL phalcon_array_isset_string(const zval *arr, char *index, uint index_length);
+
+/** Unset existing indexes */
+extern int PHALCON_FASTCALL phalcon_array_unset(zval *arr, zval *index);
+extern int PHALCON_FASTCALL phalcon_array_unset_long(zval *arr, ulong index);
+extern int PHALCON_FASTCALL phalcon_array_unset_string(zval *arr, char *index, uint index_length);
+
+/** Append elements to arrays */
+extern int phalcon_array_append(zval **arr, zval *value, int separate TSRMLS_DC);
+extern int phalcon_array_append_long(zval **arr, long value, int separate TSRMLS_DC);
+extern int phalcon_array_append_string(zval **arr, char *value, uint value_length, int separate TSRMLS_DC);
+
+/** Modify arrays */
+extern int phalcon_array_update_zval(zval **arr, zval *index, zval **value, int flags TSRMLS_DC);
+extern int phalcon_array_update_zval_bool(zval **arr, zval *index, int value, int flags TSRMLS_DC);
+extern int phalcon_array_update_zval_string(zval **arr, zval *index, char *value, uint value_length, int flags TSRMLS_DC);
+
+extern int phalcon_array_update_string(zval **arr, char *index, uint index_length, zval **value, int flags TSRMLS_DC);
+extern int phalcon_array_update_string_bool(zval **arr, char *index, uint index_length, int value, int flags TSRMLS_DC);
+extern int phalcon_array_update_string_long(zval **arr, char *index, uint index_length, long value, int flags TSRMLS_DC);
+extern int phalcon_array_update_string_string(zval **arr, char *index, uint index_length, char *value, uint value_length, int flags TSRMLS_DC);
+
+extern int phalcon_array_update_long(zval **arr, ulong index, zval **value, int flags TSRMLS_DC);
+extern int phalcon_array_update_long_string(zval **arr, ulong index, char *value, uint value_length, int flags TSRMLS_DC);
+extern int phalcon_array_update_long_long(zval **arr, ulong index, long value, int flags TSRMLS_DC);
+extern int phalcon_array_update_long_bool(zval **arr, ulong index, int value, int flags TSRMLS_DC);
+
+/** Update/Append two dimension arrays */
+extern void phalcon_array_update_multi_2(zval **config, zval *index1, zval *index2, zval **value, int flags TSRMLS_DC);
+extern void phalcon_array_update_string_multi_2(zval **arr, zval *index1, char *index2, uint index2_length, zval **value, int flags TSRMLS_DC);
+extern void phalcon_array_update_long_long_multi_2(zval **arr, long index1, long index2, zval **value, int flags TSRMLS_DC);
+extern void phalcon_array_update_long_string_multi_2(zval **arr, long index1, char *index2, uint index2_length, zval **value, int flags TSRMLS_DC);
+extern void phalcon_array_update_append_multi_2(zval **arr, zval *index1, zval *value, int flags TSRMLS_DC);
+
+/** Update/Append three dimension arrays */
+extern void phalcon_array_update_zval_string_append_multi_3(zval **arr, zval *index1, char *index2, uint index2_length, zval **value, int flags TSRMLS_DC);
+extern void phalcon_array_update_zval_zval_zval_multi_3(zval **arr, zval *index1, zval *index2, zval *index3, zval **value, int flags TSRMLS_DC);
+extern void phalcon_array_update_string_zval_zval_multi_3(zval **arr, zval *index1, zval *index2, char *index3, uint index3_length, zval **value, int flags TSRMLS_DC);
+extern void phalcon_array_update_zval_string_string_multi_3(zval **arr, zval *index1, char *index2, uint index2_length, char *index3, uint index3_length, zval **value, int flags TSRMLS_DC);
+
+/** Fetch items from arrays */
+extern int phalcon_array_fetch(zval **return_value, zval *arr, zval *index, int silent TSRMLS_DC);
+extern int phalcon_array_fetch_string(zval **return_value, zval *arr, char *index, uint index_length, int silent TSRMLS_DC);
+extern int phalcon_array_fetch_long(zval **return_value, zval *arr, ulong index, int silent TSRMLS_DC);
+
View
47 ext/kernel/assert.c
@@ -0,0 +1,47 @@
+
+/*
+ +------------------------------------------------------------------------+
+ | Phalcon Framework |
+ +------------------------------------------------------------------------+
+ | Copyright (c) 2011-2012 Phalcon Team (http://www.phalconphp.com) |
+ +------------------------------------------------------------------------+
+ | This source file is subject to the New BSD License that is bundled |
+ | with this package in the file docs/LICENSE.txt. |
+ | |
+ | If you did not receive a copy of the license and are unable to |
+ | obtain it through the world-wide-web, please send an email |
+ | to license@phalconphp.com so we can send you a copy immediately. |
+ +------------------------------------------------------------------------+
+ | Authors: Andres Gutierrez <andres@phalconphp.com> |
+ | Eduar Carvajal <eduar@phalconphp.com> |
+ +------------------------------------------------------------------------+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_phalcon.h"
+#include "kernel/debug.h"
+
+#ifndef PHALCON_RELEASE
+
+int phalcon_assert_class(zval *object, char *class_name TSRMLS_DC){
+ if (object) {
+ if (Z_TYPE_P(object) != IS_OBJECT) {
+ phalcon_error_space();
+ fprintf(phalcon_log, "AssertClass: [Failed] Value is not an object\n");
+ return FAILURE;
+ } else {
+ if (strcmp(Z_OBJCE_P(object)->name, class_name)) {
+ phalcon_error_space();
+ fprintf(phalcon_log, "AssertClass: [Failed] Object is not class %s, is %s\n", class_name, Z_OBJCE_P(object)->name);
+ return FAILURE;
+ }
+ }
+ }
+ return SUCCESS;
+}
+
+#endif
View
24 ext/kernel/assert.h
@@ -0,0 +1,24 @@
+
+/*
+ +------------------------------------------------------------------------+
+ | Phalcon Framework |
+ +------------------------------------------------------------------------+
+ | Copyright (c) 2011-2012 Phalcon Team (http://www.phalconphp.com) |
+ +------------------------------------------------------------------------+
+ | This source file is subject to the New BSD License that is bundled |
+ | with this package in the file docs/LICENSE.txt. |
+ | |
+ | If you did not receive a copy of the license and are unable to |
+ | obtain it through the world-wide-web, please send an email |
+ | to license@phalconphp.com so we can send you a copy immediately. |
+ +------------------------------------------------------------------------+
+ | Authors: Andres Gutierrez <andres@phalconphp.com> |
+ | Eduar Carvajal <eduar@phalconphp.com> |
+ +------------------------------------------------------------------------+
+*/
+
+#ifndef PHALCON_RELEASE
+
+extern int phalcon_assert_class(zval *object, char *class_name TSRMLS_DC);
+
+#endif
View
769 ext/kernel/concat.c
@@ -0,0 +1,769 @@
+
+/*
+ +------------------------------------------------------------------------+
+ | Phalcon Framework |
+ +------------------------------------------------------------------------+
+ | Copyright (c) 2011-2012 Phalcon Team (http://www.phalconphp.com) |
+ +------------------------------------------------------------------------+
+ | This source file is subject to the New BSD License that is bundled |
+ | with this package in the file docs/LICENSE.txt. |
+ | |
+ | If you did not receive a copy of the license and are unable to |
+ | obtain it through the world-wide-web, please send an email |
+ | to license@phalconphp.com so we can send you a copy immediately. |
+ +------------------------------------------------------------------------+
+ | Authors: Andres Gutierrez <andres@phalconphp.com> |
+ | Eduar Carvajal <eduar@phalconphp.com> |
+ +------------------------------------------------------------------------+
+*/
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_phalcon.h"
+#include "ext/standard/php_string.h"
+
+#include "kernel/main.h"
+#include "kernel/memory.h"
+#include "kernel/concat.h"
+
+void phalcon_concat_sv(zval *result, char *op1, zend_uint op1_len, zval *op2 TSRMLS_DC){
+
+ zval op2_copy;
+ int use_copy2 = 0;
+
+ if (Z_TYPE_P(op2) != IS_STRING) {
+ zend_make_printable_zval(op2, &op2_copy, &use_copy2);
+ if (use_copy2) {
+ op2 = &op2_copy;
+ }
+ }
+
+ Z_STRLEN_P(result) = op1_len + Z_STRLEN_P(op2);
+ Z_STRVAL_P(result) = (char *) emalloc(Z_STRLEN_P(result) + 1);
+ memcpy(Z_STRVAL_P(result), op1, op1_len);
+ memcpy(Z_STRVAL_P(result)+op1_len, Z_STRVAL_P(op2), Z_STRLEN_P(op2));
+ Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
+ Z_TYPE_P(result) = IS_STRING;
+
+ if (use_copy2) {
+ zval_dtor(op2);
+ }
+
+}
+
+void phalcon_concat_svs(zval *result, char *op1, zend_uint op1_len, zval *op2, char *op3, zend_uint op3_len TSRMLS_DC){
+
+ zval op2_copy;
+ int use_copy2 = 0;
+
+ if (Z_TYPE_P(op2) != IS_STRING) {
+ zend_make_printable_zval(op2, &op2_copy, &use_copy2);
+ if (use_copy2) {
+ op2 = &op2_copy;
+ }
+ }
+
+ Z_STRLEN_P(result) = op1_len + Z_STRLEN_P(op2) + op3_len;
+ Z_STRVAL_P(result) = (char *) emalloc(Z_STRLEN_P(result) + 1);
+ memcpy(Z_STRVAL_P(result), op1, op1_len);
+ memcpy(Z_STRVAL_P(result)+op1_len, Z_STRVAL_P(op2), Z_STRLEN_P(op2));
+ memcpy(Z_STRVAL_P(result)+op1_len+Z_STRLEN_P(op2), op3, op3_len);
+ Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
+ Z_TYPE_P(result) = IS_STRING;
+
+ if (use_copy2) {
+ zval_dtor(op2);
+ }
+
+}
+
+void phalcon_concat_svsv(zval *result, char *op1, zend_uint op1_len, zval *op2, char *op3, zend_uint op3_len, zval *op4 TSRMLS_DC){
+
+ zval op2_copy, op4_copy;
+ int use_copy2 = 0, use_copy4 = 0;
+
+ if (Z_TYPE_P(op2) != IS_STRING) {
+ zend_make_printable_zval(op2, &op2_copy, &use_copy2);
+ if (use_copy2) {
+ op2 = &op2_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op4) != IS_STRING) {
+ zend_make_printable_zval(op4, &op4_copy, &use_copy4);
+ if (use_copy4) {
+ op4 = &op4_copy;
+ }
+ }
+
+ Z_STRLEN_P(result) = op1_len + Z_STRLEN_P(op2) + op3_len + Z_STRLEN_P(op4);
+ Z_STRVAL_P(result) = (char *) emalloc(Z_STRLEN_P(result) + 1);
+ memcpy(Z_STRVAL_P(result), op1, op1_len);
+ memcpy(Z_STRVAL_P(result)+op1_len, Z_STRVAL_P(op2), Z_STRLEN_P(op2));
+ memcpy(Z_STRVAL_P(result)+op1_len+Z_STRLEN_P(op2), op3, op3_len);
+ memcpy(Z_STRVAL_P(result)+op1_len+Z_STRLEN_P(op2)+op3_len, Z_STRVAL_P(op4), Z_STRLEN_P(op4));
+ Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
+ Z_TYPE_P(result) = IS_STRING;
+
+ if (use_copy2) {
+ zval_dtor(op2);
+ }
+
+ if (use_copy4) {
+ zval_dtor(op4);
+ }
+
+}
+
+void phalcon_concat_svsvs(zval *result, char *op1, zend_uint op1_len, zval *op2, char *op3, zend_uint op3_len, zval *op4, char *op5, zend_uint op5_len TSRMLS_DC){
+
+ zval op2_copy, op4_copy;
+ int use_copy2 = 0, use_copy4 = 0;
+
+ if (Z_TYPE_P(op2) != IS_STRING) {
+ zend_make_printable_zval(op2, &op2_copy, &use_copy2);
+ if (use_copy2) {
+ op2 = &op2_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op4) != IS_STRING) {
+ zend_make_printable_zval(op4, &op4_copy, &use_copy4);
+ if (use_copy4) {
+ op4 = &op4_copy;
+ }
+ }
+
+ Z_STRLEN_P(result) = op1_len + Z_STRLEN_P(op2) + op3_len + Z_STRLEN_P(op4) + op5_len;
+ Z_STRVAL_P(result) = (char *) emalloc(Z_STRLEN_P(result) + 1);
+ memcpy(Z_STRVAL_P(result), op1, op1_len);
+ memcpy(Z_STRVAL_P(result)+op1_len, Z_STRVAL_P(op2), Z_STRLEN_P(op2));
+ memcpy(Z_STRVAL_P(result)+op1_len+Z_STRLEN_P(op2), op3, op3_len);
+ memcpy(Z_STRVAL_P(result)+op1_len+Z_STRLEN_P(op2)+op3_len, Z_STRVAL_P(op4), Z_STRLEN_P(op4));
+ memcpy(Z_STRVAL_P(result)+op1_len+Z_STRLEN_P(op2)+op3_len+Z_STRLEN_P(op4), op5, op5_len);
+ Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
+ Z_TYPE_P(result) = IS_STRING;
+
+ if (use_copy2) {
+ zval_dtor(op2);
+ }
+
+ if (use_copy4) {
+ zval_dtor(op4);
+ }
+
+}
+
+void phalcon_concat_svsvsv(zval *result, char *op1, zend_uint op1_len, zval *op2, char *op3, zend_uint op3_len, zval *op4, char *op5, zend_uint op5_len, zval *op6 TSRMLS_DC){
+
+ zval op2_copy, op4_copy, op6_copy;
+ int use_copy2 = 0, use_copy4 = 0, use_copy6 = 0;
+
+ if (Z_TYPE_P(op2) != IS_STRING) {
+ zend_make_printable_zval(op2, &op2_copy, &use_copy2);
+ if (use_copy2) {
+ op2 = &op2_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op4) != IS_STRING) {
+ zend_make_printable_zval(op4, &op4_copy, &use_copy4);
+ if (use_copy4) {
+ op4 = &op4_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op6) != IS_STRING) {
+ zend_make_printable_zval(op6, &op6_copy, &use_copy6);
+ if (use_copy6) {
+ op6 = &op6_copy;
+ }
+ }
+
+ Z_STRLEN_P(result) = op1_len + Z_STRLEN_P(op2) + op3_len + Z_STRLEN_P(op4) + op5_len + Z_STRLEN_P(op6);
+ Z_STRVAL_P(result) = (char *) emalloc(Z_STRLEN_P(result) + 1);
+ memcpy(Z_STRVAL_P(result), op1, op1_len);
+ memcpy(Z_STRVAL_P(result)+op1_len, Z_STRVAL_P(op2), Z_STRLEN_P(op2));
+ memcpy(Z_STRVAL_P(result)+op1_len+Z_STRLEN_P(op2), op3, op3_len);
+ memcpy(Z_STRVAL_P(result)+op1_len+Z_STRLEN_P(op2)+op3_len, Z_STRVAL_P(op4), Z_STRLEN_P(op4));
+ memcpy(Z_STRVAL_P(result)+op1_len+Z_STRLEN_P(op2)+op3_len+Z_STRLEN_P(op4), op5, op5_len);
+ memcpy(Z_STRVAL_P(result)+op1_len+Z_STRLEN_P(op2)+op3_len+Z_STRLEN_P(op4)+op5_len, Z_STRVAL_P(op6), Z_STRLEN_P(op6));
+ Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
+ Z_TYPE_P(result) = IS_STRING;
+
+ if (use_copy2) {
+ zval_dtor(op2);
+ }
+
+ if (use_copy4) {
+ zval_dtor(op4);
+ }
+
+ if (use_copy6) {
+ zval_dtor(op6);
+ }
+
+}
+
+void phalcon_concat_svsvsvs(zval *result, char *op1, zend_uint op1_len, zval *op2, char *op3, zend_uint op3_len, zval *op4, char *op5, zend_uint op5_len, zval *op6, char *op7, zend_uint op7_len TSRMLS_DC){
+
+ zval op2_copy, op4_copy, op6_copy;
+ int use_copy2 = 0, use_copy4 = 0, use_copy6 = 0;
+
+ if (Z_TYPE_P(op2) != IS_STRING) {
+ zend_make_printable_zval(op2, &op2_copy, &use_copy2);
+ if (use_copy2) {
+ op2 = &op2_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op4) != IS_STRING) {
+ zend_make_printable_zval(op4, &op4_copy, &use_copy4);
+ if (use_copy4) {
+ op4 = &op4_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op6) != IS_STRING) {
+ zend_make_printable_zval(op6, &op6_copy, &use_copy6);
+ if (use_copy6) {
+ op6 = &op6_copy;
+ }
+ }
+
+ Z_STRLEN_P(result) = op1_len + Z_STRLEN_P(op2) + op3_len + Z_STRLEN_P(op4) + op5_len + Z_STRLEN_P(op6) + op7_len;
+ Z_STRVAL_P(result) = (char *) emalloc(Z_STRLEN_P(result) + 1);
+ memcpy(Z_STRVAL_P(result), op1, op1_len);
+ memcpy(Z_STRVAL_P(result)+op1_len, Z_STRVAL_P(op2), Z_STRLEN_P(op2));
+ memcpy(Z_STRVAL_P(result)+op1_len+Z_STRLEN_P(op2), op3, op3_len);
+ memcpy(Z_STRVAL_P(result)+op1_len+Z_STRLEN_P(op2)+op3_len, Z_STRVAL_P(op4), Z_STRLEN_P(op4));
+ memcpy(Z_STRVAL_P(result)+op1_len+Z_STRLEN_P(op2)+op3_len+Z_STRLEN_P(op4), op5, op5_len);
+ memcpy(Z_STRVAL_P(result)+op1_len+Z_STRLEN_P(op2)+op3_len+Z_STRLEN_P(op4)+op5_len, Z_STRVAL_P(op6), Z_STRLEN_P(op6));
+ memcpy(Z_STRVAL_P(result)+op1_len+Z_STRLEN_P(op2)+op3_len+Z_STRLEN_P(op4)+op5_len+Z_STRLEN_P(op6), op7, op7_len);
+ Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
+ Z_TYPE_P(result) = IS_STRING;
+
+ if (use_copy2) {
+ zval_dtor(op2);
+ }
+
+ if (use_copy4) {
+ zval_dtor(op4);
+ }
+
+ if (use_copy6) {
+ zval_dtor(op6);
+ }
+
+}
+
+void phalcon_concat_svsvv(zval *result, char *op1, zend_uint op1_len, zval *op2, char *op3, zend_uint op3_len, zval *op4, zval *op5 TSRMLS_DC){
+
+ zval op2_copy, op4_copy, op5_copy;
+ int use_copy2 = 0, use_copy4 = 0, use_copy5 = 0;
+
+ if (Z_TYPE_P(op2) != IS_STRING) {
+ zend_make_printable_zval(op2, &op2_copy, &use_copy2);
+ if (use_copy2) {
+ op2 = &op2_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op4) != IS_STRING) {
+ zend_make_printable_zval(op4, &op4_copy, &use_copy4);
+ if (use_copy4) {
+ op4 = &op4_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op5) != IS_STRING) {
+ zend_make_printable_zval(op5, &op5_copy, &use_copy5);
+ if (use_copy5) {
+ op5 = &op5_copy;
+ }
+ }
+
+ Z_STRLEN_P(result) = op1_len + Z_STRLEN_P(op2) + op3_len + Z_STRLEN_P(op4) + Z_STRLEN_P(op5);
+ Z_STRVAL_P(result) = (char *) emalloc(Z_STRLEN_P(result) + 1);
+ memcpy(Z_STRVAL_P(result), op1, op1_len);
+ memcpy(Z_STRVAL_P(result)+op1_len, Z_STRVAL_P(op2), Z_STRLEN_P(op2));
+ memcpy(Z_STRVAL_P(result)+op1_len+Z_STRLEN_P(op2), op3, op3_len);
+ memcpy(Z_STRVAL_P(result)+op1_len+Z_STRLEN_P(op2)+op3_len, Z_STRVAL_P(op4), Z_STRLEN_P(op4));
+ memcpy(Z_STRVAL_P(result)+op1_len+Z_STRLEN_P(op2)+op3_len+Z_STRLEN_P(op4), Z_STRVAL_P(op5), Z_STRLEN_P(op5));
+ Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
+ Z_TYPE_P(result) = IS_STRING;
+
+ if (use_copy2) {
+ zval_dtor(op2);
+ }
+
+ if (use_copy4) {
+ zval_dtor(op4);
+ }
+
+ if (use_copy5) {
+ zval_dtor(op5);
+ }
+
+}
+
+void phalcon_concat_svv(zval *result, char *op1, zend_uint op1_len, zval *op2, zval *op3 TSRMLS_DC){
+
+ zval op2_copy, op3_copy;
+ int use_copy2 = 0, use_copy3 = 0;
+
+ if (Z_TYPE_P(op2) != IS_STRING) {
+ zend_make_printable_zval(op2, &op2_copy, &use_copy2);
+ if (use_copy2) {
+ op2 = &op2_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op3) != IS_STRING) {
+ zend_make_printable_zval(op3, &op3_copy, &use_copy3);
+ if (use_copy3) {
+ op3 = &op3_copy;
+ }
+ }
+
+ Z_STRLEN_P(result) = op1_len + Z_STRLEN_P(op2) + Z_STRLEN_P(op3);
+ Z_STRVAL_P(result) = (char *) emalloc(Z_STRLEN_P(result) + 1);
+ memcpy(Z_STRVAL_P(result), op1, op1_len);
+ memcpy(Z_STRVAL_P(result)+op1_len, Z_STRVAL_P(op2), Z_STRLEN_P(op2));
+ memcpy(Z_STRVAL_P(result)+op1_len+Z_STRLEN_P(op2), Z_STRVAL_P(op3), Z_STRLEN_P(op3));
+ Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
+ Z_TYPE_P(result) = IS_STRING;
+
+ if (use_copy2) {
+ zval_dtor(op2);
+ }
+
+ if (use_copy3) {
+ zval_dtor(op3);
+ }
+
+}
+
+void phalcon_concat_vs(zval *result, zval *op1, char *op2, zend_uint op2_len TSRMLS_DC){
+
+ zval op1_copy;
+ int use_copy1 = 0;
+
+ if (Z_TYPE_P(op1) != IS_STRING) {
+ zend_make_printable_zval(op1, &op1_copy, &use_copy1);
+ if (use_copy1) {
+ op1 = &op1_copy;
+ }
+ }
+
+ Z_STRLEN_P(result) = Z_STRLEN_P(op1) + op2_len;
+ Z_STRVAL_P(result) = (char *) emalloc(Z_STRLEN_P(result) + 1);
+ memcpy(Z_STRVAL_P(result), Z_STRVAL_P(op1), Z_STRLEN_P(op1));
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1), op2, op2_len);
+ Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
+ Z_TYPE_P(result) = IS_STRING;
+
+ if (use_copy1) {
+ zval_dtor(op1);
+ }
+
+}
+
+void phalcon_concat_vsv(zval *result, zval *op1, char *op2, zend_uint op2_len, zval *op3 TSRMLS_DC){
+
+ zval op1_copy, op3_copy;
+ int use_copy1 = 0, use_copy3 = 0;
+
+ if (Z_TYPE_P(op1) != IS_STRING) {
+ zend_make_printable_zval(op1, &op1_copy, &use_copy1);
+ if (use_copy1) {
+ op1 = &op1_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op3) != IS_STRING) {
+ zend_make_printable_zval(op3, &op3_copy, &use_copy3);
+ if (use_copy3) {
+ op3 = &op3_copy;
+ }
+ }
+
+ Z_STRLEN_P(result) = Z_STRLEN_P(op1) + op2_len + Z_STRLEN_P(op3);
+ Z_STRVAL_P(result) = (char *) emalloc(Z_STRLEN_P(result) + 1);
+ memcpy(Z_STRVAL_P(result), Z_STRVAL_P(op1), Z_STRLEN_P(op1));
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1), op2, op2_len);
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1)+op2_len, Z_STRVAL_P(op3), Z_STRLEN_P(op3));
+ Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
+ Z_TYPE_P(result) = IS_STRING;
+
+ if (use_copy1) {
+ zval_dtor(op1);
+ }
+
+ if (use_copy3) {
+ zval_dtor(op3);
+ }
+
+}
+
+void phalcon_concat_vsvs(zval *result, zval *op1, char *op2, zend_uint op2_len, zval *op3, char *op4, zend_uint op4_len TSRMLS_DC){
+
+ zval op1_copy, op3_copy;
+ int use_copy1 = 0, use_copy3 = 0;
+
+ if (Z_TYPE_P(op1) != IS_STRING) {
+ zend_make_printable_zval(op1, &op1_copy, &use_copy1);
+ if (use_copy1) {
+ op1 = &op1_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op3) != IS_STRING) {
+ zend_make_printable_zval(op3, &op3_copy, &use_copy3);
+ if (use_copy3) {
+ op3 = &op3_copy;
+ }
+ }
+
+ Z_STRLEN_P(result) = Z_STRLEN_P(op1) + op2_len + Z_STRLEN_P(op3) + op4_len;
+ Z_STRVAL_P(result) = (char *) emalloc(Z_STRLEN_P(result) + 1);
+ memcpy(Z_STRVAL_P(result), Z_STRVAL_P(op1), Z_STRLEN_P(op1));
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1), op2, op2_len);
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1)+op2_len, Z_STRVAL_P(op3), Z_STRLEN_P(op3));
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1)+op2_len+Z_STRLEN_P(op3), op4, op4_len);
+ Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
+ Z_TYPE_P(result) = IS_STRING;
+
+ if (use_copy1) {
+ zval_dtor(op1);
+ }
+
+ if (use_copy3) {
+ zval_dtor(op3);
+ }
+
+}
+
+void phalcon_concat_vsvsvs(zval *result, zval *op1, char *op2, zend_uint op2_len, zval *op3, char *op4, zend_uint op4_len, zval *op5, char *op6, zend_uint op6_len TSRMLS_DC){
+
+ zval op1_copy, op3_copy, op5_copy;
+ int use_copy1 = 0, use_copy3 = 0, use_copy5 = 0;
+
+ if (Z_TYPE_P(op1) != IS_STRING) {
+ zend_make_printable_zval(op1, &op1_copy, &use_copy1);
+ if (use_copy1) {
+ op1 = &op1_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op3) != IS_STRING) {
+ zend_make_printable_zval(op3, &op3_copy, &use_copy3);
+ if (use_copy3) {
+ op3 = &op3_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op5) != IS_STRING) {
+ zend_make_printable_zval(op5, &op5_copy, &use_copy5);
+ if (use_copy5) {
+ op5 = &op5_copy;
+ }
+ }
+
+ Z_STRLEN_P(result) = Z_STRLEN_P(op1) + op2_len + Z_STRLEN_P(op3) + op4_len + Z_STRLEN_P(op5) + op6_len;
+ Z_STRVAL_P(result) = (char *) emalloc(Z_STRLEN_P(result) + 1);
+ memcpy(Z_STRVAL_P(result), Z_STRVAL_P(op1), Z_STRLEN_P(op1));
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1), op2, op2_len);
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1)+op2_len, Z_STRVAL_P(op3), Z_STRLEN_P(op3));
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1)+op2_len+Z_STRLEN_P(op3), op4, op4_len);
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1)+op2_len+Z_STRLEN_P(op3)+op4_len, Z_STRVAL_P(op5), Z_STRLEN_P(op5));
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1)+op2_len+Z_STRLEN_P(op3)+op4_len+Z_STRLEN_P(op5), op6, op6_len);
+ Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
+ Z_TYPE_P(result) = IS_STRING;
+
+ if (use_copy1) {
+ zval_dtor(op1);
+ }
+
+ if (use_copy3) {
+ zval_dtor(op3);
+ }
+
+ if (use_copy5) {
+ zval_dtor(op5);
+ }
+
+}
+
+void phalcon_concat_vsvsvsv(zval *result, zval *op1, char *op2, zend_uint op2_len, zval *op3, char *op4, zend_uint op4_len, zval *op5, char *op6, zend_uint op6_len, zval *op7 TSRMLS_DC){
+
+ zval op1_copy, op3_copy, op5_copy, op7_copy;
+ int use_copy1 = 0, use_copy3 = 0, use_copy5 = 0, use_copy7 = 0;
+
+ if (Z_TYPE_P(op1) != IS_STRING) {
+ zend_make_printable_zval(op1, &op1_copy, &use_copy1);
+ if (use_copy1) {
+ op1 = &op1_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op3) != IS_STRING) {
+ zend_make_printable_zval(op3, &op3_copy, &use_copy3);
+ if (use_copy3) {
+ op3 = &op3_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op5) != IS_STRING) {
+ zend_make_printable_zval(op5, &op5_copy, &use_copy5);
+ if (use_copy5) {
+ op5 = &op5_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op7) != IS_STRING) {
+ zend_make_printable_zval(op7, &op7_copy, &use_copy7);
+ if (use_copy7) {
+ op7 = &op7_copy;
+ }
+ }
+
+ Z_STRLEN_P(result) = Z_STRLEN_P(op1) + op2_len + Z_STRLEN_P(op3) + op4_len + Z_STRLEN_P(op5) + op6_len + Z_STRLEN_P(op7);
+ Z_STRVAL_P(result) = (char *) emalloc(Z_STRLEN_P(result) + 1);
+ memcpy(Z_STRVAL_P(result), Z_STRVAL_P(op1), Z_STRLEN_P(op1));
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1), op2, op2_len);
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1)+op2_len, Z_STRVAL_P(op3), Z_STRLEN_P(op3));
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1)+op2_len+Z_STRLEN_P(op3), op4, op4_len);
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1)+op2_len+Z_STRLEN_P(op3)+op4_len, Z_STRVAL_P(op5), Z_STRLEN_P(op5));
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1)+op2_len+Z_STRLEN_P(op3)+op4_len+Z_STRLEN_P(op5), op6, op6_len);
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1)+op2_len+Z_STRLEN_P(op3)+op4_len+Z_STRLEN_P(op5)+op6_len, Z_STRVAL_P(op7), Z_STRLEN_P(op7));
+ Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
+ Z_TYPE_P(result) = IS_STRING;
+
+ if (use_copy1) {
+ zval_dtor(op1);
+ }
+
+ if (use_copy3) {
+ zval_dtor(op3);
+ }
+
+ if (use_copy5) {
+ zval_dtor(op5);
+ }
+
+ if (use_copy7) {
+ zval_dtor(op7);
+ }
+
+}
+
+void phalcon_concat_vv(zval *result, zval *op1, zval *op2 TSRMLS_DC){
+
+ zval op1_copy, op2_copy;
+ int use_copy1 = 0, use_copy2 = 0;
+
+ if (Z_TYPE_P(op1) != IS_STRING) {
+ zend_make_printable_zval(op1, &op1_copy, &use_copy1);
+ if (use_copy1) {
+ op1 = &op1_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op2) != IS_STRING) {
+ zend_make_printable_zval(op2, &op2_copy, &use_copy2);
+ if (use_copy2) {
+ op2 = &op2_copy;
+ }
+ }
+
+ Z_STRLEN_P(result) = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
+ Z_STRVAL_P(result) = (char *) emalloc(Z_STRLEN_P(result) + 1);
+ memcpy(Z_STRVAL_P(result), Z_STRVAL_P(op1), Z_STRLEN_P(op1));
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
+ Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
+ Z_TYPE_P(result) = IS_STRING;
+
+ if (use_copy1) {
+ zval_dtor(op1);
+ }
+
+ if (use_copy2) {
+ zval_dtor(op2);
+ }
+
+}
+
+void phalcon_concat_vvsv(zval *result, zval *op1, zval *op2, char *op3, zend_uint op3_len, zval *op4 TSRMLS_DC){
+
+ zval op1_copy, op2_copy, op4_copy;
+ int use_copy1 = 0, use_copy2 = 0, use_copy4 = 0;
+
+ if (Z_TYPE_P(op1) != IS_STRING) {
+ zend_make_printable_zval(op1, &op1_copy, &use_copy1);
+ if (use_copy1) {
+ op1 = &op1_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op2) != IS_STRING) {
+ zend_make_printable_zval(op2, &op2_copy, &use_copy2);
+ if (use_copy2) {
+ op2 = &op2_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op4) != IS_STRING) {
+ zend_make_printable_zval(op4, &op4_copy, &use_copy4);
+ if (use_copy4) {
+ op4 = &op4_copy;
+ }
+ }
+
+ Z_STRLEN_P(result) = Z_STRLEN_P(op1) + Z_STRLEN_P(op2) + op3_len + Z_STRLEN_P(op4);
+ Z_STRVAL_P(result) = (char *) emalloc(Z_STRLEN_P(result) + 1);
+ memcpy(Z_STRVAL_P(result), Z_STRVAL_P(op1), Z_STRLEN_P(op1));
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1)+Z_STRLEN_P(op2), op3, op3_len);
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1)+Z_STRLEN_P(op2)+op3_len, Z_STRVAL_P(op4), Z_STRLEN_P(op4));
+ Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
+ Z_TYPE_P(result) = IS_STRING;
+
+ if (use_copy1) {
+ zval_dtor(op1);
+ }
+
+ if (use_copy2) {
+ zval_dtor(op2);
+ }
+
+ if (use_copy4) {
+ zval_dtor(op4);
+ }
+
+}
+
+void phalcon_concat_vvv(zval *result, zval *op1, zval *op2, zval *op3 TSRMLS_DC){
+
+ zval op1_copy, op2_copy, op3_copy;
+ int use_copy1 = 0, use_copy2 = 0, use_copy3 = 0;
+
+ if (Z_TYPE_P(op1) != IS_STRING) {
+ zend_make_printable_zval(op1, &op1_copy, &use_copy1);
+ if (use_copy1) {
+ op1 = &op1_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op2) != IS_STRING) {
+ zend_make_printable_zval(op2, &op2_copy, &use_copy2);
+ if (use_copy2) {
+ op2 = &op2_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op3) != IS_STRING) {
+ zend_make_printable_zval(op3, &op3_copy, &use_copy3);
+ if (use_copy3) {
+ op3 = &op3_copy;
+ }
+ }
+
+ Z_STRLEN_P(result) = Z_STRLEN_P(op1) + Z_STRLEN_P(op2) + Z_STRLEN_P(op3);
+ Z_STRVAL_P(result) = (char *) emalloc(Z_STRLEN_P(result) + 1);
+ memcpy(Z_STRVAL_P(result), Z_STRVAL_P(op1), Z_STRLEN_P(op1));
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1)+Z_STRLEN_P(op2), Z_STRVAL_P(op3), Z_STRLEN_P(op3));
+ Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
+ Z_TYPE_P(result) = IS_STRING;
+
+ if (use_copy1) {
+ zval_dtor(op1);
+ }
+
+ if (use_copy2) {
+ zval_dtor(op2);
+ }
+
+ if (use_copy3) {
+ zval_dtor(op3);
+ }
+
+}
+
+void phalcon_concat_vvvvv(zval *result, zval *op1, zval *op2, zval *op3, zval *op4, zval *op5 TSRMLS_DC){
+
+ zval op1_copy, op2_copy, op3_copy, op4_copy, op5_copy;
+ int use_copy1 = 0, use_copy2 = 0, use_copy3 = 0, use_copy4 = 0, use_copy5 = 0;
+
+ if (Z_TYPE_P(op1) != IS_STRING) {
+ zend_make_printable_zval(op1, &op1_copy, &use_copy1);
+ if (use_copy1) {
+ op1 = &op1_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op2) != IS_STRING) {
+ zend_make_printable_zval(op2, &op2_copy, &use_copy2);
+ if (use_copy2) {
+ op2 = &op2_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op3) != IS_STRING) {
+ zend_make_printable_zval(op3, &op3_copy, &use_copy3);
+ if (use_copy3) {
+ op3 = &op3_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op4) != IS_STRING) {
+ zend_make_printable_zval(op4, &op4_copy, &use_copy4);
+ if (use_copy4) {
+ op4 = &op4_copy;
+ }
+ }
+
+ if (Z_TYPE_P(op5) != IS_STRING) {
+ zend_make_printable_zval(op5, &op5_copy, &use_copy5);
+ if (use_copy5) {
+ op5 = &op5_copy;
+ }
+ }
+
+ Z_STRLEN_P(result) = Z_STRLEN_P(op1) + Z_STRLEN_P(op2) + Z_STRLEN_P(op3) + Z_STRLEN_P(op4) + Z_STRLEN_P(op5);
+ Z_STRVAL_P(result) = (char *) emalloc(Z_STRLEN_P(result) + 1);
+ memcpy(Z_STRVAL_P(result), Z_STRVAL_P(op1), Z_STRLEN_P(op1));
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1)+Z_STRLEN_P(op2), Z_STRVAL_P(op3), Z_STRLEN_P(op3));
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1)+Z_STRLEN_P(op2)+Z_STRLEN_P(op3), Z_STRVAL_P(op4), Z_STRLEN_P(op4));
+ memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1)+Z_STRLEN_P(op2)+Z_STRLEN_P(op3)+Z_STRLEN_P(op4), Z_STRVAL_P(op5), Z_STRLEN_P(op5));
+ Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
+ Z_TYPE_P(result) = IS_STRING;
+
+ if (use_copy1) {
+ zval_dtor(op1);
+ }
+
+ if (use_copy2) {
+ zval_dtor(op2);
+ }
+
+ if (use_copy3) {
+ zval_dtor(op3);
+ }
+
+ if (use_copy4) {
+ zval_dtor(op4);
+ }
+
+ if (use_copy5) {
+ zval_dtor(op5);
+ }
+
+}
+
View
71 ext/kernel/concat.h
@@ -0,0 +1,71 @@
+
+/*
+ +------------------------------------------------------------------------+
+ | Phalcon Framework |
+ +------------------------------------------------------------------------+
+ | Copyright (c) 2011-2012 Phalcon Team (http://www.phalconphp.com) |
+ +------------------------------------------------------------------------+
+ | This source file is subject to the New BSD License that is bundled |
+ | with this package in the file docs/LICENSE.txt. |
+ | |
+ | If you did not receive a copy of the license and are unable to |
+ | obtain it through the world-wide-web, please send an email |
+ | to license@phalconphp.com so we can send you a copy immediately. |
+ +------------------------------------------------------------------------+
+ | Authors: Andres Gutierrez <andres@phalconphp.com> |
+ | Eduar Carvajal <eduar@phalconphp.com> |
+ +------------------------------------------------------------------------+
+*/
+
+#define PHALCON_CONCAT_SV(result, op1, op2) \
+ phalcon_concat_sv(result, op1, strlen(op1), op2 TSRMLS_CC);
+#define PHALCON_CONCAT_SVS(result, op1, op2, op3) \
+ phalcon_concat_svs(result, op1, strlen(op1), op2, op3, strlen(op3) TSRMLS_CC);
+#define PHALCON_CONCAT_SVSV(result, op1, op2, op3, op4) \
+ phalcon_concat_svsv(result, op1, strlen(op1), op2, op3, strlen(op3), op4 TSRMLS_CC);
+#define PHALCON_CONCAT_SVSVS(result, op1, op2, op3, op4, op5) \
+ phalcon_concat_svsvs(result, op1, strlen(op1), op2, op3, strlen(op3), op4, op5, strlen(op5) TSRMLS_CC);
+#define PHALCON_CONCAT_SVSVSV(result, op1, op2, op3, op4, op5, op6) \
+ phalcon_concat_svsvsv(result, op1, strlen(op1), op2, op3, strlen(op3), op4, op5, strlen(op5), op6 TSRMLS_CC);
+#define PHALCON_CONCAT_SVSVSVS(result, op1, op2, op3, op4, op5, op6, op7) \
+ phalcon_concat_svsvsvs(result, op1, strlen(op1), op2, op3, strlen(op3), op4, op5, strlen(op5), op6, op7, strlen(op7) TSRMLS_CC);
+#define PHALCON_CONCAT_SVSVV(result, op1, op2, op3, op4, op5) \
+ phalcon_concat_svsvv(result, op1, strlen(op1), op2, op3, strlen(op3), op4, op5 TSRMLS_CC);
+#define PHALCON_CONCAT_SVV(result, op1, op2, op3) \
+ phalcon_concat_svv(result, op1, strlen(op1), op2, op3 TSRMLS_CC);
+#define PHALCON_CONCAT_VS(result, op1, op2) \
+ phalcon_concat_vs(result, op1, op2, strlen(op2) TSRMLS_CC);
+#define PHALCON_CONCAT_VSV(result, op1, op2, op3) \
+ phalcon_concat_vsv(result, op1, op2, strlen(op2), op3 TSRMLS_CC);
+#define PHALCON_CONCAT_VSVS(result, op1, op2, op3, op4) \
+ phalcon_concat_vsvs(result, op1, op2, strlen(op2), op3, op4, strlen(op4) TSRMLS_CC);
+#define PHALCON_CONCAT_VSVSVS(result, op1, op2, op3, op4, op5, op6) \
+ phalcon_concat_vsvsvs(result, op1, op2, strlen(op2), op3, op4, strlen(op4), op5, op6, strlen(op6) TSRMLS_CC);
+#define PHALCON_CONCAT_VSVSVSV(result, op1, op2, op3, op4, op5, op6, op7) \
+ phalcon_concat_vsvsvsv(result, op1, op2, strlen(op2), op3, op4, strlen(op4), op5, op6, strlen(op6), op7 TSRMLS_CC);
+#define PHALCON_CONCAT_VV(result, op1, op2) \
+ phalcon_concat_vv(result, op1, op2 TSRMLS_CC);
+#define PHALCON_CONCAT_VVSV(result, op1, op2, op3, op4) \
+ phalcon_concat_vvsv(result, op1, op2, op3, strlen(op3), op4 TSRMLS_CC);
+#define PHALCON_CONCAT_VVV(result, op1, op2, op3) \
+ phalcon_concat_vvv(result, op1, op2, op3 TSRMLS_CC);
+#define PHALCON_CONCAT_VVVVV(result, op1, op2, op3, op4, op5) \
+ phalcon_concat_vvvvv(result, op1, op2, op3, op4, op5 TSRMLS_CC);
+
+extern void phalcon_concat_sv(zval *result, char *op1, zend_uint op1_len, zval *op2 TSRMLS_DC);
+extern void phalcon_concat_svs(zval *result, char *op1, zend_uint op1_len, zval *op2, char *op3, zend_uint op3_len TSRMLS_DC);
+extern void phalcon_concat_svsv(zval *result, char *op1, zend_uint op1_len, zval *op2, char *op3, zend_uint op3_len, zval *op4 TSRMLS_DC);
+extern void phalcon_concat_svsvs(zval *result, char *op1, zend_uint op1_len, zval *op2, char *op3, zend_uint op3_len, zval *op4, char *op5, zend_uint op5_len TSRMLS_DC);
+extern void phalcon_concat_svsvsv(zval *result, char *op1, zend_uint op1_len, zval *op2, char *op3, zend_uint op3_len, zval *op4, char *op5, zend_uint op5_len, zval *op6 TSRMLS_DC);
+extern void phalcon_concat_svsvsvs(zval *result, char *op1, zend_uint op1_len, zval *op2, char *op3, zend_uint op3_len, zval *op4, char *op5, zend_uint op5_len, zval *op6, char *op7, zend_uint op7_len TSRMLS_DC);
+extern void phalcon_concat_svsvv(zval *result, char *op1, zend_uint op1_len, zval *op2, char *op3, zend_uint op3_len, zval *op4, zval *op5 TSRMLS_DC);
+extern void phalcon_concat_svv(zval *result, char *op1, zend_uint op1_len, zval *op2, zval *op3 TSRMLS_DC);
+extern void phalcon_concat_vs(zval *result, zval *op1, char *op2, zend_uint op2_len TSRMLS_DC);
+extern void phalcon_concat_vsv(zval *result, zval *op1, char *op2, zend_uint op2_len, zval *op3 TSRMLS_DC);
+extern void phalcon_concat_vsvs(zval *result, zval *op1, char *op2, zend_uint op2_len, zval *op3, char *op4, zend_uint op4_len TSRMLS_DC);
+extern void phalcon_concat_vsvsvs(zval *result, zval *op1, char *op2, zend_uint op2_len, zval *op3, char *op4, zend_uint op4_len, zval *op5, char *op6, zend_uint op6_len TSRMLS_DC);
+extern void phalcon_concat_vsvsvsv(zval *result, zval *op1, char *op2, zend_uint op2_len, zval *op3, char *op4, zend_uint op4_len, zval *op5, char *op6, zend_uint op6_len, zval *op7 TSRMLS_DC);
+extern void phalcon_concat_vv(zval *result, zval *op1, zval *op2 TSRMLS_DC);
+extern void phalcon_concat_vvsv(zval *result, zval *op1, zval *op2, char *op3, zend_uint op3_len, zval *op4 TSRMLS_DC);
+extern void phalcon_concat_vvv(zval *result, zval *op1, zval *op2, zval *op3 TSRMLS_DC);
+extern void phalcon_concat_vvvvv(zval *result, zval *op1, zval *op2, zval *op3, zval *op4, zval *op5 TSRMLS_DC);
View
332 ext/kernel/debug.c
@@ -0,0 +1,332 @@
+
+/*
+ +------------------------------------------------------------------------+
+ | Phalcon Framework |
+ +------------------------------------------------------------------------+
+ | Copyright (c) 2011-2012 Phalcon Team (http://www.phalconphp.com) |
+ +------------------------------------------------------------------------+
+ | This source file is subject to the New BSD License that is bundled |
+ | with this package in the file docs/LICENSE.txt. |
+ | |
+ | If you did not receive a copy of the license and are unable to |
+ | obtain it through the world-wide-web, please send an email |
+ | to license@phalconphp.com so we can send you a copy immediately. |
+ +------------------------------------------------------------------------+
+ | Authors: Andres Gutierrez <andres@phalconphp.com> |
+ | Eduar Carvajal <eduar@phalconphp.com> |
+ +------------------------------------------------------------------------+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_phalcon.h"
+#include "kernel/debug.h"
+
+/**
+ * Applies sprintf function to a variable list
+ */
+int phalcon_spprintf(char **message, int max_len, char *format, ...){
+ va_list arg;
+ int len;
+
+ va_start(arg, format);
+ len = vspprintf(message, max_len, format, arg);
+ va_end(arg);
+ return len;
+}
+
+#ifndef PHALCON_RELEASE
+
+FILE *phalcon_log = NULL;
+int phalcon_debug_trace = 0;
+phalcon_debug_entry *start = NULL;
+phalcon_debug_entry *active = NULL;
+
+/**
+ * Stars debug on file pipe
+ */
+int phalcon_start_debug(){
+ if(!phalcon_log){
+ /*//phalcon_log = fopen("/home/gutierrezandresfelipe/phalcon-debug.a", "w");
+ phalcon_log = fopen("/tmp/phalcon-debug.a", "w");
+ if(!phalcon_log){
+ fprintf(stderr, "Can't open debug log\n");
+ }*/
+ phalcon_log = stderr;
+ }
+ return SUCCESS;
+}
+
+/**
+ * Stops debug process
+ */
+int phalcon_stop_debug(){
+ phalcon_debug_entry *ptr = active;
+ phalcon_debug_entry *this_entry = NULL;
+ while(ptr){
+ this_entry = ptr;
+ ptr = ptr->prev;
+ efree(this_entry);
+ }
+ //fclose(phalcon_log);
+ phalcon_log = NULL;
+ return SUCCESS;
+}
+
+/**
+ * Executes a print_r on an interal zval
+ */
+int phalcon_print_r(zval *userval TSRMLS_DC){
+ zend_print_zval_r(userval, 0 TSRMLS_CC);
+ return SUCCESS;
+}
+
+/**
+ * Internal fast zval dump
+ */
+int phalcon_vdump(zval *uservar TSRMLS_DC){
+ phalcon_start_debug();
+ if(!uservar){
+ fprintf(phalcon_log, "Null pointer\n");
+ return SUCCESS;
+ }
+ switch(Z_TYPE_P(uservar)){
+ case IS_NULL:
+ fprintf(phalcon_log, "NULL \n");
+ break;
+ case IS_BOOL:
+ fprintf(phalcon_log, "Boolean: %s\n", Z_LVAL_P(uservar) ? "TRUE" : "FALSE");
+ break;
+ case IS_LONG:
+ fprintf(phalcon_log, "Long: %ld at %p, refcount=%d\n", Z_LVAL_P(uservar), uservar, Z_REFCOUNT_P(uservar));
+ break;
+ case IS_DOUBLE:
+ fprintf(phalcon_log, "Double: %f\n", Z_DVAL_P(uservar));
+ break;
+ case IS_STRING:
+ fprintf(phalcon_log, "String: %s(%d) at %p, refcount=%d\n", Z_STRVAL_P(uservar), Z_STRLEN_P(uservar), uservar, Z_REFCOUNT_P(uservar));
+ break;
+ case IS_RESOURCE:
+ fprintf(phalcon_log, "Resource\n");
+ break;
+ case IS_ARRAY:
+ fprintf(phalcon_log, "Array at %p, refcount=%d\n", uservar, Z_REFCOUNT_P(uservar));
+ break;
+ case IS_OBJECT:
+ fprintf(phalcon_log, "Object <%s> at %p\n", Z_OBJCE_P(uservar)->name, uservar);
+ break;
+ default:
+ fprintf(phalcon_log, "Unknown\n");
+ }
+ return SUCCESS;
+}
+
+int phalcon_dump_ce(zend_class_entry *ce TSRMLS_DC){
+ char *message = emalloc(sizeof(char *)*120);
+ if(ce){
+ sprintf(message, "- ClassType => %d", ce->type);
+ phalcon_step_over(message);
+ if(ce->name){
+ sprintf(message, "- ClassName => %s", ce->name);
+ phalcon_step_over(message);
+ } else {
+ phalcon_step_over("- ClassName => NULL");
+ }
+ } else {
+ phalcon_step_over("- NULL class entry :(");
+ }
+ return SUCCESS;
+}
+
+int phalcon_class_debug(zval *val TSRMLS_DC){
+ char *message = emalloc(sizeof(char *)*120);
+ zend_class_entry *ce;
+ if(val){
+ ce = Z_OBJCE_P(val);
+ if(ce){
+ sprintf(message, "- MemoryAddress => %p", val);
+ phalcon_step_over(message);
+ phalcon_dump_ce(ce TSRMLS_CC);
+ } else {
+ phalcon_step_over("- No class entry :(");
+ }
+ } else {
+ phalcon_step_over("- this_ptr is null :(");
+ }
+ return SUCCESS;
+}
+
+/**
+ * Append debug information to file
+ */
+int phalcon_debug_str(char *what, char *message){
+ fprintf(phalcon_log, "%s", what);
+ fprintf(phalcon_log, "%s", message);
+ fprintf(phalcon_log, "\n");
+ return SUCCESS;
+}
+
+int phalcon_debug_long(char *what, uint vlong){
+ fprintf(phalcon_log, "%s", what);
+ fprintf(phalcon_log, "%u", vlong);
+ fprintf(phalcon_log, "\n");
+ return SUCCESS;
+}
+
+int phalcon_debug_screen(char *message){
+ phalcon_debug_space();
+ fprintf(phalcon_log, "%s\n", message);
+ return SUCCESS;
+}
+
+int phalcon_debug_method_call(zval *obj, char *method_name TSRMLS_DC){
+ if(Z_TYPE_P(obj)==IS_OBJECT){
+ phalcon_debug_space();
+ } else {
+ phalcon_error_space();
+ }
+ if(Z_TYPE_P(obj)==IS_OBJECT){
+ fprintf(phalcon_log, "Calling method %s::%s on Object at %p\n", Z_OBJCE_P(obj)->name, method_name, obj);
+ } else {
+ fprintf(phalcon_log, "Calling method %s on non object :(\n", method_name);
+ }
+ return SUCCESS;
+}
+
+int phalcon_error_space(){
+ int i;
+ fprintf(phalcon_log, "[ERROR] ");
+ for(i=0;i<phalcon_debug_trace;i++){
+ fprintf(phalcon_log, " ");
+ }
+ return SUCCESS;
+}
+
+int phalcon_debug_space(){
+ int i;
+ fprintf(phalcon_log, "[DEBUG] ");
+ for(i=0;i<phalcon_debug_trace;i++){
+ fprintf(phalcon_log, " ");
+ }
+ return SUCCESS;
+}
+
+int phalcon_debug_param(zval *param TSRMLS_DC){
+ phalcon_debug_space();
+ fprintf(phalcon_log, "Push method Param > ");
+ phalcon_vdump(param TSRMLS_CC);
+ return SUCCESS;
+}
+
+int phalcon_debug_vdump(char *preffix, zval *value TSRMLS_DC){
+ phalcon_debug_space();
+ fprintf(phalcon_log, "%s", preffix);
+ phalcon_vdump(value TSRMLS_CC);
+ return SUCCESS;
+}
+
+int phalcon_debug_assign(char *name, zval *value TSRMLS_DC){
+ phalcon_debug_space();
+ fprintf(phalcon_log, "Assign on %s with ", name);
+ phalcon_vdump(value TSRMLS_CC);
+ return SUCCESS;
+}
+
+int phalcon_step_over(char *message){
+ phalcon_debug_screen(message);
+ return SUCCESS;
+}
+
+int phalcon_step_into(char *message){
+ phalcon_debug_trace++;
+ phalcon_debug_screen(message);
+ return SUCCESS;
+}
+
+int phalcon_step_out(char *message){
+ phalcon_debug_screen(message);
+ phalcon_debug_trace--;
+ return SUCCESS;
+}
+
+/**
+ * Prints internal debug backtrace
+ */
+int phalcon_debug_backtrace_internal(){
+ int step = 0;
+ char *message;
+ phalcon_debug_entry *ptr = active;
+ while(ptr){
+ phalcon_spprintf(&message, 0, "#%d %s::%s", step, ptr->class_name, ptr->method_name);
+ phalcon_debug_screen(message);
+ efree(message);
+ ptr = ptr->prev;
+ step++;
+ }
+ return SUCCESS;
+}
+
+/**
+ * Appends a debug entry to internal execution scope
+ */
+int phalcon_step_into_entry(char *class_name, char *method_name, int lineno){
+
+ char *message;
+ phalcon_debug_entry *entry;
+
+ if (!start) {
+ start = (phalcon_debug_entry *) emalloc(sizeof(phalcon_debug_entry));
+ start->class_name = "__main__";
+ start->method_name = "__init__";
+ start->lineno = 0;
+ start->prev = NULL;
+ start->next = NULL;
+ active = start;
+ }
+
+ phalcon_spprintf(&message, 0, "Step Into %s::%s", class_name, method_name);
+ phalcon_debug_screen(message);
+ efree(message);
+
+ entry = emalloc(sizeof(phalcon_debug_entry));
+ entry->class_name = class_name;
+ entry->method_name = method_name;
+ entry->lineno = lineno;
+ entry->prev = active;
+ active->next = entry;
+ active = entry;
+ phalcon_debug_trace++;
+
+ return SUCCESS;
+}
+
+/**
+ * Steps out current stack
+ */
+int phalcon_step_out_entry(){
+
+ char *message;
+ phalcon_debug_entry *prev;
+ if(active){
+
+ phalcon_debug_trace--;
+
+ phalcon_spprintf(&message, 0, "Step out %s::%s", active->class_name, active->method_name);
+ phalcon_debug_screen(message);
+ efree(message);
+
+ prev = active->prev;
+ efree(active);
+ active = prev;
+
+ } else {
+ fprintf(phalcon_log, "Problem, stack?");
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+
+#endif
View
69 ext/kernel/debug.h
@@ -0,0 +1,69 @@
+
+/*
+ +------------------------------------------------------------------------+
+ | Phalcon Framework |
+ +------------------------------------------------------------------------+
+ | Copyright (c) 2011-2012 Phalcon Team (http://www.phalconphp.com) |
+ +------------------------------------------------------------------------+
+ | This source file is subject to the New BSD License that is bundled |
+ | with this package in the file docs/LICENSE.txt. |
+ | |
+ | If you did not receive a copy of the license and are unable to |
+ | obtain it through the world-wide-web, please send an email |
+ | to license@phalconphp.com so we can send you a copy immediately. |
+ +------------------------------------------------------------------------+
+ | Authors: Andres Gutierrez <andres@phalconphp.com> |
+ | Eduar Carvajal <eduar@phalconphp.com> |
+ +------------------------------------------------------------------------+
+*/
+
+extern int phalcon_spprintf(char **message, int max_len, char *format, ...);
+
+#ifndef PHALCON_RELEASE
+
+#define PHV(v) phalcon_vdump(v)
+#define PHPR(v) phalcon_print_r(v)
+
+typedef struct _phalcon_debug_entry {
+ char *class_name;
+ char *method_name;
+ int lineno;
+ struct _phalcon_debug_entry *prev;
+ struct _phalcon_debug_entry *next;
+} phalcon_debug_entry;
+
+extern int phalcon_start_debug();
+extern int phalcon_stop_debug();
+
+extern int phalcon_print_r(zval *userval TSRMLS_DC);
+extern int phalcon_vdump(zval *uservar TSRMLS_DC);
+extern int phalcon_debug_assign(char *name, zval *value TSRMLS_DC);
+extern int phalcon_vpdump(const zval **uservar TSRMLS_DC);
+extern int phalcon_dump_ce(zend_class_entry *ce TSRMLS_DC);
+extern int phalcon_class_debug(zval *val TSRMLS_DC);
+
+extern int phalcon_debug_backtrace_internal();
+extern int phalcon_debug_str(char *what, char *message);
+extern int phalcon_debug_long(char *what, uint vlong);
+extern int phalcon_debug_screen(char *message);
+
+extern int phalcon_step_over(char *message);
+extern int phalcon_step_into(char *message);
+extern int phalcon_step_out(char *message);
+
+extern int phalcon_step_into_entry(char *class_name, char *method_name, int lineno);
+extern int phalcon_step_out_entry();
+
+extern int phalcon_debug_method_call(zval *obj, char *method_name TSRMLS_DC);
+extern int phalcon_debug_vdump(char *preffix, zval *value TSRMLS_DC);
+extern int phalcon_debug_param(zval *param TSRMLS_DC);
+
+extern int phalcon_error_space();
+extern int phalcon_debug_space();
+
+extern FILE *phalcon_log;
+extern int phalcon_debug_trace;
+extern phalcon_debug_entry *start;
+extern phalcon_debug_entry *active;
+
+#endif
View
96 ext/kernel/exception.c
@@ -0,0 +1,96 @@
+
+/*
+ +------------------------------------------------------------------------+
+ | Phalcon Framework |
+ +------------------------------------------------------------------------+
+ | Copyright (c) 2011-2012 Phalcon Team (http://www.phalconphp.com) |
+ +------------------------------------------------------------------------+
+ | This source file is subject to the New BSD License that is bundled |
+ | with this package in the file docs/LICENSE.txt. |
+ | |
+ | If you did not receive a copy of the license and are unable to |
+ | obtain it through the world-wide-web, please send an email |
+ | to license@phalconphp.com so we can send you a copy immediately. |
+ +------------------------------------------------------------------------+
+ | Authors: Andres Gutierrez <andres@phalconphp.com> |
+ | Eduar Carvajal <eduar@phalconphp.com> |
+ +------------------------------------------------------------------------+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_phalcon.h"
+#include "php_main.h"
+#include "ext/standard/php_string.h"
+
+#include "kernel/main.h"
+#include "kernel/memory.h"
+#include "kernel/fcall.h"
+
+#include "Zend/zend_exceptions.h"
+
+/**
+ * Throws an zval object as exception
+ */
+void phalcon_throw_exception(zval *object TSRMLS_DC){
+ Z_ADDREF_P(object);
+ zend_throw_exception_object(object TSRMLS_CC);
+ phalcon_memory_restore_stack(TSRMLS_C);
+}
+
+/**
+ * Throws a exception with a single string parameter
+ */
+void phalcon_throw_exception_string(zend_class_entry *ce, char *message, zend_uint message_len TSRMLS_DC){
+ zval *object, *msg;
+
+ ALLOC_INIT_ZVAL(object);
+ object_init_ex(object, ce);
+
+ PHALCON_ALLOC_ZVAL_MM(msg);
+ ZVAL_STRINGL(msg, message, message_len, 1);
+
+ PHALCON_CALL_METHOD_PARAMS_1_NORETURN(object, "__construct", msg, PH_CHECK);
+
+ zend_throw_exception_object(object TSRMLS_CC);
+
+ phalcon_memory_restore_stack(TSRMLS_C);
+}
+
+/**
+ * Latest version of zend_throw_exception_internal
+ */
+void phalcon_throw_exception_internal(zval *exception TSRMLS_DC) {
+
+ if (exception != NULL) {
+ zval *previous = EG(exception);
+ zend_exception_set_previous(exception, EG(exception) TSRMLS_CC);
+ EG(exception) = exception;
+ if (previous) {
+ return;
+ }
+ }
+ if (!EG(current_execute_data)) {
+ if(EG(exception)) {
+ zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
+ }
+ zend_error(E_ERROR, "Exception thrown without a stack frame");
+ }
+
+ if (zend_throw_exception_hook) {
+ zend_throw_exception_hook(exception TSRMLS_CC);
+ }
+
+ if (EG(current_execute_data)->opline == NULL ||
+ (EG(current_execute_data)->opline+1)->opcode == ZEND_HANDLE_EXCEPTION) {
+ /* no need to rethrow the exception */
+ return;
+ }
+ EG(opline_before_exception) = EG(current_execute_data)->opline;
+ EG(current_execute_data)->opline = EG(exception_op);
+
+}
+
View
25 ext/kernel/exception.h
@@ -0,0 +1,25 @@
+
+/*
+ +------------------------------------------------------------------------+
+ | Phalcon Framework |
+ +------------------------------------------------------------------------+
+ | Copyright (c) 2011-2012 Phalcon Team (http://www.phalconphp.com) |
+ +------------------------------------------------------------------------+
+ | This source file is subject to the New BSD License that is bundled |
+ | with this package in the file docs/LICENSE.txt. |
+ | |
+ | If you did not receive a copy of the license and are unable to |
+ | obtain it through the world-wide-web, please send an email |
+ | to license@phalconphp.com so we can send you a copy immediately. |
+ +------------------------------------------------------------------------+
+ | Authors: Andres Gutierrez <andres@phalconphp.com> |
+ | Eduar Carvajal <eduar@phalconphp.com> |
+ +------------------------------------------------------------------------+
+*/
+
+/** Exceptions */
+#define PHALCON_THROW_EXCEPTION_STR(class_entry, message) phalcon_throw_exception_string(class_entry, message, strlen(message) TSRMLS_CC);
+
+extern void phalcon_throw_exception(zval *object TSRMLS_DC);
+extern void phalcon_throw_exception_string(zend_class_entry *ce, char *message, zend_uint message_len TSRMLS_DC);
+extern void phalcon_throw_exception_internal(zval *exception TSRMLS_DC);
View
1,175 ext/kernel/fcall.c
@@ -0,0 +1,1175 @@
+
+/*
+ +------------------------------------------------------------------------+
+ | Phalcon Framework |
+ +------------------------------------------------------------------------+
+ | Copyright (c) 2011-2012 Phalcon Team (http://www.phalconphp.com) |
+ +------------------------------------------------------------------------+
+ | This source file is subject to the New BSD License that is bundled |
+ | with this package in the file docs/LICENSE.txt. |
+ | |
+ | If you did not receive a copy of the license and are unable to |
+ | obtain it through the world-wide-web, please send an email |
+ | to license@phalconphp.com so we can send you a copy immediately. |
+ +------------------------------------------------------------------------+
+ | Authors: Andres Gutierrez <andres@phalconphp.com> |
+ | Eduar Carvajal <eduar@phalconphp.com> |
+ +------------------------------------------------------------------------+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_phalcon.h"
+
+#include "kernel/main.h"
+#include "kernel/fcall.h"
+#include "kernel/memory.h"
+#include "kernel/exception.h"
+
+#include "Zend/zend_API.h"
+#include "Zend/zend_exceptions.h"
+#include "Zend/zend_execute.h"
+
+/**
+ * Finds the correct scope to execute the function
+ */
+int phalcon_find_scope(zend_class_entry *ce, char *method_name, int method_len TSRMLS_DC){
+ char *lcname = zend_str_tolower_dup(method_name, method_len);
+ while (ce) {
+ if (zend_hash_exists(&ce->function_table, lcname, method_len+1)) {
+ EG(scope) = ce;
+ efree(lcname);
+ return SUCCESS;
+ }
+ ce = ce->parent;
+ }
+ if (lcname) {
+ efree(lcname);
+ }
+ return FAILURE;
+}
+
+/**
+ * Find out the function scope on parent classes
+ */
+int phalcon_find_parent_scope(zend_class_entry *ce, char *active_class, int active_class_len, char *method_name, int method_len TSRMLS_DC){
+ char *lcname = zend_str_tolower_dup(method_name, method_len);
+ while (ce) {
+ if (ce->name_length == active_class_len) {
+ if (!zend_binary_strcasecmp(ce->name, ce->name_length, active_class, active_class_len)) {
+ if (zend_hash_exists(&ce->function_table, lcname, method_len+1)) {
+ EG(scope) = ce;
+ efree(lcname);
+ return SUCCESS;
+ }
+ }
+ }
+ ce = ce->parent;
+ }
+ if (lcname) {
+ efree(lcname);
+ }
+ return FAILURE;
+}
+
+/**
+ * This is a function to call PHP functions in a old-style secure way
+ */
+static inline int phalcon_call_func_normal(zval *return_value, char *func_name, int func_length, int noreturn TSRMLS_DC){
+
+ zval *fn = NULL;
+ int status = FAILURE;
+ zval *local_retval_ptr = NULL;
+
+ if (!noreturn) {
+ ALLOC_INIT_ZVAL(return_value);
+ }
+
+ PHALCON_ALLOC_ZVAL(fn);
+ ZVAL_STRINGL(fn, func_name, func_length, 1);
+
+ status = PHALCON_CALL_USER_FUNCTION(CG(function_table), NULL, fn, return_value, 0, NULL TSRMLS_CC);
+ if (status == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Call to undefined function %s()", func_name);
+ }
+
+ zval_ptr_dtor(&fn);
+
+ if (local_retval_ptr) {
+ COPY_PZVAL_TO_ZVAL(*return_value, local_retval_ptr);
+ }
+
+ if (!noreturn) {
+ zval_ptr_dtor(&return_value);
+ }
+
+ if (EG(exception)){
+ status = FAILURE;
+ }
+
+ if (status == FAILURE) {
+ phalcon_memory_restore_stack(TSRMLS_C);
+ }
+
+ return status;
+}
+
+/**
+ * Call single function which not requires parameters
+ */
+int phalcon_call_func(zval *return_value, char *func_name, int func_length, int noreturn TSRMLS_DC){
+ return phalcon_call_func_normal(return_value, func_name, func_length, noreturn TSRMLS_CC);
+}
+
+/**
+ * This is an experimental function to call PHP functions that requires parameters in a faster way
+ */
+static inline int phalcon_call_func_params_normal(zval *return_value, char *func_name, int func_length, zend_uint param_count, zval *params[], int noreturn TSRMLS_DC){
+
+ zval *fn = NULL;
+ int status = FAILURE;
+ zval *local_retval_ptr = NULL;
+
+ if (!noreturn) {
+ ALLOC_INIT_ZVAL(return_value);
+ }
+
+ PHALCON_ALLOC_ZVAL(fn);
+ ZVAL_STRINGL(fn, func_name, func_length, 1);
+
+ status = PHALCON_CALL_USER_FUNCTION(CG(function_table), NULL, fn, return_value, param_count, params TSRMLS_CC);
+ if (status == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Call to undefined function %s()", func_name);
+ }
+
+ zval_ptr_dtor(&fn);
+
+ if (local_retval_ptr) {
+ COPY_PZVAL_TO_ZVAL(*return_value, local_retval_ptr);
+ }
+
+ if (!noreturn) {
+ zval_ptr_dtor(&return_value);
+ }
+
+ if (EG(exception)){
+ status = FAILURE;
+ }
+
+ if (status == FAILURE) {
+ phalcon_memory_restore_stack(TSRMLS_C);
+ }
+
+ return status;
+}
+
+/**
+ * Call single function which requires arbitrary number of parameters
+ */
+int phalcon_call_func_params(zval *return_value, char *func_name, int func_length, zend_uint param_count, zval *params[], int noreturn TSRMLS_DC){
+ return phalcon_call_func_params_normal(return_value, func_name, func_length, param_count, params, noreturn TSRMLS_CC);
+}
+
+/**
+ * Call single function which requires only 1 parameter
+ */
+int phalcon_call_func_one_param(zval *return_value, char *func_name, int func_length, zval *param1, int noreturn TSRMLS_DC){
+ zval *params[] = { param1 };
+ return phalcon_call_func_params(return_value, func_name, func_length, 1, params, noreturn TSRMLS_CC);
+}
+
+/**
+ * Call single function which requires only 2 parameters
+ */
+int phalcon_call_func_two_params(zval *return_value, char *func_name, int func_length, zval *param1, zval *param2, int noreturn TSRMLS_DC){
+ zval *params[] = { param1, param2 };
+ return phalcon_call_func_params(return_value, func_name, func_length, 2, params, noreturn TSRMLS_CC);
+}
+
+/**
+ * Call single function which requires only 3 parameters
+ */
+int phalcon_call_func_three_params(zval *return_value, char *func_name, int func_length, zval *param1, zval *param2, zval *param3, int noreturn TSRMLS_DC){
+ zval *params[] = { param1, param2, param3 };
+ return phalcon_call_func_params(return_value, func_name, func_length, 3, params, noreturn TSRMLS_CC);
+}
+
+/**
+ * This function implements a secure old-style way to call functions
+ */
+static inline int phalcon_call_method_normal(zval *return_value, zval *object, char *method_name, int method_len, int check, int noreturn TSRMLS_DC){
+
+ zval *fn = NULL;
+ int status = FAILURE;
+ zend_class_entry *active_scope = NULL;
+
+ if (check) {
+ if (!zend_hash_exists(&Z_OBJCE_P(object)->function_table, method_name, strlen(method_name)+1)) {
+ return SUCCESS;
+ }
+ }
+
+ if(!noreturn){
+ ALLOC_INIT_ZVAL(return_value);
+ }
+
+ PHALCON_ALLOC_ZVAL(fn);
+ ZVAL_STRINGL(fn, method_name, method_len, 1);
+
+ if (Z_TYPE_P(object) == IS_OBJECT) {
+ active_scope = EG(scope);
+ phalcon_find_scope(Z_OBJCE_P(object), method_name, method_len TSRMLS_CC);
+ status = PHALCON_CALL_USER_FUNCTION(&Z_OBJCE_P(object)->function_table, &object, fn, return_value, 0, NULL TSRMLS_CC);
+ if (status == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Call to undefined method %s()", Z_STRVAL_P(fn));
+ }
+ EG(scope) = active_scope;
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Call to method %s() on a non object", Z_STRVAL_P(fn));
+ status = FAILURE;
+ }
+
+ zval_ptr_dtor(&fn);
+
+ if (!noreturn) {
+ zval_ptr_dtor(&return_value);
+ }
+
+ if (EG(exception)){
+ status = FAILURE;
+ }
+
+ if (status == FAILURE) {
+ phalcon_memory_restore_stack(TSRMLS_C);
+ }
+
+ return status;
+}
+
+/**
+ * Call method on an object that not requires parameters
+ *
+ */
+int phalcon_call_method(zval *return_value, zval *object, char *method_name, int method_len, int check, int noreturn TSRMLS_DC){
+ return phalcon_call_method_normal(return_value, object, method_name, method_len, check, noreturn TSRMLS_CC);
+}
+
+/**
+ * Call methods that require parameters in a old-style secure way
+ */
+static inline int phalcon_call_method_params_normal(zval *return_value, zval *object, char *method_name, int method_len, zend_uint param_count, zval *params[], int check, int noreturn TSRMLS_DC){
+
+ zval *fn = NULL;
+ int status = FAILURE;
+ zend_class_entry *ce, *active_scope = NULL;
+
+ if (check) {
+ if (!zend_hash_exists(&Z_OBJCE_P(object)->function_table, method_name, method_len+1)) {
+ return SUCCESS;
+ }
+ }
+
+ if (!noreturn) {