LTP GCOV extension - code coverage report
Current view: directory - Zend - zend_operators.c
Test: PHP Code Coverage
Date: 2007-04-10 Instrumented lines: 967
Code covered: 41.2 % Executed lines: 398
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | Zend Engine                                                          |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1998-2007 Zend Technologies Ltd. (http://www.zend.com) |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 2.00 of the Zend license,     |
       8                 :    | that is bundled with this package in the file LICENSE, and is        | 
       9                 :    | available through the world-wide-web at the following url:           |
      10                 :    | http://www.zend.com/license/2_00.txt.                                |
      11                 :    | If you did not receive a copy of the Zend license and are unable to  |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@zend.com so we can mail you a copy immediately.              |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Authors: Andi Gutmans <andi@zend.com>                                |
      16                 :    |          Zeev Suraski <zeev@zend.com>                                |
      17                 :    +----------------------------------------------------------------------+
      18                 : */
      19                 : 
      20                 : /* $Id: zend_operators.c,v 1.208.2.4.2.20 2007/02/24 02:17:23 helly Exp $ */
      21                 : 
      22                 : #include <ctype.h>
      23                 : 
      24                 : #include "zend.h"
      25                 : #include "zend_operators.h"
      26                 : #include "zend_variables.h"
      27                 : #include "zend_globals.h"
      28                 : #include "zend_list.h"
      29                 : #include "zend_API.h"
      30                 : #include "zend_multiply.h"
      31                 : #include "zend_strtod.h"
      32                 : #include "zend_exceptions.h"
      33                 : 
      34                 : #define LONG_SIGN_MASK (1L << (8*sizeof(long)-1))
      35                 : 
      36                 : #if ZEND_USE_TOLOWER_L
      37                 : #include <locale.h>
      38                 : static _locale_t current_locale = NULL;
      39                 : /* this is true global! may lead to strange effects on ZTS, but so is setlocale() */
      40                 : #define zend_tolower(c) _tolower_l(c, current_locale)
      41                 : #else
      42                 : #define zend_tolower(c) tolower(c)
      43                 : #endif
      44                 : 
      45                 : ZEND_API int zend_atoi(const char *str, int str_len)
      46            6708 : {
      47                 :         int retval;
      48                 : 
      49            6708 :         if (!str_len) {
      50             326 :                 str_len = strlen(str);
      51                 :         }
      52            6708 :         retval = strtol(str, NULL, 0);
      53            6708 :         if (str_len>0) {
      54            6490 :                 switch (str[str_len-1]) {
      55                 :                         case 'g':
      56                 :                         case 'G':
      57               0 :                                 retval *= 1024;
      58                 :                                 /* break intentionally missing */
      59                 :                         case 'm':
      60                 :                         case 'M':
      61             659 :                                 retval *= 1024;
      62                 :                                 /* break intentionally missing */
      63                 :                         case 'k':
      64                 :                         case 'K':
      65             879 :                                 retval *= 1024;
      66                 :                                 break;
      67                 :                 }
      68                 :         }
      69            6708 :         return retval;
      70                 : }
      71                 : 
      72                 : 
      73                 : ZEND_API double zend_string_to_double(const char *number, zend_uint length)
      74               0 : {
      75               0 :         double divisor = 10.0;
      76               0 :         double result = 0.0;
      77                 :         double exponent;
      78               0 :         const char *end = number+length;
      79               0 :         const char *digit = number;
      80                 : 
      81               0 :         if (!length) {
      82               0 :                 return result;
      83                 :         }
      84                 : 
      85               0 :         while (digit < end) {
      86               0 :                 if ((*digit <= '9' && *digit >= '0')) {
      87               0 :                         result *= 10;
      88               0 :                         result += *digit - '0';
      89               0 :                 } else if (*digit == '.') {
      90               0 :                         digit++;
      91               0 :                         break;
      92               0 :                 } else if (toupper(*digit) == 'E') {
      93               0 :                         exponent = (double) atoi(digit+1);
      94               0 :                         result *= pow(10.0, exponent);
      95               0 :                         return result;
      96                 :                 } else {
      97               0 :                         return result;
      98                 :                 }
      99               0 :                 digit++;
     100                 :         }
     101                 : 
     102               0 :         while (digit < end) {
     103               0 :                 if ((*digit <= '9' && *digit >= '0')) {
     104               0 :                         result += (*digit - '0') / divisor;
     105               0 :                         divisor *= 10;
     106               0 :                 } else if (toupper(*digit) == 'E') {
     107               0 :                         exponent = (double) atoi(digit+1);
     108               0 :                         result *= pow(10.0, exponent);
     109               0 :                         return result;
     110                 :                 } else {
     111               0 :                         return result;
     112                 :                 }
     113               0 :                 digit++;
     114                 :         }
     115               0 :         return result;
     116                 : }
     117                 : 
     118                 : 
     119                 : ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC)
     120               0 : {
     121               0 :         switch (op->type) {
     122                 :                 case IS_STRING:
     123                 :                         {
     124                 :                                 char *strval;
     125                 : 
     126               0 :                                 strval = op->value.str.val;
     127               0 :                                 if ((op->type=is_numeric_string(strval, op->value.str.len, &op->value.lval, &op->value.dval, 1)) == 0) {
     128               0 :                                         op->value.lval = 0;
     129               0 :                                         op->type = IS_LONG;
     130                 :                                 }
     131               0 :                                 STR_FREE(strval);
     132               0 :                                 break;
     133                 :                         }
     134                 :                 case IS_BOOL:
     135               0 :                         op->type = IS_LONG;
     136               0 :                         break;
     137                 :                 case IS_RESOURCE:
     138               0 :                         zend_list_delete(op->value.lval);
     139               0 :                         op->type = IS_LONG;
     140               0 :                         break;
     141                 :                 case IS_OBJECT:
     142               0 :                         convert_to_long_base(op, 10);
     143               0 :                         break;
     144                 :                 case IS_NULL:
     145               0 :                         op->type = IS_LONG;
     146               0 :                         op->value.lval = 0;
     147                 :                         break;
     148                 :         }
     149               0 : }
     150                 : 
     151                 : #define zendi_convert_scalar_to_number(op, holder, result)                      \
     152                 :         if (op==result) {                                                                                               \
     153                 :                 if (op->type != IS_LONG) {                                                                   \
     154                 :                         convert_scalar_to_number(op TSRMLS_CC);                                 \
     155                 :                 }                                                                                                                       \
     156                 :         } else {                                                                                                                \
     157                 :                 switch ((op)->type) {                                                                                \
     158                 :                         case IS_STRING:                                                                                 \
     159                 :                                 {                                                                                                       \
     160                 :                                         if (((holder).type=is_numeric_string((op)->value.str.val, (op)->value.str.len, &(holder).value.lval, &(holder).value.dval, 1)) == 0) {    \
     161                 :                                                 (holder).value.lval = 0;                                                \
     162                 :                                                 (holder).type = IS_LONG;                                                \
     163                 :                                         }                                                                                                               \
     164                 :                                         (op) = &(holder);                                                                           \
     165                 :                                         break;                                                                                                  \
     166                 :                                 }                                                                                                                       \
     167                 :                         case IS_BOOL:                                                                                                   \
     168                 :                         case IS_RESOURCE:                                                                                               \
     169                 :                                 (holder).value.lval = (op)->value.lval;                                              \
     170                 :                                 (holder).type = IS_LONG;                                                                        \
     171                 :                                 (op) = &(holder);                                                                                   \
     172                 :                                 break;                                                                                                          \
     173                 :                         case IS_NULL:                                                                                                   \
     174                 :                                 (holder).value.lval = 0;                                                                        \
     175                 :                                 (holder).type = IS_LONG;                                                                        \
     176                 :                                 (op) = &(holder);                                                                                   \
     177                 :                                 break;                                                                                                          \
     178                 :                         case IS_OBJECT:                                                                                                 \
     179                 :                                 (holder) = (*(op));                                                                                     \
     180                 :                                 zval_copy_ctor(&(holder));                                                                  \
     181                 :                                 convert_to_long_base(&(holder), 10);                                                \
     182                 :                                 if ((holder).type == IS_LONG) {                                                         \
     183                 :                                         (op) = &(holder);                                                                           \
     184                 :                                 }                                                                                                                       \
     185                 :                                 break;                                                                                                          \
     186                 :                 }                                                                                                                                       \
     187                 :         }
     188                 : 
     189                 : #define DVAL_TO_LVAL(d, l) \
     190                 :         if ((d) > LONG_MAX) { \
     191                 :                 (l) = (unsigned long) (d); \
     192                 :         } else { \
     193                 :                 (l) = (long) (d); \
     194                 :         }
     195                 : 
     196                 : 
     197                 : #define zendi_convert_to_long(op, holder, result)                                       \
     198                 :         if (op == result) {                                                                                             \
     199                 :                 convert_to_long(op);                                                                            \
     200                 :         } else if ((op)->type != IS_LONG) {                                                          \
     201                 :                 switch ((op)->type) {                                                                                \
     202                 :                         case IS_NULL:                                                                                   \
     203                 :                                 (holder).value.lval = 0;                                                        \
     204                 :                                 break;                                                                                          \
     205                 :                         case IS_DOUBLE:                                                                                 \
     206                 :                                 DVAL_TO_LVAL((op)->value.dval, (holder).value.lval); \
     207                 :                                 break;                                                                                          \
     208                 :                         case IS_STRING:                                                                                 \
     209                 :                                 (holder).value.lval = strtol((op)->value.str.val, NULL, 10);                                 \
     210                 :                                 break;                                                                                          \
     211                 :                         case IS_ARRAY:                                                                                  \
     212                 :                                 (holder).value.lval = (zend_hash_num_elements((op)->value.ht)?1:0);                          \
     213                 :                                 break;                                                                                          \
     214                 :                         case IS_OBJECT:                                                                                 \
     215                 :                                 (holder) = (*(op));                                                                     \
     216                 :                                 zval_copy_ctor(&(holder));                                                  \
     217                 :                                 convert_to_long_base(&(holder), 10);                                \
     218                 :                                 break;                                                                                          \
     219                 :                         case IS_BOOL:                                                                                   \
     220                 :                         case IS_RESOURCE:                                                                               \
     221                 :                                 (holder).value.lval = (op)->value.lval;                              \
     222                 :                                 break;                                                                                          \
     223                 :                         default:                                                                                                \
     224                 :                                 zend_error(E_WARNING, "Cannot convert to ordinal value");                                             \
     225                 :                                 (holder).value.lval = 0;                                                        \
     226                 :                                 break;                                                                                          \
     227                 :                 }                                                                                                                       \
     228                 :                 (holder).type = IS_LONG;                                                                        \
     229                 :                 (op) = &(holder);                                                                                   \
     230                 :         }
     231                 : 
     232                 : 
     233                 : #define zendi_convert_to_boolean(op, holder, result)                            \
     234                 :         if (op==result) {                                                                                               \
     235                 :                 convert_to_boolean(op);                                                                         \
     236                 :         } else if ((op)->type != IS_BOOL) {                                                          \
     237                 :                 switch ((op)->type) {                                                                                \
     238                 :                         case IS_NULL:                                                                                   \
     239                 :                                 (holder).value.lval = 0;                                                        \
     240                 :                                 break;                                                                                          \
     241                 :                         case IS_RESOURCE:                                                                               \
     242                 :                         case IS_LONG:                                                                                   \
     243                 :                                 (holder).value.lval = ((op)->value.lval ? 1 : 0);    \
     244                 :                                 break;                                                                                          \
     245                 :                         case IS_DOUBLE:                                                                                 \
     246                 :                                 (holder).value.lval = ((op)->value.dval ? 1 : 0);    \
     247                 :                                 break;                                                                                          \
     248                 :                         case IS_STRING:                                                                                 \
     249                 :                                 if ((op)->value.str.len == 0                                         \
     250                 :                                         || ((op)->value.str.len==1 && (op)->value.str.val[0]=='0')) {     \
     251                 :                                         (holder).value.lval = 0;                                                \
     252                 :                                 } else {                                                                                        \
     253                 :                                         (holder).value.lval = 1;                                                \
     254                 :                                 }                                                                                                       \
     255                 :                                 break;                                                                                          \
     256                 :                         case IS_ARRAY:                                                                                  \
     257                 :                                 (holder).value.lval = (zend_hash_num_elements((op)->value.ht)?1:0);  \
     258                 :                                 break;                                                                                          \
     259                 :                         case IS_OBJECT:                                                                                 \
     260                 :                                 (holder) = (*(op));                                                                     \
     261                 :                                 zval_copy_ctor(&(holder));                                                  \
     262                 :                                 convert_to_boolean(&(holder));                                              \
     263                 :                                 break;                                                                                          \
     264                 :                         default:                                                                                                \
     265                 :                                 (holder).value.lval = 0;                                                        \
     266                 :                                 break;                                                                                          \
     267                 :                 }                                                                                                                       \
     268                 :                 (holder).type = IS_BOOL;                                                                        \
     269                 :                 (op) = &(holder);                                                                                   \
     270                 :         }
     271                 : 
     272                 : 
     273                 : #define convert_object_to_type(op, ctype, conv_func)                                                                            \
     274                 :         if (Z_OBJ_HT_P(op)->cast_object) {                                                                                                           \
     275                 :                 zval dst;                                                                                                                                                       \
     276                 :                 if (Z_OBJ_HT_P(op)->cast_object(op, &dst, ctype TSRMLS_CC) == FAILURE) {                 \
     277                 :                         zend_error(E_RECOVERABLE_ERROR,                                                                                                 \
     278                 :                         "Object of class %s could not be converted to %s", Z_OBJCE_P(op)->name,                    \
     279                 :                         zend_get_type_by_const(ctype));                                                                                                 \
     280                 :                 } else {                                                                                                                                                        \
     281                 :                         zval_dtor(op);                                                                                                                                  \
     282                 :                         Z_TYPE_P(op) = ctype;                                                                                                                   \
     283                 :                         op->value = dst.value;                                                                                                                       \
     284                 :                 }                                                                                                                                                                       \
     285                 :         } else {                                                                                                                                                                \
     286                 :                 if(Z_OBJ_HT_P(op)->get) {                                                                                                                    \
     287                 :                         zval *newop = Z_OBJ_HT_P(op)->get(op TSRMLS_CC);                                                             \
     288                 :                         if(Z_TYPE_P(newop) != IS_OBJECT) {                                                                                              \
     289                 :                                 /* for safety - avoid loop */                                                                                           \
     290                 :                                 zval_dtor(op);                                                                                                                          \
     291                 :                                 *op = *newop;                                                                                                                           \
     292                 :                                 FREE_ZVAL(newop);                                                                                                                       \
     293                 :                                 conv_func(op);                                                                                                                          \
     294                 :                         }                                                                                                                                                               \
     295                 :                 }                                                                                                                                                                       \
     296                 :         }
     297                 : 
     298                 : ZEND_API void convert_to_long(zval *op)
     299            1066 : {
     300            1066 :         if ((op)->type != IS_LONG) {
     301              10 :                 convert_to_long_base(op, 10);
     302                 :         }
     303            1066 : }
     304                 : 
     305                 : ZEND_API void convert_to_long_base(zval *op, int base)
     306              10 : {
     307                 :         char *strval;
     308                 :         long tmp;
     309                 : 
     310              10 :         switch (op->type) {
     311                 :                 case IS_NULL:
     312               0 :                         op->value.lval = 0;
     313               0 :                         break;
     314                 :                 case IS_RESOURCE: {
     315                 :                                 TSRMLS_FETCH();
     316                 : 
     317               0 :                                 zend_list_delete(op->value.lval);
     318                 :                         }
     319                 :                         /* break missing intentionally */
     320                 :                 case IS_BOOL:
     321                 :                 case IS_LONG:
     322               0 :                         break;
     323                 :                 case IS_DOUBLE:
     324               0 :                         DVAL_TO_LVAL(op->value.dval, op->value.lval);
     325               0 :                         break;
     326                 :                 case IS_STRING:
     327              10 :                         strval = op->value.str.val;
     328              10 :                         op->value.lval = strtol(strval, NULL, base);
     329              10 :                         STR_FREE(strval);
     330              10 :                         break;
     331                 :                 case IS_ARRAY:
     332               0 :                         tmp = (zend_hash_num_elements(op->value.ht)?1:0);
     333               0 :                         zval_dtor(op);
     334               0 :                         op->value.lval = tmp;
     335               0 :                         break;
     336                 :                 case IS_OBJECT:
     337                 :                         {
     338               0 :                                 int retval = 1;
     339                 :                                 TSRMLS_FETCH();
     340                 : 
     341               0 :                                 convert_object_to_type(op, IS_LONG, convert_to_long);
     342                 : 
     343               0 :                                 if (op->type == IS_LONG) {
     344               0 :                                         return;
     345                 :                                 }
     346                 : 
     347               0 :                                 if (EG(ze1_compatibility_mode)) {
     348               0 :                                         HashTable *ht = Z_OBJPROP_P(op);
     349               0 :                                         if (ht) {
     350               0 :                                                 retval = (zend_hash_num_elements(ht)?1:0);
     351                 :                                         }
     352                 :                                 } else {
     353               0 :                                         zend_error(E_NOTICE, "Object of class %s could not be converted to int", Z_OBJCE_P(op)->name);
     354                 :                                 }
     355               0 :                                 zval_dtor(op);
     356               0 :                                 ZVAL_LONG(op, retval);
     357               0 :                                 return;
     358                 :                         }
     359                 :                 default:
     360               0 :                         zend_error(E_WARNING, "Cannot convert to ordinal value");
     361               0 :                         zval_dtor(op);
     362               0 :                         op->value.lval = 0;
     363                 :                         break;
     364                 :         }
     365                 : 
     366              10 :         op->type = IS_LONG;
     367                 : }
     368                 : 
     369                 : 
     370                 : ZEND_API void convert_to_double(zval *op)
     371             130 : {
     372                 :         char *strval;
     373                 :         double tmp;
     374                 : 
     375             130 :         switch (op->type) {
     376                 :                 case IS_NULL:
     377               0 :                         op->value.dval = 0.0;
     378               0 :                         break;
     379                 :                 case IS_RESOURCE: {
     380                 :                                 TSRMLS_FETCH();
     381                 : 
     382               0 :                                 zend_list_delete(op->value.lval);
     383                 :                         }
     384                 :                         /* break missing intentionally */
     385                 :                 case IS_BOOL:
     386                 :                 case IS_LONG:
     387              26 :                         op->value.dval = (double) op->value.lval;
     388              26 :                         break;
     389                 :                 case IS_DOUBLE:
     390              48 :                         break;
     391                 :                 case IS_STRING:
     392              56 :                         strval = op->value.str.val;
     393                 : 
     394              56 :                         op->value.dval = zend_strtod(strval, NULL);
     395              56 :                         STR_FREE(strval);
     396              56 :                         break;
     397                 :                 case IS_ARRAY:
     398               0 :                         tmp = (zend_hash_num_elements(op->value.ht)?1:0);
     399               0 :                         zval_dtor(op);
     400               0 :                         op->value.dval = tmp;
     401               0 :                         break;
     402                 :                 case IS_OBJECT:
     403                 :                         {
     404               0 :                                 double retval = 1.0;
     405                 :                                 TSRMLS_FETCH();
     406                 :                                 
     407               0 :                                 convert_object_to_type(op, IS_DOUBLE, convert_to_double);
     408                 : 
     409               0 :                                 if (op->type == IS_DOUBLE) {
     410               0 :                                         return;
     411                 :                                 }
     412                 : 
     413               0 :                                 if (EG(ze1_compatibility_mode)) {
     414               0 :                                         HashTable *ht = Z_OBJPROP_P(op);
     415               0 :                                         if (ht) {
     416               0 :                                                 retval = (zend_hash_num_elements(ht)?1.0:0.0);
     417                 :                                         }
     418                 :                                 } else {
     419               0 :                                         zend_error(E_NOTICE, "Object of class %s could not be converted to double", Z_OBJCE_P(op)->name);
     420                 :                                 }
     421                 : 
     422               0 :                                 zval_dtor(op);
     423               0 :                                 ZVAL_DOUBLE(op, retval);
     424               0 :                                 break;
     425                 :                         }       
     426                 :                 default:
     427               0 :                         zend_error(E_WARNING, "Cannot convert to real value (type=%d)", op->type);
     428               0 :                         zval_dtor(op);
     429               0 :                         op->value.dval = 0;
     430                 :                         break;
     431                 :         }
     432             130 :         op->type = IS_DOUBLE;
     433                 : }
     434                 : 
     435                 : 
     436                 : ZEND_API void convert_to_null(zval *op)
     437               0 : {
     438               0 :         if (Z_TYPE_P(op) == IS_OBJECT) {
     439               0 :                 if (Z_OBJ_HT_P(op)->cast_object) {
     440                 :                         zval *org;
     441                 :                         TSRMLS_FETCH();
     442                 : 
     443               0 :                         ALLOC_ZVAL(org);
     444               0 :                         *org = *op;
     445               0 :                         if (Z_OBJ_HT_P(op)->cast_object(org, op, IS_NULL TSRMLS_CC) == SUCCESS) {
     446               0 :                                 zval_dtor(org);
     447               0 :                                 return;
     448                 :                         }
     449               0 :                         *op = *org;
     450               0 :                         FREE_ZVAL(org);
     451                 :                 }
     452                 :         }
     453                 : 
     454               0 :         zval_dtor(op);
     455               0 :         Z_TYPE_P(op) = IS_NULL;
     456                 : }
     457                 : 
     458                 : 
     459                 : ZEND_API void convert_to_boolean(zval *op)
     460            8285 : {
     461                 :         char *strval;
     462                 :         int tmp;
     463                 : 
     464            8285 :         switch (op->type) {
     465                 :                 case IS_BOOL:
     466             102 :                         break;
     467                 :                 case IS_NULL:
     468               0 :                         op->value.lval = 0;
     469               0 :                         break;
     470                 :                 case IS_RESOURCE: {
     471                 :                                 TSRMLS_FETCH();
     472                 : 
     473               0 :                                 zend_list_delete(op->value.lval);
     474                 :                         }
     475                 :                         /* break missing intentionally */
     476                 :                 case IS_LONG:
     477            8181 :                         op->value.lval = (op->value.lval ? 1 : 0);
     478            8181 :                         break;
     479                 :                 case IS_DOUBLE:
     480               0 :                         op->value.lval = (op->value.dval ? 1 : 0);
     481               0 :                         break;
     482                 :                 case IS_STRING:
     483               2 :                         strval = op->value.str.val;
     484                 : 
     485               2 :                         if (op->value.str.len == 0
     486                 :                                 || (op->value.str.len==1 && op->value.str.val[0]=='0')) {
     487               0 :                                 op->value.lval = 0;
     488                 :                         } else {
     489               2 :                                 op->value.lval = 1;
     490                 :                         }
     491               2 :                         STR_FREE(strval);
     492               2 :                         break;
     493                 :                 case IS_ARRAY:
     494               0 :                         tmp = (zend_hash_num_elements(op->value.ht)?1:0);
     495               0 :                         zval_dtor(op);
     496               0 :                         op->value.lval = tmp;
     497               0 :                         break;
     498                 :                 case IS_OBJECT:
     499                 :                         {
     500               0 :                                 zend_bool retval = 1;
     501                 :                                 TSRMLS_FETCH();
     502                 : 
     503               0 :                                 convert_object_to_type(op, IS_BOOL, convert_to_boolean);
     504                 : 
     505               0 :                                 if (op->type == IS_BOOL) {
     506               0 :                                         return;
     507                 :                                 }
     508                 :                                         
     509               0 :                                 if (EG(ze1_compatibility_mode)) {
     510               0 :                                         HashTable *ht = Z_OBJPROP_P(op);
     511               0 :                                         if (ht) {
     512               0 :                                                 retval = (zend_hash_num_elements(ht)?1:0);
     513                 :                                         }
     514                 :                                 }
     515                 :                                 
     516               0 :                                 zval_dtor(op);
     517               0 :                                 ZVAL_BOOL(op, retval);
     518               0 :                                 break;
     519                 :                         }
     520                 :                 default:
     521               0 :                         zval_dtor(op);
     522               0 :                         op->value.lval = 0;
     523                 :                         break;
     524                 :         }
     525            8285 :         op->type = IS_BOOL;
     526                 : }
     527                 : 
     528                 : ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC)
     529            5117 : {
     530                 :         long lval;
     531                 :         double dval;
     532                 : 
     533            5117 :         switch (op->type) {
     534                 :                 case IS_NULL:
     535              17 :                         op->value.str.val = STR_EMPTY_ALLOC();
     536              17 :                         op->value.str.len = 0;
     537              17 :                         break;
     538                 :                 case IS_STRING:
     539               0 :                         break;
     540                 :                 case IS_BOOL:
     541             105 :                         if (op->value.lval) {
     542               1 :                                 op->value.str.val = estrndup_rel("1", 1);
     543               1 :                                 op->value.str.len = 1;
     544                 :                         } else {
     545             104 :                                 op->value.str.val = STR_EMPTY_ALLOC();
     546             104 :                                 op->value.str.len = 0;
     547                 :                         }
     548             105 :                         break;
     549                 :                 case IS_RESOURCE: {
     550               0 :                         long tmp = op->value.lval;
     551                 :                         TSRMLS_FETCH();
     552                 : 
     553               0 :                         zend_list_delete(op->value.lval);
     554               0 :                         op->value.str.len = zend_spprintf(&op->value.str.val, 0, "Resource id #%ld", tmp);
     555               0 :                         break;
     556                 :                 }
     557                 :                 case IS_LONG:
     558            4992 :                         lval = op->value.lval;
     559                 : 
     560            4992 :                         op->value.str.len = zend_spprintf(&op->value.str.val, 0, "%ld", lval);  /* SAFE */
     561            4992 :                         break;
     562                 :                 case IS_DOUBLE: {
     563                 :                         TSRMLS_FETCH();
     564               3 :                         dval = op->value.dval;
     565               3 :                         op->value.str.len = zend_spprintf(&op->value.str.val, 0, "%.*G", (int) EG(precision), dval);  /* SAFE */
     566                 :                         /* %G already handles removing trailing zeros from the fractional part, yay */
     567               3 :                         break;
     568                 :                 }
     569                 :                 case IS_ARRAY:
     570               0 :                         zend_error(E_NOTICE, "Array to string conversion");
     571               0 :                         zval_dtor(op);
     572               0 :                         op->value.str.val = estrndup_rel("Array", sizeof("Array")-1);
     573               0 :                         op->value.str.len = sizeof("Array")-1;
     574               0 :                         break;
     575                 :                 case IS_OBJECT: {
     576                 :                         TSRMLS_FETCH();
     577                 :                         
     578               0 :                         convert_object_to_type(op, IS_STRING, convert_to_string);
     579                 : 
     580               0 :                         if (op->type == IS_STRING) {
     581               0 :                                 return;
     582                 :                         }
     583                 : 
     584               0 :                         zend_error(E_NOTICE, "Object of class %s to string conversion", Z_OBJCE_P(op)->name);
     585               0 :                         zval_dtor(op);
     586               0 :                         op->value.str.val = estrndup_rel("Object", sizeof("Object")-1);
     587               0 :                         op->value.str.len = sizeof("Object")-1;
     588               0 :                         break;
     589                 :                 }
     590                 :                 default:
     591               0 :                         zval_dtor(op);
     592               0 :                         ZVAL_BOOL(op, 0);
     593                 :                         break;
     594                 :         }
     595            5117 :         op->type = IS_STRING;
     596                 : }
     597                 : 
     598                 : 
     599                 : static void convert_scalar_to_array(zval *op, int type)
     600              22 : {
     601                 :         zval *entry;
     602                 :         
     603              22 :         ALLOC_ZVAL(entry);
     604              22 :         *entry = *op;
     605              22 :         INIT_PZVAL(entry);
     606                 :         
     607              22 :         switch (type) {
     608                 :                 case IS_ARRAY:
     609              22 :                         ALLOC_HASHTABLE(op->value.ht);
     610              22 :                         zend_hash_init(op->value.ht, 0, NULL, ZVAL_PTR_DTOR, 0);
     611              22 :                         zend_hash_index_update(op->value.ht, 0, (void *) &entry, sizeof(zval *), NULL);
     612              22 :                         op->type = IS_ARRAY;
     613              22 :                         break;
     614                 :                 case IS_OBJECT:
     615                 :                         {
     616                 :                                 /* OBJECTS_OPTIMIZE */
     617                 :                                 TSRMLS_FETCH();
     618                 : 
     619               0 :                                 object_init(op);
     620               0 :                                 zend_hash_update(Z_OBJPROP_P(op), "scalar", sizeof("scalar"), (void *) &entry, sizeof(zval *), NULL);
     621                 :                         }
     622                 :                         break;
     623                 :         }
     624              22 : }
     625                 : 
     626                 : 
     627                 : ZEND_API void convert_to_array(zval *op)
     628              26 : {
     629                 :         TSRMLS_FETCH();
     630                 : 
     631              26 :         switch (op->type) {
     632                 :                 case IS_ARRAY:
     633               3 :                         return;
     634                 :                         break;
     635                 : /* OBJECTS_OPTIMIZE */
     636                 :                 case IS_OBJECT:
     637                 :                         {
     638                 :                                 zval *tmp;
     639                 :                                 HashTable *ht;
     640                 : 
     641               1 :                                 ALLOC_HASHTABLE(ht);
     642               1 :                                 zend_hash_init(ht, 0, NULL, ZVAL_PTR_DTOR, 0);
     643               1 :                                 if (Z_OBJ_HT_P(op)->get_properties) {
     644               1 :                                         HashTable *obj_ht = Z_OBJ_HT_P(op)->get_properties(op TSRMLS_CC);
     645               1 :                                         if(obj_ht) {
     646               1 :                                                 zend_hash_copy(ht, obj_ht, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
     647                 :                                         }
     648                 :                                 } else {
     649               0 :                                         convert_object_to_type(op, IS_ARRAY, convert_to_array);
     650                 : 
     651               0 :                                         if (op->type == IS_ARRAY) {
     652               0 :                                                 zend_hash_destroy(ht);
     653               0 :                                                 FREE_HASHTABLE(ht);
     654               0 :                                                 return;
     655                 :                                         }
     656                 :                                 }
     657               1 :                                 zval_dtor(op);
     658               1 :                                 op->type = IS_ARRAY;
     659               1 :                                 op->value.ht = ht;
     660                 :                         }
     661               1 :                         return;
     662                 :                 case IS_NULL:
     663               0 :                         ALLOC_HASHTABLE(op->value.ht);
     664               0 :                         zend_hash_init(op->value.ht, 0, NULL, ZVAL_PTR_DTOR, 0);
     665               0 :                         op->type = IS_ARRAY;
     666               0 :                         break;
     667                 :                 default:
     668              22 :                         convert_scalar_to_array(op, IS_ARRAY);
     669                 :                         break;
     670                 :         }
     671                 : }
     672                 : 
     673                 : 
     674                 : ZEND_API void convert_to_object(zval *op)
     675               4 : {
     676               4 :         switch (op->type) {
     677                 :                 case IS_ARRAY:
     678                 :                         {
     679                 :                                 /* OBJECTS_OPTIMIZE */
     680                 :                                 TSRMLS_FETCH();
     681                 : 
     682               4 :                                 object_and_properties_init(op, zend_standard_class_def, op->value.ht);
     683               4 :                                 return;
     684                 :                                 break;
     685                 :                         }
     686                 :                 case IS_OBJECT:
     687               0 :                         return;
     688                 :                 case IS_NULL:
     689                 :                         {
     690                 :                                 /* OBJECTS_OPTIMIZE */
     691                 :                                 TSRMLS_FETCH();
     692                 : 
     693               0 :                                 object_init(op);
     694               0 :                                 break;
     695                 :                         }
     696                 :                 default:
     697               0 :                         convert_scalar_to_array(op, IS_OBJECT);
     698                 :                         break;
     699                 :         }
     700                 : }
     701                 : 
     702                 : ZEND_API void multi_convert_to_long_ex(int argc, ...)
     703               0 : {
     704                 :         zval **arg;
     705                 :         va_list ap;
     706                 :         
     707               0 :         va_start(ap, argc);
     708                 : 
     709               0 :         while (argc--) {
     710               0 :                 arg = va_arg(ap, zval **);
     711               0 :                 convert_to_long_ex(arg);
     712                 :         }
     713                 :         
     714               0 :         va_end(ap);
     715               0 : }
     716                 : 
     717                 : ZEND_API void multi_convert_to_double_ex(int argc, ...)
     718               0 : {
     719                 :         zval **arg;
     720                 :         va_list ap;
     721                 :         
     722               0 :         va_start(ap, argc);
     723                 : 
     724               0 :         while (argc--) {        
     725               0 :                 arg = va_arg(ap, zval **);
     726               0 :                 convert_to_double_ex(arg);
     727                 :         }
     728                 :         
     729               0 :         va_end(ap);
     730               0 : }
     731                 : 
     732                 : ZEND_API void multi_convert_to_string_ex(int argc, ...)
     733               0 : {
     734                 :         zval **arg;
     735                 :         va_list ap;
     736                 :         
     737               0 :         va_start(ap, argc);
     738                 : 
     739               0 :         while (argc--) {        
     740               0 :                 arg = va_arg(ap, zval **);
     741               0 :                 convert_to_string_ex(arg);
     742                 :         }
     743                 :         
     744               0 :         va_end(ap);
     745               0 : }
     746                 : 
     747                 : ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     748            7011 : {
     749                 :         zval op1_copy, op2_copy;
     750                 : 
     751            7011 :         if (op1->type == IS_ARRAY && op2->type == IS_ARRAY) {
     752                 :                 zval *tmp;
     753                 : 
     754               0 :                 if ((result == op1) && (result == op2)) {
     755                 :                         /* $a += $a */
     756               0 :                         return SUCCESS;
     757                 :                 }
     758               0 :                 if (result != op1) {
     759               0 :                         *result = *op1;
     760               0 :                         zval_copy_ctor(result);
     761                 :                 }
     762               0 :                 zend_hash_merge(result->value.ht, op2->value.ht, (void (*)(void *pData)) zval_add_ref, (void *) &tmp, sizeof(zval *), 0);
     763               0 :                 return SUCCESS;
     764                 :         }
     765            7011 :         zendi_convert_scalar_to_number(op1, op1_copy, result);
     766            7011 :         zendi_convert_scalar_to_number(op2, op2_copy, result);
     767                 : 
     768                 : 
     769            7011 :         if (op1->type == IS_LONG && op2->type == IS_LONG) {
     770            7011 :                 long lval = op1->value.lval + op2->value.lval;
     771                 :                 
     772                 :                 /* check for overflow by comparing sign bits */
     773            7011 :                 if ( (op1->value.lval & LONG_SIGN_MASK) == (op2->value.lval & LONG_SIGN_MASK) 
     774                 :                         && (op1->value.lval & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) {
     775                 : 
     776               0 :                         result->value.dval = (double) op1->value.lval + (double) op2->value.lval;
     777               0 :                         result->type = IS_DOUBLE;
     778                 :                 } else {
     779            7011 :                         result->value.lval = lval;
     780            7011 :                         result->type = IS_LONG;
     781                 :                 }
     782            7011 :                 return SUCCESS;
     783                 :         }
     784               0 :         if ((op1->type == IS_DOUBLE && op2->type == IS_LONG)
     785                 :                 || (op1->type == IS_LONG && op2->type == IS_DOUBLE)) {
     786               0 :                 result->value.dval = (op1->type == IS_LONG ?
     787                 :                                                  (((double) op1->value.lval) + op2->value.dval) :
     788                 :                                                  (op1->value.dval + ((double) op2->value.lval)));
     789               0 :                 result->type = IS_DOUBLE;
     790               0 :                 return SUCCESS;
     791                 :         }
     792               0 :         if (op1->type == IS_DOUBLE && op2->type == IS_DOUBLE) {
     793               0 :                 result->type = IS_DOUBLE;
     794               0 :                 result->value.dval = op1->value.dval + op2->value.dval;
     795               0 :                 return SUCCESS;
     796                 :         }
     797               0 :         zend_error(E_ERROR, "Unsupported operand types");
     798               0 :         return FAILURE;                         /* unknown datatype */
     799                 : }
     800                 : 
     801                 : 
     802                 : ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     803            1445 : {
     804                 :         zval op1_copy, op2_copy;
     805                 :         
     806            1445 :         zendi_convert_scalar_to_number(op1, op1_copy, result);
     807            1445 :         zendi_convert_scalar_to_number(op2, op2_copy, result);
     808                 : 
     809            1445 :         if (op1->type == IS_LONG && op2->type == IS_LONG) {
     810            1444 :                 long lval = op1->value.lval - op2->value.lval;
     811                 :                 
     812                 :                 /* check for overflow by comparing sign bits */
     813            1444 :                 if ( (op1->value.lval & LONG_SIGN_MASK) != (op2->value.lval & LONG_SIGN_MASK) 
     814                 :                         && (op1->value.lval & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) {
     815                 : 
     816               0 :                         result->value.dval = (double) op1->value.lval - (double) op2->value.lval;
     817               0 :                         result->type = IS_DOUBLE;
     818                 :                 } else {
     819            1444 :                         result->value.lval = lval;
     820            1444 :                         result->type = IS_LONG;
     821                 :                 }
     822            1444 :                 return SUCCESS;
     823                 :         }
     824               1 :         if ((op1->type == IS_DOUBLE && op2->type == IS_LONG)
     825                 :                 || (op1->type == IS_LONG && op2->type == IS_DOUBLE)) {
     826               0 :                 result->value.dval = (op1->type == IS_LONG ?
     827                 :                                                  (((double) op1->value.lval) - op2->value.dval) :
     828                 :                                                  (op1->value.dval - ((double) op2->value.lval)));
     829               0 :                 result->type = IS_DOUBLE;
     830               0 :                 return SUCCESS;
     831                 :         }
     832               1 :         if (op1->type == IS_DOUBLE && op2->type == IS_DOUBLE) {
     833               1 :                 result->type = IS_DOUBLE;
     834               1 :                 result->value.dval = op1->value.dval - op2->value.dval;
     835               1 :                 return SUCCESS;
     836                 :         }
     837               0 :         zend_error(E_ERROR, "Unsupported operand types");
     838               0 :         return FAILURE;                         /* unknown datatype */
     839                 : }
     840                 : 
     841                 : 
     842                 : ZEND_API int mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     843              11 : {
     844                 :         zval op1_copy, op2_copy;
     845                 :         
     846              11 :         zendi_convert_scalar_to_number(op1, op1_copy, result);
     847              11 :         zendi_convert_scalar_to_number(op2, op2_copy, result);
     848                 : 
     849              11 :         if (op1->type == IS_LONG && op2->type == IS_LONG) {
     850                 :                 long overflow;
     851                 : 
     852               0 :                 ZEND_SIGNED_MULTIPLY_LONG(op1->value.lval,op2->value.lval, result->value.lval,result->value.dval,overflow);
     853               0 :                 result->type = overflow ? IS_DOUBLE : IS_LONG;       
     854               0 :                 return SUCCESS;
     855                 :         }
     856              11 :         if ((op1->type == IS_DOUBLE && op2->type == IS_LONG)
     857                 :                 || (op1->type == IS_LONG && op2->type == IS_DOUBLE)) {
     858              11 :                 result->value.dval = (op1->type == IS_LONG ?
     859                 :                                                  (((double) op1->value.lval) * op2->value.dval) :
     860                 :                                                  (op1->value.dval * ((double) op2->value.lval)));
     861              11 :                 result->type = IS_DOUBLE;
     862              11 :                 return SUCCESS;
     863                 :         }
     864               0 :         if (op1->type == IS_DOUBLE && op2->type == IS_DOUBLE) {
     865               0 :                 result->type = IS_DOUBLE;
     866               0 :                 result->value.dval = op1->value.dval * op2->value.dval;
     867               0 :                 return SUCCESS;
     868                 :         }
     869               0 :         zend_error(E_ERROR, "Unsupported operand types");
     870               0 :         return FAILURE;                         /* unknown datatype */
     871                 : }
     872                 : 
     873                 : ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     874            2898 : {
     875                 :         zval op1_copy, op2_copy;
     876                 :         
     877            2898 :         zendi_convert_scalar_to_number(op1, op1_copy, result);
     878            2898 :         zendi_convert_scalar_to_number(op2, op2_copy, result);
     879                 : 
     880            2898 :         if ((op2->type == IS_LONG && op2->value.lval == 0) || (op2->type == IS_DOUBLE && op2->value.dval == 0.0)) {
     881               0 :                 zend_error(E_WARNING, "Division by zero");
     882               0 :                 ZVAL_BOOL(result, 0);
     883               0 :                 return FAILURE;                 /* division by zero */
     884                 :         }
     885            2898 :         if (op1->type == IS_LONG && op2->type == IS_LONG) {
     886            2293 :                 if (op1->value.lval % op2->value.lval == 0) { /* integer */
     887             800 :                         result->type = IS_LONG;
     888             800 :                         result->value.lval = op1->value.lval / op2->value.lval;
     889                 :                 } else {
     890            1493 :                         result->type = IS_DOUBLE;
     891            1493 :                         result->value.dval = ((double) op1->value.lval) / op2->value.lval;
     892                 :                 }
     893            2293 :                 return SUCCESS;
     894                 :         }
     895             605 :         if ((op1->type == IS_DOUBLE && op2->type == IS_LONG)
     896                 :                 || (op1->type == IS_LONG && op2->type == IS_DOUBLE)) {
     897             605 :                 result->value.dval = (op1->type == IS_LONG ?
     898                 :                                                  (((double) op1->value.lval) / op2->value.dval) :
     899                 :                                                  (op1->value.dval / ((double) op2->value.lval)));
     900             605 :                 result->type = IS_DOUBLE;
     901             605 :                 return SUCCESS;
     902                 :         }
     903               0 :         if (op1->type == IS_DOUBLE && op2->type == IS_DOUBLE) {
     904               0 :                 result->type = IS_DOUBLE;
     905               0 :                 result->value.dval = op1->value.dval / op2->value.dval;
     906               0 :                 return SUCCESS;
     907                 :         }
     908               0 :         zend_error(E_ERROR, "Unsupported operand types");
     909               0 :         return FAILURE;                         /* unknown datatype */
     910                 : }
     911                 : 
     912                 : 
     913                 : ZEND_API int mod_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     914               0 : {
     915                 :         zval op1_copy, op2_copy;
     916                 :         
     917               0 :         zendi_convert_to_long(op1, op1_copy, result);
     918               0 :         zendi_convert_to_long(op2, op2_copy, result);
     919                 : 
     920               0 :         if (op2->value.lval == 0) {
     921               0 :                 zend_error(E_WARNING, "Division by zero");
     922               0 :                 ZVAL_BOOL(result, 0);
     923               0 :                 return FAILURE;                 /* modulus by zero */
     924                 :         }
     925                 : 
     926               0 :         if (abs(op2->value.lval) == 1) {
     927               0 :                 ZVAL_LONG(result, 0);
     928               0 :                 return SUCCESS;
     929                 :         }
     930                 : 
     931               0 :         result->type = IS_LONG;
     932               0 :         result->value.lval = op1->value.lval % op2->value.lval;
     933               0 :         return SUCCESS;
     934                 : }
     935                 : 
     936                 : 
     937                 : 
     938                 : ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     939               0 : {
     940                 :         zval op1_copy, op2_copy;
     941                 :         
     942               0 :         result->type = IS_BOOL;
     943                 : 
     944               0 :         zendi_convert_to_boolean(op1, op1_copy, result);
     945               0 :         zendi_convert_to_boolean(op2, op2_copy, result);
     946               0 :         result->value.lval = op1->value.lval ^ op2->value.lval;
     947               0 :         return SUCCESS;
     948                 : }
     949                 : 
     950                 : 
     951                 : ZEND_API int boolean_not_function(zval *result, zval *op1 TSRMLS_DC)
     952           11252 : {
     953                 :         zval op1_copy;
     954                 :         
     955           11252 :         zendi_convert_to_boolean(op1, op1_copy, result);
     956                 : 
     957           11252 :         result->type = IS_BOOL;
     958           11252 :         result->value.lval = !op1->value.lval;
     959           11252 :         return SUCCESS;
     960                 : }
     961                 : 
     962                 : 
     963                 : ZEND_API int bitwise_not_function(zval *result, zval *op1 TSRMLS_DC)
     964               0 : {
     965               0 :         zval op1_copy = *op1;
     966                 :         
     967               0 :         op1 = &op1_copy;
     968                 :         
     969               0 :         if (op1->type == IS_DOUBLE) {
     970               0 :                 op1->value.lval = (long) op1->value.dval;
     971               0 :                 op1->type = IS_LONG;
     972                 :         }
     973               0 :         if (op1->type == IS_LONG) {
     974               0 :                 result->value.lval = ~op1->value.lval;
     975               0 :                 result->type = IS_LONG;
     976               0 :                 return SUCCESS;
     977                 :         }
     978               0 :         if (op1->type == IS_STRING) {
     979                 :                 int i;
     980                 : 
     981               0 :                 result->type = IS_STRING;
     982               0 :                 result->value.str.val = estrndup(op1->value.str.val, op1->value.str.len);
     983               0 :                 result->value.str.len = op1->value.str.len;
     984               0 :                 for (i = 0; i < op1->value.str.len; i++) {
     985               0 :                         result->value.str.val[i] = ~op1->value.str.val[i];
     986                 :                 }
     987               0 :                 return SUCCESS;
     988                 :         }
     989               0 :         zend_error(E_ERROR, "Unsupported operand types");
     990               0 :         return FAILURE;                         /* unknown datatype */
     991                 : }
     992                 : 
     993                 : 
     994                 : ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     995               7 : {
     996                 :         zval op1_copy, op2_copy;
     997                 :         
     998               7 :         if (op1->type == IS_STRING && op2->type == IS_STRING) {
     999                 :                 zval *longer, *shorter;
    1000                 :                 char *result_str;
    1001                 :                 int i, result_len;
    1002                 : 
    1003               0 :                 if (op1->value.str.len >= op2->value.str.len) {
    1004               0 :                         longer = op1;
    1005               0 :                         shorter = op2;
    1006                 :                 } else {
    1007               0 :                         longer = op2;
    1008               0 :                         shorter = op1;
    1009                 :                 }
    1010                 : 
    1011               0 :                 result->type = IS_STRING;
    1012               0 :                 result_len = longer->value.str.len;
    1013               0 :                 result_str = estrndup(longer->value.str.val, longer->value.str.len);
    1014               0 :                 for (i = 0; i < shorter->value.str.len; i++) {
    1015               0 :                         result_str[i] |= shorter->value.str.val[i];
    1016                 :                 }
    1017               0 :                 if (result==op1) {
    1018               0 :                         STR_FREE(result->value.str.val);
    1019                 :                 }
    1020               0 :                 result->value.str.val = result_str;
    1021               0 :                 result->value.str.len = result_len;
    1022               0 :                 return SUCCESS;
    1023                 :         }
    1024               7 :         zendi_convert_to_long(op1, op1_copy, result);
    1025               7 :         zendi_convert_to_long(op2, op2_copy, result);
    1026                 : 
    1027               7 :         result->type = IS_LONG;
    1028               7 :         result->value.lval = op1->value.lval | op2->value.lval;
    1029               7 :         return SUCCESS;
    1030                 : }
    1031                 : 
    1032                 : 
    1033                 : ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1034               0 : {
    1035                 :         zval op1_copy, op2_copy;
    1036                 :         
    1037               0 :         if (op1->type == IS_STRING && op2->type == IS_STRING) {
    1038                 :                 zval *longer, *shorter;
    1039                 :                 char *result_str;
    1040                 :                 int i, result_len;
    1041                 : 
    1042               0 :                 if (op1->value.str.len >= op2->value.str.len) {
    1043               0 :                         longer = op1;
    1044               0 :                         shorter = op2;
    1045                 :                 } else {
    1046               0 :                         longer = op2;
    1047               0 :                         shorter = op1;
    1048                 :                 }
    1049                 : 
    1050               0 :                 result->type = IS_STRING;
    1051               0 :                 result_len = shorter->value.str.len;
    1052               0 :                 result_str = estrndup(shorter->value.str.val, shorter->value.str.len);
    1053               0 :                 for (i = 0; i < shorter->value.str.len; i++) {
    1054               0 :                         result_str[i] &= longer->value.str.val[i];
    1055                 :                 }
    1056               0 :                 if (result==op1) {
    1057               0 :                         STR_FREE(result->value.str.val);
    1058                 :                 }
    1059               0 :                 result->value.str.val = result_str;
    1060               0 :                 result->value.str.len = result_len;
    1061               0 :                 return SUCCESS;
    1062                 :         }
    1063                 :         
    1064                 : 
    1065               0 :         zendi_convert_to_long(op1, op1_copy, result);
    1066               0 :         zendi_convert_to_long(op2, op2_copy, result);
    1067                 : 
    1068               0 :         result->type = IS_LONG;
    1069               0 :         result->value.lval = op1->value.lval & op2->value.lval;
    1070               0 :         return SUCCESS;
    1071                 : }
    1072                 : 
    1073                 : 
    1074                 : ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1075               0 : {
    1076                 :         zval op1_copy, op2_copy;
    1077                 :         
    1078               0 :         if (op1->type == IS_STRING && op2->type == IS_STRING) {
    1079                 :                 zval *longer, *shorter;
    1080                 :                 char *result_str;
    1081                 :                 int i, result_len;
    1082                 : 
    1083               0 :                 if (op1->value.str.len >= op2->value.str.len) {
    1084               0 :                         longer = op1;
    1085               0 :                         shorter = op2;
    1086                 :                 } else {
    1087               0 :                         longer = op2;
    1088               0 :                         shorter = op1;
    1089                 :                 }
    1090                 : 
    1091               0 :                 result->type = IS_STRING;
    1092               0 :                 result_len = shorter->value.str.len;
    1093               0 :                 result_str = estrndup(shorter->value.str.val, shorter->value.str.len);
    1094               0 :                 for (i = 0; i < shorter->value.str.len; i++) {
    1095               0 :                         result_str[i] ^= longer->value.str.val[i];
    1096                 :                 }
    1097               0 :                 if (result==op1) {
    1098               0 :                         STR_FREE(result->value.str.val);
    1099                 :                 }
    1100               0 :                 result->value.str.val = result_str;
    1101               0 :                 result->value.str.len = result_len;
    1102               0 :                 return SUCCESS;
    1103                 :         }
    1104                 : 
    1105               0 :         zendi_convert_to_long(op1, op1_copy, result);
    1106               0 :         zendi_convert_to_long(op2, op2_copy, result);   
    1107                 : 
    1108               0 :         result->type = IS_LONG;
    1109               0 :         result->value.lval = op1->value.lval ^ op2->value.lval;
    1110               0 :         return SUCCESS;
    1111                 : }
    1112                 : 
    1113                 : 
    1114                 : ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1115               0 : {
    1116                 :         zval op1_copy, op2_copy;
    1117                 :         
    1118               0 :         zendi_convert_to_long(op1, op1_copy, result);
    1119               0 :         zendi_convert_to_long(op2, op2_copy, result);
    1120               0 :         result->value.lval = op1->value.lval << op2->value.lval;
    1121               0 :         result->type = IS_LONG;
    1122               0 :         return SUCCESS;
    1123                 : }
    1124                 : 
    1125                 : 
    1126                 : ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1127               0 : {
    1128                 :         zval op1_copy, op2_copy;
    1129                 :         
    1130               0 :         zendi_convert_to_long(op1, op1_copy, result);
    1131               0 :         zendi_convert_to_long(op2, op2_copy, result);
    1132               0 :         result->value.lval = op1->value.lval >> op2->value.lval;
    1133               0 :         result->type = IS_LONG;
    1134               0 :         return SUCCESS;
    1135                 : }
    1136                 : 
    1137                 : 
    1138                 : 
    1139                 : /* must support result==op1 */
    1140                 : ZEND_API int add_char_to_string(zval *result, zval *op1, zval *op2)
    1141            5394 : {
    1142            5394 :         result->value.str.len = op1->value.str.len + 1;
    1143            5394 :         result->value.str.val = (char *) erealloc(op1->value.str.val, result->value.str.len+1);
    1144            5394 :     result->value.str.val[result->value.str.len - 1] = (char) op2->value.lval;
    1145            5394 :         result->value.str.val[result->value.str.len] = 0;
    1146            5394 :         result->type = IS_STRING;
    1147            5394 :         return SUCCESS;
    1148                 : }
    1149                 : 
    1150                 : 
    1151                 : /* must support result==op1 */
    1152                 : ZEND_API int add_string_to_string(zval *result, zval *op1, zval *op2)
    1153           25601 : {
    1154           25601 :         int length = op1->value.str.len + op2->value.str.len;
    1155                 : 
    1156           25601 :         result->value.str.val = (char *) erealloc(op1->value.str.val, length+1);
    1157           25601 :     memcpy(result->value.str.val+op1->value.str.len, op2->value.str.val, op2->value.str.len);
    1158           25601 :     result->value.str.val[length] = 0;
    1159           25601 :         result->value.str.len = length;
    1160           25601 :         result->type = IS_STRING;
    1161           25601 :         return SUCCESS;
    1162                 : }
    1163                 : 
    1164                 : 
    1165                 : ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1166           47786 : {
    1167                 :         zval op1_copy, op2_copy;
    1168           47786 :         int use_copy1 = 0, use_copy2 = 0;
    1169                 : 
    1170           47786 :         if (op1->type != IS_STRING) {
    1171               0 :                 zend_make_printable_zval(op1, &op1_copy, &use_copy1);
    1172                 :         }
    1173           47786 :         if (op2->type != IS_STRING) {
    1174             102 :                 zend_make_printable_zval(op2, &op2_copy, &use_copy2);
    1175                 :         }
    1176                 : 
    1177           47786 :         if (use_copy1) {
    1178                 :                 /* We have created a converted copy of op1. Therefore, op1 won't become the result so
    1179                 :                  * we have to free it.
    1180                 :                  */
    1181               0 :                 if (result == op1) {
    1182               0 :                         zval_dtor(op1);
    1183                 :                 }
    1184               0 :                 op1 = &op1_copy;
    1185                 :         }
    1186           47786 :         if (use_copy2) {
    1187             102 :                 op2 = &op2_copy;
    1188                 :         }
    1189           47786 :         if (result==op1) {      /* special case, perform operations on result */
    1190           13149 :                 uint res_len = op1->value.str.len + op2->value.str.len;
    1191                 :                 
    1192           13149 :                 result->value.str.val = erealloc(result->value.str.val, res_len+1);
    1193                 : 
    1194           13149 :                 memcpy(result->value.str.val+result->value.str.len, op2->value.str.val, op2->value.str.len);
    1195           13149 :                 result->value.str.val[res_len]=0;
    1196           13149 :                 result->value.str.len = res_len;
    1197                 :         } else {
    1198           34637 :                 result->value.str.len = op1->value.str.len + op2->value.str.len;
    1199           34637 :                 result->value.str.val = (char *) emalloc(result->value.str.len + 1);
    1200           34637 :                 memcpy(result->value.str.val, op1->value.str.val, op1->value.str.len);
    1201           34637 :                 memcpy(result->value.str.val+op1->value.str.len, op2->value.str.val, op2->value.str.len);
    1202           34637 :                 result->value.str.val[result->value.str.len] = 0;
    1203           34637 :                 result->type = IS_STRING;
    1204                 :         }
    1205           47786 :         if (use_copy1) {
    1206               0 :                 zval_dtor(op1);
    1207                 :         }
    1208           47786 :         if (use_copy2) {
    1209             102 :                 zval_dtor(op2);
    1210                 :         }
    1211           47786 :         return SUCCESS;
    1212                 : }
    1213                 : 
    1214                 : 
    1215                 : ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1216             867 : {
    1217                 :         zval op1_copy, op2_copy;
    1218             867 :         int use_copy1 = 0, use_copy2 = 0;
    1219                 : 
    1220             867 :         if (op1->type != IS_STRING) {
    1221               0 :                 zend_make_printable_zval(op1, &op1_copy, &use_copy1);
    1222                 :         }
    1223             867 :         if (op2->type != IS_STRING) {
    1224               0 :                 zend_make_printable_zval(op2, &op2_copy, &use_copy2);
    1225                 :         }
    1226                 : 
    1227             867 :         if (use_copy1) {
    1228               0 :                 op1 = &op1_copy;
    1229                 :         }
    1230             867 :         if (use_copy2) {
    1231               0 :                 op2 = &op2_copy;
    1232                 :         }
    1233                 : 
    1234             867 :         result->value.lval = zend_binary_zval_strcmp(op1, op2);
    1235             867 :         result->type = IS_LONG;
    1236                 : 
    1237             867 :         if (use_copy1) {
    1238               0 :                 zval_dtor(op1);
    1239                 :         }
    1240             867 :         if (use_copy2) {
    1241               0 :                 zval_dtor(op2);
    1242                 :         }
    1243             867 :         return SUCCESS;
    1244                 : }
    1245                 : 
    1246                 : #if HAVE_STRCOLL
    1247                 : ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1248               0 : {
    1249                 :         zval op1_copy, op2_copy;
    1250               0 :         int use_copy1 = 0, use_copy2 = 0;
    1251                 : 
    1252               0 :         if (op1->type != IS_STRING) {
    1253               0 :                 zend_make_printable_zval(op1, &op1_copy, &use_copy1);
    1254                 :         }
    1255               0 :         if (op2->type != IS_STRING) {
    1256               0 :                 zend_make_printable_zval(op2, &op2_copy, &use_copy2);
    1257                 :         }
    1258                 : 
    1259               0 :         if (use_copy1) {
    1260               0 :                 op1 = &op1_copy;
    1261                 :         }
    1262               0 :         if (use_copy2) {
    1263               0 :                 op2 = &op2_copy;
    1264                 :         }
    1265                 : 
    1266               0 :         result->value.lval = strcoll(op1->value.str.val, op2->value.str.val);
    1267               0 :         result->type = IS_LONG;
    1268                 : 
    1269               0 :         if (use_copy1) {
    1270               0 :                 zval_dtor(op1);
    1271                 :         }
    1272               0 :         if (use_copy2) {
    1273               0 :                 zval_dtor(op2);
    1274                 :         }
    1275               0 :         return SUCCESS;
    1276                 : }
    1277                 : #endif
    1278                 : 
    1279                 : ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1280               6 : {
    1281                 :         zval op1_copy, op2_copy;
    1282                 : 
    1283               6 :         op1_copy = *op1;
    1284               6 :         zval_copy_ctor(&op1_copy);
    1285                 : 
    1286               6 :         op2_copy = *op2;
    1287               6 :         zval_copy_ctor(&op2_copy);
    1288                 : 
    1289               6 :         convert_to_double(&op1_copy);
    1290               6 :         convert_to_double(&op2_copy);
    1291                 : 
    1292               6 :         ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL(op1_copy)-Z_DVAL(op2_copy)));
    1293                 : 
    1294               6 :         return SUCCESS;
    1295                 : }
    1296                 : 
    1297                 : 
    1298                 : static inline void zend_free_obj_get_result(zval *op)
    1299          210642 : {
    1300          210642 :         if (op) {
    1301               0 :                 if (op->refcount == 0) {
    1302               0 :                         zval_dtor(op);
    1303               0 :                         FREE_ZVAL(op);
    1304                 :                 } else {
    1305               0 :                         zval_ptr_dtor(&op);
    1306                 :                 }
    1307                 :         }
    1308          210642 : }
    1309                 : 
    1310                 : #define COMPARE_RETURN_AND_FREE(retval) \
    1311                 :                         zend_free_obj_get_result(op1_free); \
    1312                 :                         zend_free_obj_get_result(op2_free); \
    1313                 :                         return retval;
    1314                 : 
    1315                 : ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1316          105321 : {
    1317                 :         zval op1_copy, op2_copy;
    1318                 :         zval *op1_free, *op2_free;
    1319          105321 :         int op1_obj = Z_TYPE_P(op1) == IS_OBJECT;
    1320          105321 :         int op2_obj = Z_TYPE_P(op2) == IS_OBJECT;
    1321                 :         int eq_comp = op1_obj && op2_obj && (Z_OBJ_HANDLER_P(op1,compare_objects) 
    1322          105321 :                                           == Z_OBJ_HANDLER_P(op2,compare_objects));
    1323                 : 
    1324          105321 :         if (op1_obj && !eq_comp) {
    1325               0 :                 if (Z_TYPE_P(op2) == IS_NULL) {
    1326               0 :                         ZVAL_LONG(result, 1);
    1327               0 :                         return SUCCESS;
    1328               0 :                 } else if (Z_OBJ_HT_P(op1)->get) {
    1329               0 :                         op1 = op1_free = Z_OBJ_HT_P(op1)->get(op1 TSRMLS_CC);
    1330               0 :                 } else if (!op2_obj && Z_OBJ_HT_P(op1)->cast_object) {
    1331               0 :                         ALLOC_INIT_ZVAL(op1_free);
    1332               0 :                         if (Z_OBJ_HT_P(op1)->cast_object(op1, op1_free, Z_TYPE_P(op2) TSRMLS_CC) == FAILURE) {
    1333               0 :                                 op2_free = NULL;
    1334               0 :                                 ZVAL_LONG(result, 1);
    1335               0 :                                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1336                 :                         }
    1337               0 :                         op1 = op1_free;
    1338                 :                 } else {
    1339               0 :                         op1_free = NULL;
    1340                 :                 }
    1341               0 :                 op1_obj = Z_TYPE_P(op1) == IS_OBJECT;
    1342               0 :                 eq_comp = op1_obj && op2_obj && (Z_OBJ_HANDLER_P(op1,compare_objects) 
    1343                 :                                           == Z_OBJ_HANDLER_P(op2,compare_objects));
    1344                 :         } else {
    1345          105321 :                 op1_free = NULL;
    1346                 :         }
    1347          105321 :         if (op2_obj && !eq_comp) {
    1348               0 :                 if (Z_TYPE_P(op1) == IS_NULL) {
    1349               0 :                         op2_free = NULL;
    1350               0 :                         ZVAL_LONG(result, -1);
    1351               0 :                         COMPARE_RETURN_AND_FREE(SUCCESS);
    1352               0 :                 } else if (Z_OBJ_HT_P(op2)->get) {
    1353               0 :                         op2 = op2_free = Z_OBJ_HT_P(op2)->get(op2 TSRMLS_CC);
    1354               0 :                 } else if (!op1_obj && Z_OBJ_HT_P(op2)->cast_object) {
    1355               0 :                         ALLOC_INIT_ZVAL(op2_free);
    1356               0 :                         if (Z_OBJ_HT_P(op2)->cast_object(op2, op2_free, Z_TYPE_P(op1) TSRMLS_CC) == FAILURE) {
    1357               0 :                                 ZVAL_LONG(result, -1);
    1358               0 :                                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1359                 :                         }
    1360               0 :                         op2 = op2_free;
    1361                 :                 } else {
    1362               0 :                         op2_free = NULL;
    1363                 :                 }
    1364               0 :                 op2_obj = Z_TYPE_P(op2) == IS_OBJECT;
    1365               0 :                 eq_comp = op1_obj && op2_obj && (Z_OBJ_HANDLER_P(op1,compare_objects) 
    1366                 :                                           == Z_OBJ_HANDLER_P(op2,compare_objects));
    1367                 :         } else {
    1368          105321 :                 op2_free = NULL;
    1369                 :         }
    1370                 : 
    1371          105321 :         if ((Z_TYPE_P(op1) == IS_NULL && Z_TYPE_P(op2) == IS_STRING)
    1372                 :                 || (Z_TYPE_P(op2) == IS_NULL && Z_TYPE_P(op1) == IS_STRING)) {
    1373               0 :                 if (Z_TYPE_P(op1) == IS_NULL) {
    1374               0 :                         ZVAL_LONG(result, zend_binary_strcmp("", 0, Z_STRVAL_P(op2), Z_STRLEN_P(op2)));
    1375               0 :                         COMPARE_RETURN_AND_FREE(SUCCESS);
    1376                 :                 } else {
    1377               0 :                         ZVAL_LONG(result, zend_binary_strcmp(Z_STRVAL_P(op1), Z_STRLEN_P(op1), "", 0));
    1378               0 :                         COMPARE_RETURN_AND_FREE(SUCCESS);
    1379                 :                 }
    1380                 :         }
    1381                 :                 
    1382          105321 :         if (op1->type == IS_STRING && op2->type == IS_STRING) {
    1383            4727 :                 zendi_smart_strcmp(result, op1, op2);
    1384            4727 :                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1385                 :         }
    1386                 : 
    1387          100594 :         if (Z_TYPE_P(op1) == IS_BOOL || Z_TYPE_P(op2) == IS_BOOL
    1388                 :                 || Z_TYPE_P(op1) == IS_NULL || Z_TYPE_P(op2) == IS_NULL) {
    1389              94 :                 zendi_convert_to_boolean(op1, op1_copy, result);
    1390              94 :                 zendi_convert_to_boolean(op2, op2_copy, result);
    1391              94 :                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
    1392              94 :                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1393                 :         }
    1394                 : 
    1395                 :         /* If both are objects sharing the same comparision handler then use is */
    1396          100500 :         if (eq_comp) {
    1397               0 :                 ZVAL_LONG(result, Z_OBJ_HT_P(op1)->compare_objects(op1, op2 TSRMLS_CC));
    1398               0 :                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1399                 :         }
    1400                 : 
    1401          100500 :         zendi_convert_scalar_to_number(op1, op1_copy, result);
    1402          100500 :         zendi_convert_scalar_to_number(op2, op2_copy, result);
    1403                 : 
    1404          100500 :         if (Z_TYPE_P(op1) == IS_LONG && Z_TYPE_P(op2) == IS_LONG) {
    1405           89764 :                 ZVAL_LONG(result, Z_LVAL_P(op1)>Z_LVAL_P(op2)?1:(Z_LVAL_P(op1)<Z_LVAL_P(op2)?-1:0));
    1406           89764 :                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1407                 :         }
    1408           10736 :         if ((Z_TYPE_P(op1) == IS_DOUBLE || Z_TYPE_P(op1) == IS_LONG)
    1409                 :                 && (Z_TYPE_P(op2) == IS_DOUBLE || Z_TYPE_P(op2) == IS_LONG)) {
    1410           10734 :                 Z_DVAL_P(result) = (Z_TYPE_P(op1) == IS_LONG ? (double) Z_LVAL_P(op1) : Z_DVAL_P(op1)) - (Z_TYPE_P(op2) == IS_LONG ? (double) Z_LVAL_P(op2) : Z_DVAL_P(op2));
    1411           10734 :                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1412           10734 :                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1413                 :         }
    1414               2 :         if (Z_TYPE_P(op1)==IS_ARRAY && Z_TYPE_P(op2)==IS_ARRAY) {
    1415               1 :                 zend_compare_arrays(result, op1, op2 TSRMLS_CC);
    1416               1 :                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1417                 :         }
    1418                 : 
    1419               1 :         if (Z_TYPE_P(op1)==IS_ARRAY) {
    1420               1 :                 ZVAL_LONG(result, 1);
    1421               1 :                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1422                 :         }
    1423               0 :         if (Z_TYPE_P(op2)==IS_ARRAY) {
    1424               0 :                 ZVAL_LONG(result, -1);
    1425               0 :                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1426                 :         }
    1427               0 :         if (Z_TYPE_P(op1)==IS_OBJECT) {
    1428               0 :                 ZVAL_LONG(result, 1);
    1429               0 :                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1430                 :         }
    1431               0 :         if (Z_TYPE_P(op2)==IS_OBJECT) {
    1432               0 :                 ZVAL_LONG(result, -1);
    1433               0 :                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1434                 :         }
    1435                 : 
    1436               0 :         ZVAL_BOOL(result, 0);
    1437               0 :         COMPARE_RETURN_AND_FREE(FAILURE);
    1438                 : }
    1439                 : 
    1440                 : 
    1441                 : static int hash_zval_identical_function(const zval **z1, const zval **z2)
    1442               3 : {
    1443                 :         zval result;
    1444                 :         TSRMLS_FETCH();
    1445                 : 
    1446                 :         /* is_identical_function() returns 1 in case of identity and 0 in case
    1447                 :          * of a difference;
    1448                 :          * whereas this comparison function is expected to return 0 on identity,
    1449                 :          * and non zero otherwise.
    1450                 :          */
    1451               3 :         if (is_identical_function(&result, (zval *) *z1, (zval *) *z2 TSRMLS_CC)==FAILURE) {
    1452               0 :                 return 1;
    1453                 :         }
    1454               3 :         return !result.value.lval;
    1455                 : }
    1456                 : 
    1457                 : 
    1458                 : ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1459            6772 : {
    1460            6772 :         result->type = IS_BOOL;
    1461            6772 :         if (op1->type != op2->type) {
    1462            4811 :                 result->value.lval = 0;
    1463            4811 :                 return SUCCESS;
    1464                 :         }
    1465            1961 :         switch (op1->type) {
    1466                 :                 case IS_NULL:
    1467              30 :                         result->value.lval = (op2->type==IS_NULL);
    1468              30 :                         break;
    1469                 :                 case IS_BOOL:
    1470                 :                 case IS_LONG:
    1471                 :                 case IS_RESOURCE:
    1472            1814 :                         result->value.lval = (op1->value.lval == op2->value.lval);
    1473            1814 :                         break;
    1474                 :                 case IS_DOUBLE:
    1475               0 :                         result->value.lval = (op1->value.dval == op2->value.dval);
    1476               0 :                         break;
    1477                 :                 case IS_STRING:
    1478             119 :                         if ((op1->value.str.len == op2->value.str.len)
    1479                 :                                 && (!memcmp(op1->value.str.val, op2->value.str.val, op1->value.str.len))) {
    1480               4 :                                 result->value.lval = 1;
    1481                 :                         } else {
    1482             111 :                                 result->value.lval = 0;
    1483                 :                         }
    1484             115 :                         break;
    1485                 :                 case IS_ARRAY:
    1486               2 :                         if (zend_hash_compare(op1->value.ht, op2->value.ht, (compare_func_t) hash_zval_identical_function, 1 TSRMLS_CC)==0) {
    1487               1 :                                 result->value.lval = 1;
    1488                 :                         } else {
    1489               1 :                                 result->value.lval = 0;
    1490                 :                         }
    1491               2 :                         break;
    1492                 :                 case IS_OBJECT:
    1493               0 :                         if (Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2)) {
    1494               0 :                                 if (EG(ze1_compatibility_mode)) {
    1495               0 :                                         zend_compare_objects(result, op1, op2 TSRMLS_CC);
    1496                 :                                         /* comparison returns 0 in case of equality and
    1497                 :                                          * 1 in case of ineqaulity, we need to reverse it
    1498                 :                                          */
    1499               0 :                                         result->value.lval = !result->value.lval;
    1500                 :                                 } else {
    1501               0 :                                         result->value.lval = (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2));
    1502                 :                                 }
    1503                 :                         } else {
    1504               0 :                                 result->value.lval = 0;
    1505                 :                         }
    1506               0 :                         break;
    1507                 :                 default:
    1508               0 :                         ZVAL_BOOL(result, 0);
    1509               0 :                         return FAILURE;
    1510                 :         }
    1511            1961 :         return SUCCESS;
    1512                 : }
    1513                 : 
    1514                 : 
    1515                 : ZEND_API int is_not_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1516            3147 : {
    1517            3147 :    result->type = IS_BOOL;
    1518            3147 :    if (is_identical_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    1519               0 :           return FAILURE;
    1520                 :    }
    1521            3147 :    result->value.lval = !result->value.lval;
    1522            3147 :    return SUCCESS;
    1523                 : }
    1524                 : 
    1525                 : 
    1526                 : ZEND_API int is_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1527            7628 : {
    1528            7628 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    1529               0 :                 return FAILURE;
    1530                 :         }
    1531            7628 :         convert_to_boolean(result);
    1532            7628 :         if (result->value.lval == 0) {
    1533            1348 :                 result->value.lval = 1;
    1534                 :         } else {
    1535            6280 :                 result->value.lval = 0;
    1536                 :         }
    1537            7628 :         return SUCCESS;
    1538                 : }
    1539                 : 
    1540                 : 
    1541                 : ZEND_API int is_not_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1542             550 : {
    1543             550 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    1544               0 :                 return FAILURE;
    1545                 :         }
    1546             550 :         convert_to_boolean(result);
    1547             550 :         if (result->value.lval) {
    1548             113 :                 result->value.lval = 1;
    1549                 :         } else {
    1550             437 :                 result->value.lval = 0;
    1551                 :         }
    1552             550 :         return SUCCESS;
    1553                 : }
    1554                 : 
    1555                 : 
    1556                 : ZEND_API int is_smaller_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1557           97112 : {
    1558           97112 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    1559               0 :                 return FAILURE;
    1560                 :         }
    1561           97112 :         if (result->type == IS_LONG) {
    1562           97112 :                 result->type = IS_BOOL;
    1563           97112 :                 if (result->value.lval < 0) {
    1564           67860 :                         result->value.lval = 1;
    1565                 :                 } else {
    1566           29252 :                         result->value.lval = 0;
    1567                 :                 }
    1568           97112 :                 return SUCCESS;
    1569                 :         }
    1570               0 :         if (result->type == IS_DOUBLE) {
    1571               0 :                 result->type = IS_BOOL;
    1572               0 :                 if (result->value.dval < 0) {
    1573               0 :                         result->value.lval = 1;
    1574                 :                 } else {
    1575               0 :                         result->value.lval = 0;
    1576                 :                 }
    1577               0 :                 return SUCCESS;
    1578                 :         }
    1579               0 :         zend_error(E_ERROR, "Unsupported operand types");
    1580               0 :         return FAILURE;
    1581                 : }
    1582                 : 
    1583                 : 
    1584                 : ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1585              30 : {
    1586              30 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    1587               0 :                 return FAILURE;
    1588                 :         }
    1589              30 :         if (result->type == IS_LONG) {
    1590              30 :                 result->type = IS_BOOL;
    1591              30 :                 if (result->value.lval <= 0) {
    1592              29 :                         result->value.lval = 1;
    1593                 :                 } else {
    1594               1 :                         result->value.lval = 0;
    1595                 :                 }
    1596              30 :                 return SUCCESS;
    1597                 :         }
    1598               0 :         if (result->type == IS_DOUBLE) {
    1599               0 :                 result->type = IS_BOOL;
    1600               0 :                 if (result->value.dval <= 0) {
    1601               0 :                         result->value.lval = 1;
    1602                 :                 } else {
    1603               0 :                         result->value.lval = 0;
    1604                 :                 }
    1605               0 :                 return SUCCESS;
    1606                 :         }
    1607               0 :         zend_error(E_ERROR, "Unsupported operand types");
    1608               0 :         return FAILURE;
    1609                 : }
    1610                 : 
    1611                 : 
    1612                 : ZEND_API zend_bool instanceof_function_ex(zend_class_entry *instance_ce, zend_class_entry *ce, zend_bool interfaces_only TSRMLS_DC)
    1613            1577 : {
    1614                 :         zend_uint i;
    1615                 : 
    1616            2599 :         for (i=0; i<instance_ce->num_interfaces; i++) {
    1617            1022 :                 if (instanceof_function(instance_ce->interfaces[i], ce TSRMLS_CC)) {
    1618               0 :                         return 1;
    1619                 :                 }
    1620                 :         }
    1621            1577 :         if (!interfaces_only) {
    1622            4515 :                 while (instance_ce) {
    1623            1913 :                         if (instance_ce == ce) {
    1624             552 :                                 return 1;
    1625                 :                         }
    1626            1361 :                         instance_ce = instance_ce->parent;
    1627                 :                 }
    1628                 :         }
    1629                 : 
    1630            1025 :         return 0;
    1631                 : }
    1632                 : 
    1633                 : ZEND_API zend_bool instanceof_function(zend_class_entry *instance_ce, zend_class_entry *ce TSRMLS_DC)
    1634            1577 : {
    1635            1577 :         return instanceof_function_ex(instance_ce, ce, 0 TSRMLS_CC);
    1636                 : }
    1637                 : 
    1638                 : #define LOWER_CASE 1
    1639                 : #define UPPER_CASE 2
    1640                 : #define NUMERIC 3
    1641                 : 
    1642                 : 
    1643                 : static void increment_string(zval *str)
    1644               0 : {
    1645               0 :     int carry=0;
    1646               0 :     int pos=str->value.str.len-1;
    1647               0 :     char *s=str->value.str.val;
    1648                 :     char *t;
    1649               0 :     int last=0; /* Shut up the compiler warning */
    1650                 :     int ch;
    1651                 :     
    1652               0 :         if (str->value.str.len == 0) {
    1653               0 :                 STR_FREE(str->value.str.val);
    1654               0 :                 str->value.str.val = estrndup("1", sizeof("1")-1);
    1655               0 :                 str->value.str.len = 1;
    1656               0 :                 return;
    1657                 :         }
    1658                 : 
    1659               0 :         while (pos >= 0) {
    1660               0 :         ch = s[pos];
    1661               0 :         if (ch >= 'a' && ch <= 'z') {
    1662               0 :             if (ch == 'z') {
    1663               0 :                 s[pos] = 'a';
    1664               0 :                 carry=1;
    1665                 :             } else {
    1666               0 :                 s[pos]++;
    1667               0 :                 carry=0;
    1668                 :             }
    1669               0 :             last=LOWER_CASE;
    1670               0 :         } else if (ch >= 'A' && ch <= 'Z') {
    1671               0 :             if (ch == 'Z') {
    1672               0 :                 s[pos] = 'A';
    1673               0 :                 carry=1;
    1674                 :             } else {
    1675               0 :                 s[pos]++;
    1676               0 :                 carry=0;
    1677                 :             }
    1678               0 :             last=UPPER_CASE;
    1679               0 :         } else if (ch >= '0' && ch <= '9') {
    1680               0 :             if (ch == '9') {
    1681               0 :                 s[pos] = '0';
    1682               0 :                 carry=1;
    1683                 :             } else {
    1684               0 :                 s[pos]++;
    1685               0 :                 carry=0;
    1686                 :             }
    1687               0 :             last = NUMERIC;
    1688                 :         } else {
    1689               0 :             carry=0;
    1690               0 :             break;
    1691                 :         }
    1692               0 :         if (carry == 0) {
    1693               0 :             break;
    1694                 :         }
    1695               0 :         pos--;
    1696                 :     }
    1697                 : 
    1698               0 :     if (carry) {
    1699               0 :         t = (char *) emalloc(str->value.str.len+1+1);
    1700               0 :         memcpy(t+1, str->value.str.val, str->value.str.len);
    1701               0 :         str->value.str.len++;
    1702               0 :         t[str->value.str.len] = '\0';
    1703               0 :         switch (last) {
    1704                 :             case NUMERIC:
    1705               0 :                 t[0] = '1';
    1706               0 :                 break;
    1707                 :             case UPPER_CASE:
    1708               0 :                 t[0] = 'A';
    1709               0 :                 break;
    1710                 :             case LOWER_CASE:
    1711               0 :                 t[0] = 'a';
    1712                 :                 break;
    1713                 :         }
    1714               0 :         STR_FREE(str->value.str.val);
    1715               0 :         str->value.str.val = t;
    1716                 :     }
    1717                 : }
    1718                 : 
    1719                 : 
    1720                 : ZEND_API int increment_function(zval *op1)
    1721           28928 : {
    1722           28928 :         switch (op1->type) {
    1723                 :                 case IS_LONG:
    1724           28928 :                         if (op1->value.lval == LONG_MAX) {
    1725                 :                                 /* switch to double */
    1726               0 :                                 double d = (double)op1->value.lval;
    1727               0 :                                 ZVAL_DOUBLE(op1, d+1);
    1728                 :                         } else {
    1729           28928 :                         op1->value.lval++;
    1730                 :                         } 
    1731           28928 :                         break;
    1732                 :                 case IS_DOUBLE:
    1733               0 :                         op1->value.dval = op1->value.dval + 1;
    1734               0 :                         break;
    1735                 :                 case IS_NULL:
    1736               0 :                         op1->value.lval = 1;
    1737               0 :                         op1->type = IS_LONG;
    1738               0 :                         break;
    1739                 :                 case IS_STRING: {
    1740                 :                                 long lval;
    1741                 :                                 double dval;
    1742               0 :                                 char *strval = op1->value.str.val;
    1743                 : 
    1744               0 :                                 switch (is_numeric_string(strval, op1->value.str.len, &lval, &dval, 0)) {
    1745                 :                                         case IS_LONG:
    1746               0 :                                                 if (lval == LONG_MAX) {
    1747                 :                                                         /* switch to double */
    1748               0 :                                                         double d = (double)lval;
    1749               0 :                                                         ZVAL_DOUBLE(op1, d+1);
    1750                 :                                                 } else {
    1751               0 :                                                 op1->value.lval = lval+1;
    1752               0 :                                                 op1->type = IS_LONG;
    1753                 :                                                 }
    1754               0 :                                                 efree(strval); /* should never be empty_string */
    1755               0 :                                                 break;
    1756                 :                                         case IS_DOUBLE:
    1757               0 :                                                 op1->value.dval = dval+1;
    1758               0 :                                                 op1->type = IS_DOUBLE;
    1759               0 :                                                 efree(strval); /* should never be empty_string */
    1760               0 :                                                 break;
    1761                 :                                         default:
    1762                 :                                                 /* Perl style string increment */
    1763               0 :                                                 increment_string(op1);
    1764                 :                                                 break;
    1765                 :                                 }
    1766                 :                         }
    1767               0 :                         break;
    1768                 :                 default:
    1769               0 :                         return FAILURE;
    1770                 :         }
    1771           28928 :         return SUCCESS;
    1772                 : }
    1773                 : 
    1774                 : 
    1775                 : ZEND_API int decrement_function(zval *op1)
    1776           31014 : {
    1777                 :         long lval;
    1778                 :         double dval;
    1779                 :         
    1780           31014 :         switch (op1->type) {
    1781                 :                 case IS_LONG:
    1782           18462 :                         if (op1->value.lval == LONG_MIN) {
    1783               0 :                                 double d = (double)op1->value.lval;
    1784               0 :                                 ZVAL_DOUBLE(op1, d-1);
    1785                 :                         } else {
    1786           18462 :                         op1->value.lval--;
    1787                 :                         }
    1788           18462 :                         break;
    1789                 :                 case IS_DOUBLE:
    1790           12552 :                         op1->value.dval = op1->value.dval - 1;
    1791           12552 :                         break;
    1792                 :                 case IS_STRING:         /* Like perl we only support string increment */
    1793               0 :                         if (op1->value.str.len == 0) { /* consider as 0 */
    1794               0 :                                 STR_FREE(op1->value.str.val);
    1795               0 :                                 op1->value.lval = -1;
    1796               0 :                                 op1->type = IS_LONG;
    1797               0 :                                 break;
    1798                 :                         }
    1799               0 :                         switch (is_numeric_string(op1->value.str.val, op1->value.str.len, &lval, &dval, 0)) {
    1800                 :                                 case IS_LONG:
    1801               0 :                                         STR_FREE(op1->value.str.val);
    1802               0 :                                         if (lval == LONG_MIN) {
    1803               0 :                                                 double d = (double)lval;
    1804               0 :                                                 ZVAL_DOUBLE(op1, d-1);
    1805                 :                                         } else {
    1806               0 :                                                 op1->value.lval = lval-1;
    1807               0 :                                                 op1->type = IS_LONG;
    1808                 :                                         }
    1809               0 :                                         break;
    1810                 :                                 case IS_DOUBLE:
    1811               0 :                                         STR_FREE(op1->value.str.val);
    1812               0 :                                         op1->value.dval = dval - 1;
    1813               0 :                                         op1->type = IS_DOUBLE;
    1814                 :                                         break;
    1815                 :                         }
    1816               0 :                         break;
    1817                 :                 default:
    1818               0 :                         return FAILURE;
    1819                 :         }
    1820                 : 
    1821           31014 :         return SUCCESS;
    1822                 : }
    1823                 : 
    1824                 : 
    1825                 : ZEND_API int zval_is_true(zval *op)
    1826             102 : {
    1827             102 :         convert_to_boolean(op);
    1828             102 :         return (op->value.lval ? 1 : 0);
    1829                 : }
    1830                 : 
    1831                 : #ifdef ZEND_USE_TOLOWER_L
    1832                 : ZEND_API void zend_update_current_locale()
    1833                 : {
    1834                 :         current_locale = _get_current_locale();
    1835                 : }
    1836                 : #endif
    1837                 : 
    1838                 : ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length)
    1839          358122 : {
    1840          358122 :         register unsigned char *str = (unsigned char*)source;
    1841          358122 :         register unsigned char *result = (unsigned char*)dest;
    1842          358122 :         register unsigned char *end = str + length;
    1843                 : 
    1844         4786497 :         while (str < end) {
    1845         4070253 :                 *result++ = zend_tolower((int)*str++);
    1846                 :         }
    1847          358122 :         *result = '\0';
    1848                 : 
    1849          358122 :         return dest;
    1850                 : }
    1851                 :         
    1852                 : ZEND_API void zend_str_tolower(char *str, unsigned int length)
    1853           11573 : {
    1854           11573 :         register unsigned char *p = (unsigned char*)str;
    1855           11573 :         register unsigned char *end = p + length;
    1856                 : 
    1857          102266 :         while (p < end) {
    1858           79120 :                 *p = zend_tolower((int)*p);
    1859           79120 :                 p++;
    1860                 :         }
    1861           11573 : }
    1862                 : 
    1863                 : ZEND_API int zend_binary_strcmp(char *s1, uint len1, char *s2, uint len2)
    1864            6350 : {
    1865                 :         int retval;
    1866                 :         
    1867            6350 :         retval = memcmp(s1, s2, MIN(len1, len2));
    1868            6350 :         if (!retval) {
    1869             526 :                 return (len1 - len2);
    1870                 :         } else {
    1871            5824 :                 return retval;
    1872                 :         }
    1873                 : }
    1874                 : 
    1875                 : ZEND_API int zend_binary_strncmp(char *s1, uint len1, char *s2, uint len2, uint length)
    1876             110 : {
    1877                 :         int retval;
    1878                 :         
    1879             110 :         retval = memcmp(s1, s2, MIN(length, MIN(len1, len2)));
    1880             110 :         if (!retval) {
    1881             110 :                 return (MIN(length, len1) - MIN(length, len2));
    1882                 :         } else {
    1883               0 :                 return retval;
    1884                 :         }
    1885                 : }
    1886                 : 
    1887                 : 
    1888                 : ZEND_API int zend_binary_strcasecmp(char *s1, uint len1, char *s2, uint len2)
    1889              11 : {
    1890                 :         int len;
    1891                 :         int c1, c2;
    1892                 : 
    1893              11 :         len = MIN(len1, len2);
    1894                 : 
    1895              22 :         while (len--) {
    1896              11 :                 c1 = zend_tolower((int)*(unsigned char *)s1++);
    1897              11 :                 c2 = zend_tolower((int)*(unsigned char *)s2++);
    1898              11 :                 if (c1 != c2) {
    1899              11 :                         return c1 - c2;
    1900                 :                 }
    1901                 :         }
    1902                 : 
    1903               0 :         return len1 - len2;
    1904                 : }
    1905                 : 
    1906                 : 
    1907                 : ZEND_API int zend_binary_strncasecmp(char *s1, uint len1, char *s2, uint len2, uint length)
    1908             368 : {
    1909                 :         int len;
    1910                 :         int c1, c2;
    1911                 : 
    1912             368 :         len = MIN(length, MIN(len1, len2));
    1913                 : 
    1914             785 :         while (len--) {
    1915              95 :                 c1 = zend_tolower((int)*(unsigned char *)s1++);
    1916              95 :                 c2 = zend_tolower((int)*(unsigned char *)s2++);
    1917              95 :                 if (c1 != c2) {
    1918              46 :                         return c1 - c2;
    1919                 :                 }
    1920                 :         }
    1921                 : 
    1922             322 :         return MIN(length, len1) - MIN(length, len2);
    1923                 : }
    1924                 : 
    1925                 : 
    1926                 : ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2)
    1927            6350 : {
    1928            6350 :         return zend_binary_strcmp(s1->value.str.val, s1->value.str.len, s2->value.str.val, s2->value.str.len);
    1929                 : }
    1930                 : 
    1931                 : ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3)
    1932             110 : {
    1933             110 :         return zend_binary_strncmp(s1->value.str.val, s1->value.str.len, s2->value.str.val, s2->value.str.len, s3->value.lval);
    1934                 : }
    1935                 : 
    1936                 : 
    1937                 : ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2)
    1938               0 : {
    1939               0 :         return zend_binary_strcasecmp(s1->value.str.val, s1->value.str.len, s2->value.str.val, s2->value.str.len);
    1940                 : }
    1941                 : 
    1942                 : 
    1943                 : ZEND_API int zend_binary_zval_strncasecmp(zval *s1, zval *s2, zval *s3)
    1944             368 : {
    1945             368 :         return zend_binary_strncasecmp(s1->value.str.val, s1->value.str.len, s2->value.str.val, s2->value.str.len, s3->value.lval);
    1946                 : }
    1947                 : 
    1948                 : 
    1949                 : ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2)
    1950            4727 : {
    1951                 :         int ret1, ret2;
    1952                 :         long lval1, lval2;
    1953                 :         double dval1, dval2;
    1954                 :         
    1955            4729 :         if ((ret1=is_numeric_string(s1->value.str.val, s1->value.str.len, &lval1, &dval1, 0)) &&
    1956                 :                 (ret2=is_numeric_string(s2->value.str.val, s2->value.str.len, &lval2, &dval2, 0))) {
    1957               4 :                 if ((ret1==IS_DOUBLE) || (ret2==IS_DOUBLE)) {
    1958               2 :                         if (ret1!=IS_DOUBLE) {
    1959               0 :                                 dval1 = (double) lval1;
    1960               2 :                         } else if (ret2!=IS_DOUBLE) {
    1961               0 :                                 dval2 = (double) lval2;
    1962               2 :                         } else if (dval1 == dval2 && !zend_finite(dval1)) {
    1963                 :                                 /* Both values overflowed and have the same sign,
    1964                 :                                  * so a numeric comparison would be inaccurate */
    1965               0 :                                 goto string_cmp;
    1966                 :                         }
    1967               2 :                         result->value.dval = dval1 - dval2;
    1968               2 :                         result->value.lval = ZEND_NORMALIZE_BOOL(result->value.dval);
    1969               2 :                         result->type = IS_LONG;
    1970                 :                 } else { /* they both have to be long's */
    1971               0 :                         result->value.lval = lval1 > lval2 ? 1 : (lval1 < lval2 ? -1 : 0);
    1972               0 :                         result->type = IS_LONG;
    1973                 :                 }
    1974                 :         } else {
    1975            4725 : string_cmp:
    1976            4725 :                 result->value.lval = zend_binary_zval_strcmp(s1, s2);
    1977            4725 :                 result->value.lval = ZEND_NORMALIZE_BOOL(result->value.lval);
    1978            4725 :                 result->type = IS_LONG;
    1979                 :         }
    1980                 :         return; 
    1981                 : }
    1982                 : 
    1983                 : 
    1984                 : static int hash_zval_compare_function(const zval **z1, const zval **z2 TSRMLS_DC)
    1985               1 : {
    1986                 :         zval result;
    1987                 : 
    1988               1 :         if (compare_function(&result, (zval *) *z1, (zval *) *z2 TSRMLS_CC)==FAILURE) {
    1989               0 :                 return 1;
    1990                 :         }
    1991               1 :         return result.value.lval;
    1992                 : }
    1993                 : 
    1994                 : ZEND_API int zend_compare_symbol_tables_i(HashTable *ht1, HashTable *ht2 TSRMLS_DC)
    1995               0 : {
    1996               0 :         return zend_hash_compare(ht1, ht2, (compare_func_t) hash_zval_compare_function, 0 TSRMLS_CC);
    1997                 : }
    1998                 : 
    1999                 : 
    2000                 : 
    2001                 : ZEND_API void zend_compare_symbol_tables(zval *result, HashTable *ht1, HashTable *ht2 TSRMLS_DC)
    2002               1 : {
    2003               1 :         result->type = IS_LONG;
    2004               1 :         result->value.lval = zend_hash_compare(ht1, ht2, (compare_func_t) hash_zval_compare_function, 0 TSRMLS_CC);
    2005               1 : }
    2006                 : 
    2007                 : 
    2008                 : ZEND_API void zend_compare_arrays(zval *result, zval *a1, zval *a2 TSRMLS_DC)
    2009               1 : {
    2010               1 :         zend_compare_symbol_tables(result, a1->value.ht, a2->value.ht TSRMLS_CC);
    2011               1 : }
    2012                 : 
    2013                 : 
    2014                 : ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2 TSRMLS_DC)
    2015               0 : {
    2016               0 :         result->type = IS_LONG;
    2017                 : 
    2018               0 :         if (Z_OBJ_HANDLE_P(o1) == Z_OBJ_HANDLE_P(o2)) {
    2019               0 :                 result->value.lval = 0;
    2020               0 :                 return;
    2021                 :         }
    2022                 : 
    2023               0 :         if (Z_OBJ_HT_P(o1)->compare_objects == NULL) {
    2024               0 :                 result->value.lval = 1;
    2025                 :         } else {
    2026               0 :                 result->value.lval = Z_OBJ_HT_P(o1)->compare_objects(o1, o2 TSRMLS_CC);
    2027                 :         }
    2028                 : }
    2029                 : 
    2030                 : ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC)
    2031              29 : {
    2032                 :         TSRMLS_FETCH();
    2033                 : 
    2034              29 :         op->value.str.len = zend_spprintf(&op->value.str.val, 0, "%.*G", (int) EG(precision), (double)op->value.dval);
    2035              29 : }
    2036                 : 
    2037                 : /*
    2038                 :  * Local variables:
    2039                 :  * tab-width: 4
    2040                 :  * c-basic-offset: 4
    2041                 :  * indent-tabs-mode: t
    2042                 :  * End:
    2043                 :  */

Generated by: LTP GCOV extension version 1.5