PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - standard - formatted_print.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 306
Code covered: 94.4 % Executed lines: 289
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 5                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2009 The PHP Group                                |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 3.01 of the PHP 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.php.net/license/3_01.txt                                  |
      11                 :    | If you did not receive a copy of the PHP license and are unable to   |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@php.net so we can mail you a copy immediately.               |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Author: Stig Sæther Bakken <ssb@php.net>                             |
      16                 :    +----------------------------------------------------------------------+
      17                 :  */
      18                 : 
      19                 : /* $Id: formatted_print.c 290150 2009-11-02 17:37:32Z felipe $ */
      20                 : 
      21                 : #include <math.h>                         /* modf() */
      22                 : #include "php.h"
      23                 : #include "ext/standard/head.h"
      24                 : #include "php_string.h"
      25                 : #include "zend_execute.h"
      26                 : #include <stdio.h>
      27                 : 
      28                 : #ifdef HAVE_LOCALE_H
      29                 : #include <locale.h>
      30                 : #define LCONV_DECIMAL_POINT (*lconv->decimal_point)
      31                 : #else
      32                 : #define LCONV_DECIMAL_POINT '.'
      33                 : #endif
      34                 : 
      35                 : #define ALIGN_LEFT 0
      36                 : #define ALIGN_RIGHT 1
      37                 : #define ADJ_WIDTH 1
      38                 : #define ADJ_PRECISION 2
      39                 : #define NUM_BUF_SIZE 500
      40                 : #define NDIG 80
      41                 : #define FLOAT_DIGITS 6
      42                 : #define FLOAT_PRECISION 6
      43                 : #define MAX_FLOAT_DIGITS 38
      44                 : #define MAX_FLOAT_PRECISION 40
      45                 : 
      46                 : #if 0
      47                 : /* trick to control varargs functions through cpp */
      48                 : # define PRINTF_DEBUG(arg) php_printf arg
      49                 : #else
      50                 : # define PRINTF_DEBUG(arg)
      51                 : #endif
      52                 : 
      53                 : static char hexchars[] = "0123456789abcdef";
      54                 : static char HEXCHARS[] = "0123456789ABCDEF";
      55                 : 
      56                 : /* php_spintf_appendchar() {{{ */
      57                 : inline static void
      58                 : php_sprintf_appendchar(char **buffer, int *pos, int *size, char add TSRMLS_DC)
      59          756255 : {
      60          756255 :         if ((*pos + 1) >= *size) {
      61               0 :                 *size <<= 1;
      62                 :                 PRINTF_DEBUG(("%s(): ereallocing buffer to %d bytes\n", get_active_function_name(TSRMLS_C), *size));
      63               0 :                 *buffer = erealloc(*buffer, *size);
      64                 :         }
      65                 :         PRINTF_DEBUG(("sprintf: appending '%c', pos=\n", add, *pos));
      66          756255 :         (*buffer)[(*pos)++] = add;
      67          756255 : }
      68                 : /* }}} */
      69                 : 
      70                 : /* php_spintf_appendstring() {{{ */
      71                 : inline static void
      72                 : php_sprintf_appendstring(char **buffer, int *pos, int *size, char *add,
      73                 :                                                    int min_width, int max_width, char padding,
      74                 :                                                    int alignment, int len, int neg, int expprec, int always_sign)
      75           64757 : {
      76                 :         register int npad;
      77                 :         int req_size;
      78                 :         int copy_len;
      79                 :         int m_width;
      80                 : 
      81           64757 :         copy_len = (expprec ? MIN(max_width, len) : len);
      82           64757 :         npad = min_width - copy_len;
      83                 : 
      84           64757 :         if (npad < 0) {
      85           54250 :                 npad = 0;
      86                 :         }
      87                 :         
      88                 :         PRINTF_DEBUG(("sprintf: appendstring(%x, %d, %d, \"%s\", %d, '%c', %d)\n",
      89                 :                                   *buffer, *pos, *size, add, min_width, padding, alignment));
      90           64757 :         m_width = MAX(min_width, copy_len);
      91                 : 
      92           64757 :         if(m_width > INT_MAX - *pos - 1) {
      93               0 :                 zend_error_noreturn(E_ERROR, "Field width %d is too long", m_width);
      94                 :         }
      95                 : 
      96           64757 :         req_size = *pos + m_width + 1;
      97                 : 
      98           64757 :         if (req_size > *size) {
      99           18194 :                 while (req_size > *size) {
     100            6100 :                         if(*size > INT_MAX/2) {
     101               0 :                                 zend_error_noreturn(E_ERROR, "Field width %d is too long", req_size); 
     102                 :                         }
     103            6100 :                         *size <<= 1;
     104                 :                 }
     105                 :                 PRINTF_DEBUG(("sprintf ereallocing buffer to %d bytes\n", *size));
     106            6047 :                 *buffer = erealloc(*buffer, *size);
     107                 :         }
     108           64757 :         if (alignment == ALIGN_RIGHT) {
     109           63396 :                 if ((neg || always_sign) && padding=='0') {
     110              36 :                         (*buffer)[(*pos)++] = (neg) ? '-' : '+';
     111              36 :                         add++;
     112              36 :                         len--;
     113              36 :                         copy_len--;
     114                 :                 }
     115          145967 :                 while (npad-- > 0) {
     116           19175 :                         (*buffer)[(*pos)++] = padding;
     117                 :                 }
     118                 :         }
     119                 :         PRINTF_DEBUG(("sprintf: appending \"%s\"\n", add));
     120           64757 :         memcpy(&(*buffer)[*pos], add, copy_len + 1);
     121           64757 :         *pos += copy_len;
     122           64757 :         if (alignment == ALIGN_LEFT) {
     123            6434 :                 while (npad--) {
     124            3712 :                         (*buffer)[(*pos)++] = padding;
     125                 :                 }
     126                 :         }
     127           64757 : }
     128                 : /* }}} */
     129                 : 
     130                 : /* php_spintf_appendint() {{{ */
     131                 : inline static void
     132                 : php_sprintf_appendint(char **buffer, int *pos, int *size, long number,
     133                 :                                                 int width, char padding, int alignment, 
     134                 :                                                 int always_sign)
     135           27158 : {
     136                 :         char numbuf[NUM_BUF_SIZE];
     137                 :         register unsigned long magn, nmagn;
     138           27158 :         register unsigned int i = NUM_BUF_SIZE - 1, neg = 0;
     139                 : 
     140                 :         PRINTF_DEBUG(("sprintf: appendint(%x, %x, %x, %d, %d, '%c', %d)\n",
     141                 :                                   *buffer, pos, size, number, width, padding, alignment));
     142           27158 :         if (number < 0) {
     143             692 :                 neg = 1;
     144             692 :                 magn = ((unsigned long) -(number + 1)) + 1;
     145                 :         } else {
     146           26466 :                 magn = (unsigned long) number;
     147                 :         }
     148                 : 
     149                 :         /* Can't right-pad 0's on integers */
     150           27158 :         if(alignment==0 && padding=='0') padding=' ';
     151                 : 
     152           27158 :         numbuf[i] = '\0';
     153                 : 
     154                 :         do {
     155           86908 :                 nmagn = magn / 10;
     156                 : 
     157           86908 :                 numbuf[--i] = (unsigned char)(magn - (nmagn * 10)) + '0';
     158           86908 :                 magn = nmagn;
     159                 :         }
     160           86908 :         while (magn > 0 && i > 0);
     161           27158 :         if (neg) {
     162             692 :                 numbuf[--i] = '-';
     163           26466 :         } else if (always_sign) {
     164              24 :                 numbuf[--i] = '+';
     165                 :         }
     166                 :         PRINTF_DEBUG(("sprintf: appending %d as \"%s\", i=%d\n",
     167                 :                                   number, &numbuf[i], i));
     168           27158 :         php_sprintf_appendstring(buffer, pos, size, &numbuf[i], width, 0,
     169                 :                                                          padding, alignment, (NUM_BUF_SIZE - 1) - i,
     170                 :                                                          neg, 0, always_sign);
     171           27158 : }
     172                 : /* }}} */
     173                 : 
     174                 : /* php_spintf_appenduint() {{{ */
     175                 : inline static void
     176                 : php_sprintf_appenduint(char **buffer, int *pos, int *size,
     177                 :                                            unsigned long number,
     178                 :                                            int width, char padding, int alignment)
     179             927 : {
     180                 :         char numbuf[NUM_BUF_SIZE];
     181                 :         register unsigned long magn, nmagn;
     182             927 :         register unsigned int i = NUM_BUF_SIZE - 1;
     183                 : 
     184                 :         PRINTF_DEBUG(("sprintf: appenduint(%x, %x, %x, %d, %d, '%c', %d)\n",
     185                 :                                   *buffer, pos, size, number, width, padding, alignment));
     186             927 :         magn = (unsigned long) number;
     187                 : 
     188                 :         /* Can't right-pad 0's on integers */
     189             927 :         if (alignment == 0 && padding == '0') padding = ' ';
     190                 : 
     191             927 :         numbuf[i] = '\0';
     192                 : 
     193                 :         do {
     194            3300 :                 nmagn = magn / 10;
     195                 : 
     196            3300 :                 numbuf[--i] = (unsigned char)(magn - (nmagn * 10)) + '0';
     197            3300 :                 magn = nmagn;
     198            3300 :         } while (magn > 0 && i > 0);
     199                 : 
     200                 :         PRINTF_DEBUG(("sprintf: appending %d as \"%s\", i=%d\n", number, &numbuf[i], i));
     201             927 :         php_sprintf_appendstring(buffer, pos, size, &numbuf[i], width, 0,
     202                 :                                                          padding, alignment, (NUM_BUF_SIZE - 1) - i, 0, 0, 0);
     203             927 : }
     204                 : /* }}} */
     205                 : 
     206                 : /* php_spintf_appenddouble() {{{ */
     207                 : inline static void
     208                 : php_sprintf_appenddouble(char **buffer, int *pos,
     209                 :                                                  int *size, double number,
     210                 :                                                  int width, char padding,
     211                 :                                                  int alignment, int precision,
     212                 :                                                  int adjust, char fmt,
     213                 :                                                  int always_sign
     214                 :                                                  TSRMLS_DC)
     215            3781 : {
     216                 :         char num_buf[NUM_BUF_SIZE];
     217            3781 :         char *s = NULL;
     218            3781 :         int s_len = 0, is_negative = 0;
     219                 : #ifdef HAVE_LOCALE_H
     220                 :         struct lconv *lconv;
     221                 : #endif
     222                 : 
     223                 :         PRINTF_DEBUG(("sprintf: appenddouble(%x, %x, %x, %f, %d, '%c', %d, %c)\n",
     224                 :                                   *buffer, pos, size, number, width, padding, alignment, fmt));
     225            3781 :         if ((adjust & ADJ_PRECISION) == 0) {
     226            3464 :                 precision = FLOAT_PRECISION;
     227             317 :         } else if (precision > MAX_FLOAT_PRECISION) {
     228               2 :                 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Requested precision of %d digits was truncated to PHP maximum of %d digits", precision, MAX_FLOAT_PRECISION);
     229               2 :                 precision = MAX_FLOAT_PRECISION;
     230                 :         }
     231                 :         
     232            3781 :         if (zend_isnan(number)) {
     233              40 :                 is_negative = (number<0);
     234              40 :                 php_sprintf_appendstring(buffer, pos, size, "NaN", 3, 0, padding,
     235                 :                                                                  alignment, 3, is_negative, 0, always_sign);
     236              40 :                 return;
     237                 :         }
     238                 : 
     239            3741 :         if (zend_isinf(number)) {
     240               0 :                 is_negative = (number<0);
     241               0 :                 php_sprintf_appendstring(buffer, pos, size, "INF", 3, 0, padding,
     242                 :                                                                  alignment, 3, is_negative, 0, always_sign);
     243               0 :                 return;
     244                 :         }
     245                 : 
     246            3741 :         switch (fmt) {                  
     247                 :                 case 'e':
     248                 :                 case 'E':
     249                 :                 case 'f':
     250                 :                 case 'F':
     251                 : #ifdef HAVE_LOCALE_H
     252            3717 :                         lconv = localeconv();
     253                 : #endif
     254            3717 :                         s = php_conv_fp((fmt == 'f')?'F':fmt, number, 0, precision,
     255                 :                                                 (fmt == 'f')?LCONV_DECIMAL_POINT:'.',
     256                 :                                                 &is_negative, &num_buf[1], &s_len);
     257            3717 :                         if (is_negative) {
     258             821 :                                 num_buf[0] = '-';
     259             821 :                                 s = num_buf;
     260             821 :                                 s_len++;
     261            2896 :                         } else if (always_sign) {
     262              36 :                                 num_buf[0] = '+';
     263              36 :                                 s = num_buf;
     264              36 :                                 s_len++;
     265                 :                         }
     266            3717 :                         break;
     267                 : 
     268                 :                 case 'g':
     269                 :                 case 'G':
     270              24 :                         if (precision == 0)
     271               4 :                                 precision = 1;
     272                 :                         /*
     273                 :                          * * We use &num_buf[ 1 ], so that we have room for the sign
     274                 :                          */
     275                 : #ifdef HAVE_LOCALE_H
     276              24 :                         lconv = localeconv();
     277                 : #endif
     278              24 :                         s = php_gcvt(number, precision, LCONV_DECIMAL_POINT, (fmt == 'G')?'E':'e', &num_buf[1]);
     279              24 :                         is_negative = 0;
     280              24 :                         if (*s == '-') {
     281              12 :                                 is_negative = 1;
     282              12 :                                 s = &num_buf[1];
     283              12 :                         } else if (always_sign) {
     284               4 :                                 num_buf[0] = '+';
     285               4 :                                 s = num_buf;
     286                 :                         }
     287                 : 
     288              24 :                         s_len = strlen(s);
     289                 :                         break;
     290                 :         }
     291                 : 
     292            3741 :         php_sprintf_appendstring(buffer, pos, size, s, width, 0, padding,
     293                 :                                                          alignment, s_len, is_negative, 0, always_sign);
     294                 : }
     295                 : /* }}} */
     296                 : 
     297                 : /* php_spintf_appendd2n() {{{ */
     298                 : inline static void
     299                 : php_sprintf_append2n(char **buffer, int *pos, int *size, long number,
     300                 :                                          int width, char padding, int alignment, int n,
     301                 :                                          char *chartable, int expprec)
     302            6539 : {
     303                 :         char numbuf[NUM_BUF_SIZE];
     304                 :         register unsigned long num;
     305            6539 :         register unsigned int  i = NUM_BUF_SIZE - 1;
     306            6539 :         register int andbits = (1 << n) - 1;
     307                 : 
     308                 :         PRINTF_DEBUG(("sprintf: append2n(%x, %x, %x, %d, %d, '%c', %d, %d, %x)\n",
     309                 :                                   *buffer, pos, size, number, width, padding, alignment, n,
     310                 :                                   chartable));
     311                 :         PRINTF_DEBUG(("sprintf: append2n 2^%d andbits=%x\n", n, andbits));
     312                 : 
     313            6539 :         num = (unsigned long) number;
     314            6539 :         numbuf[i] = '\0';
     315                 : 
     316                 :         do {
     317           24130 :                 numbuf[--i] = chartable[(num & andbits)];
     318           24130 :                 num >>= n;
     319                 :         }
     320           24130 :         while (num > 0);
     321                 : 
     322            6539 :         php_sprintf_appendstring(buffer, pos, size, &numbuf[i], width, 0,
     323                 :                                                          padding, alignment, (NUM_BUF_SIZE - 1) - i,
     324                 :                                                          0, expprec, 0);
     325            6539 : }
     326                 : /* }}} */
     327                 : 
     328                 : /* php_spintf_getnumber() {{{ */
     329                 : inline static int
     330                 : php_sprintf_getnumber(char *buffer, int *pos)
     331           12637 : {
     332                 :         char *endptr;
     333           12637 :         register long num = strtol(&buffer[*pos], &endptr, 10);
     334           12637 :         register int i = 0;
     335                 : 
     336           12637 :         if (endptr != NULL) {
     337           12637 :                 i = (endptr - &buffer[*pos]);
     338                 :         }
     339                 :         PRINTF_DEBUG(("sprintf_getnumber: number was %d bytes long\n", i));
     340           12637 :         *pos += i;
     341                 : 
     342           12637 :         if (num >= INT_MAX || num < 0) {
     343               0 :                 return -1;
     344                 :         } else {
     345           12637 :                 return (int) num;
     346                 :         }
     347                 : }
     348                 : /* }}} */
     349                 : 
     350                 : /* php_formatted_print() {{{
     351                 :  * New sprintf implementation for PHP.
     352                 :  *
     353                 :  * Modifiers:
     354                 :  *
     355                 :  *  " "   pad integers with spaces
     356                 :  *  "-"   left adjusted field
     357                 :  *   n    field size
     358                 :  *  "."n  precision (floats only)
     359                 :  *  "+"   Always place a sign (+ or -) in front of a number
     360                 :  *
     361                 :  * Type specifiers:
     362                 :  *
     363                 :  *  "%"   literal "%", modifiers are ignored.
     364                 :  *  "b"   integer argument is printed as binary
     365                 :  *  "c"   integer argument is printed as a single character
     366                 :  *  "d"   argument is an integer
     367                 :  *  "f"   the argument is a float
     368                 :  *  "o"   integer argument is printed as octal
     369                 :  *  "s"   argument is a string
     370                 :  *  "x"   integer argument is printed as lowercase hexadecimal
     371                 :  *  "X"   integer argument is printed as uppercase hexadecimal
     372                 :  *
     373                 :  */
     374                 : static char *
     375                 : php_formatted_print(int ht, int *len, int use_array, int format_offset TSRMLS_DC)
     376           41843 : {
     377                 :         zval ***args, **z_format;
     378           41843 :         int argc, size = 240, inpos = 0, outpos = 0, temppos;
     379                 :         int alignment, currarg, adjusting, argnum, width, precision;
     380                 :         char *format, *result, padding;
     381                 :         int always_sign;
     382                 : 
     383           41843 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc) == FAILURE) {
     384               5 :                 return NULL;
     385                 :         }
     386                 : 
     387                 :         /* verify the number of args */
     388           41838 :         if ((use_array && argc != (2 + format_offset)) 
     389                 :                         || (!use_array && argc < (1 + format_offset))) {
     390               4 :                 efree(args);
     391               4 :                 WRONG_PARAM_COUNT_WITH_RETVAL(NULL);
     392                 :         }
     393                 :         
     394           41834 :         if (use_array) {
     395             590 :                 int i = 1;
     396                 :                 zval ***newargs;
     397                 :                 zval **array;
     398                 : 
     399             590 :                 z_format = args[format_offset];
     400             590 :                 array = args[1 + format_offset];
     401                 :                 
     402             590 :                 SEPARATE_ZVAL(array);
     403             590 :                 convert_to_array_ex(array);
     404                 :                 
     405             590 :                 argc = 1 + zend_hash_num_elements(Z_ARRVAL_PP(array));
     406             590 :                 newargs = (zval ***)safe_emalloc(argc, sizeof(zval *), 0);
     407             590 :                 newargs[0] = z_format;
     408                 :                 
     409             590 :                 for (zend_hash_internal_pointer_reset(Z_ARRVAL_PP(array));
     410            4386 :                          zend_hash_get_current_data(Z_ARRVAL_PP(array), (void **)&newargs[i++]) == SUCCESS;
     411            3206 :                          zend_hash_move_forward(Z_ARRVAL_PP(array)));
     412                 : 
     413             590 :                 efree(args);
     414             590 :                 args = newargs;
     415             590 :                 format_offset = 0;
     416                 :         }
     417                 :         
     418           41834 :         convert_to_string_ex(args[format_offset]);
     419           41834 :         format = Z_STRVAL_PP(args[format_offset]);
     420           41834 :         result = emalloc(size);
     421                 : 
     422           41834 :         currarg = 1;
     423                 : 
     424          907120 :         while (inpos<Z_STRLEN_PP(args[format_offset])) {
     425          823483 :                 int expprec = 0, multiuse = 0;
     426                 :                 zval *tmp;
     427                 : 
     428                 :                 PRINTF_DEBUG(("sprintf: format[%d]='%c'\n", inpos, format[inpos]));
     429                 :                 PRINTF_DEBUG(("sprintf: outpos=%d\n", outpos));
     430          823483 :                 if (format[inpos] != '%') {
     431          755201 :                         php_sprintf_appendchar(&result, &outpos, &size, format[inpos++] TSRMLS_CC);
     432           68282 :                 } else if (format[inpos + 1] == '%') {
     433              45 :                         php_sprintf_appendchar(&result, &outpos, &size, '%' TSRMLS_CC);
     434              45 :                         inpos += 2;
     435                 :                 } else {
     436                 :                         /* starting a new format specifier, reset variables */
     437           68237 :                         alignment = ALIGN_RIGHT;
     438           68237 :                         adjusting = 0;
     439           68237 :                         padding = ' ';
     440           68237 :                         always_sign = 0;
     441           68237 :                         inpos++;                        /* skip the '%' */
     442                 : 
     443                 :                         PRINTF_DEBUG(("sprintf: first looking at '%c', inpos=%d\n",
     444                 :                                                   format[inpos], inpos));
     445           82124 :                         if (isascii((int)format[inpos]) && !isalpha((int)format[inpos])) {
     446                 :                                 /* first look for argnum */
     447           13889 :                                 temppos = inpos;
     448           13889 :                                 while (isdigit((int)format[temppos])) temppos++;
     449           13889 :                                 if (format[temppos] == '$') {
     450             555 :                                         argnum = php_sprintf_getnumber(format, &inpos);
     451                 : 
     452             555 :                                         if (argnum <= 0) {
     453               2 :                                                 efree(result);
     454               2 :                                                 efree(args);
     455               2 :                                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument number must be greater than zero");
     456               2 :                                                 return NULL;
     457                 :                                         }
     458                 : 
     459             553 :                                         multiuse = 1;
     460             553 :                                         inpos++;  /* skip the '$' */
     461                 :                                 } else {
     462           13334 :                                         argnum = currarg++;
     463                 :                                 }
     464                 : 
     465           13887 :                                 argnum += format_offset;
     466                 : 
     467                 :                                 /* after argnum comes modifiers */
     468                 :                                 PRINTF_DEBUG(("sprintf: looking for modifiers\n"
     469                 :                                                           "sprintf: now looking at '%c', inpos=%d\n",
     470                 :                                                           format[inpos], inpos));
     471            9132 :                                 for (;; inpos++) {
     472           30000 :                                         if (format[inpos] == ' ' || format[inpos] == '0') {
     473            6981 :                                                 padding = format[inpos];
     474           16038 :                                         } else if (format[inpos] == '-') {
     475            1415 :                                                 alignment = ALIGN_LEFT;
     476                 :                                                 /* space padding, the default */
     477           14623 :                                         } else if (format[inpos] == '+') {
     478             179 :                                                 always_sign = 1;
     479           14444 :                                         } else if (format[inpos] == '\'') {
     480             557 :                                                 padding = format[++inpos];
     481                 :                                         } else {
     482                 :                                                 PRINTF_DEBUG(("sprintf: end of modifiers\n"));
     483           13887 :                                                 break;
     484                 :                                         }
     485            9132 :                                 }
     486                 :                                 PRINTF_DEBUG(("sprintf: padding='%c'\n", padding));
     487                 :                                 PRINTF_DEBUG(("sprintf: alignment=%s\n",
     488                 :                                                           (alignment == ALIGN_LEFT) ? "left" : "right"));
     489                 : 
     490                 : 
     491                 :                                 /* after modifiers comes width */
     492           13887 :                                 if (isdigit((int)format[inpos])) {
     493                 :                                         PRINTF_DEBUG(("sprintf: getting width\n"));
     494           11370 :                                         if ((width = php_sprintf_getnumber(format, &inpos)) < 0) {
     495               0 :                                                 efree(result);
     496               0 :                                                 efree(args);
     497               0 :                                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Width must be greater than zero and less than %d", INT_MAX);
     498               0 :                                                 return NULL;
     499                 :                                         }
     500           11370 :                                         adjusting |= ADJ_WIDTH;
     501                 :                                 } else {
     502            2517 :                                         width = 0;
     503                 :                                 }
     504                 :                                 PRINTF_DEBUG(("sprintf: width=%d\n", width));
     505                 : 
     506                 :                                 /* after width and argnum comes precision */
     507           13887 :                                 if (format[inpos] == '.') {
     508             714 :                                         inpos++;
     509                 :                                         PRINTF_DEBUG(("sprintf: getting precision\n"));
     510             714 :                                         if (isdigit((int)format[inpos])) {
     511             712 :                                                 if ((precision = php_sprintf_getnumber(format, &inpos)) < 0) {
     512               0 :                                                         efree(result);
     513               0 :                                                         efree(args);
     514               0 :                                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Precision must be greater than zero and less than %d", INT_MAX);
     515               0 :                                                         return NULL;
     516                 :                                                 }
     517             712 :                                                 adjusting |= ADJ_PRECISION;
     518             712 :                                                 expprec = 1;
     519                 :                                         } else {
     520               2 :                                                 precision = 0;
     521                 :                                         }
     522                 :                                 } else {
     523           13173 :                                         precision = 0;
     524                 :                                 }
     525                 :                                 PRINTF_DEBUG(("sprintf: precision=%d\n", precision));
     526                 :                         } else {
     527           54348 :                                 width = precision = 0;
     528           54348 :                                 argnum = currarg++ + format_offset;
     529                 :                         }
     530                 : 
     531           68235 :                         if (argnum >= argc) {
     532              29 :                                 efree(result);
     533              29 :                                 efree(args);
     534              29 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too few arguments");
     535              29 :                                 return NULL;
     536                 :                         }
     537                 : 
     538           68206 :                         if (format[inpos] == 'l') {
     539             713 :                                 inpos++;
     540                 :                         }
     541                 :                         PRINTF_DEBUG(("sprintf: format character='%c'\n", format[inpos]));
     542                 :                         /* now we expect to find a type specifier */
     543           68206 :                         if (multiuse) {
     544             553 :                                 MAKE_STD_ZVAL(tmp);
     545             553 :                                 *tmp = **(args[argnum]);
     546             553 :                                 INIT_PZVAL(tmp);
     547             553 :                                 zval_copy_ctor(tmp);
     548                 :                         } else {
     549           67653 :                                 SEPARATE_ZVAL(args[argnum]);
     550           67653 :                                 tmp = *(args[argnum]);
     551                 :                         }
     552                 : 
     553           68206 :                         switch (format[inpos]) {
     554                 :                                 case 's': {
     555                 :                                         zval *var, var_copy;
     556                 :                                         int use_copy;
     557                 : 
     558           26352 :                                         zend_make_printable_zval(tmp, &var_copy, &use_copy);
     559           26352 :                                         if (use_copy) {
     560            3668 :                                                 var = &var_copy;
     561                 :                                         } else {
     562           22684 :                                                 var = tmp;
     563                 :                                         }
     564           26352 :                                         php_sprintf_appendstring(&result, &outpos, &size,
     565                 :                                                                                          Z_STRVAL_P(var),
     566                 :                                                                                          width, precision, padding,
     567                 :                                                                                          alignment,
     568                 :                                                                                          Z_STRLEN_P(var),
     569                 :                                                                                          0, expprec, 0);
     570           26352 :                                         if (use_copy) {
     571            3668 :                                                 zval_dtor(&var_copy);
     572                 :                                         }
     573           26352 :                                         break;
     574                 :                                 }
     575                 : 
     576                 :                                 case 'd':
     577           27158 :                                         convert_to_long(tmp);
     578           27158 :                                         php_sprintf_appendint(&result, &outpos, &size,
     579                 :                                                                                   Z_LVAL_P(tmp),
     580                 :                                                                                   width, padding, alignment,
     581                 :                                                                                   always_sign);
     582           27158 :                                         break;
     583                 : 
     584                 :                                 case 'u':
     585             927 :                                         convert_to_long(tmp);
     586             927 :                                         php_sprintf_appenduint(&result, &outpos, &size,
     587                 :                                                                                   Z_LVAL_P(tmp),
     588                 :                                                                                   width, padding, alignment);
     589             927 :                                         break;
     590                 : 
     591                 :                                 case 'g':
     592                 :                                 case 'G':
     593                 :                                 case 'e':
     594                 :                                 case 'E':
     595                 :                                 case 'f':
     596                 :                                 case 'F':
     597            3781 :                                         convert_to_double(tmp);
     598            3781 :                                         php_sprintf_appenddouble(&result, &outpos, &size,
     599                 :                                                                                          Z_DVAL_P(tmp),
     600                 :                                                                                          width, padding, alignment,
     601                 :                                                                                          precision, adjusting,
     602                 :                                                                                          format[inpos], always_sign
     603                 :                                                                                          TSRMLS_CC);
     604            3781 :                                         break;
     605                 :                                         
     606                 :                                 case 'c':
     607             997 :                                         convert_to_long(tmp);
     608             997 :                                         php_sprintf_appendchar(&result, &outpos, &size,
     609                 :                                                                                 (char) Z_LVAL_P(tmp) TSRMLS_CC);
     610             997 :                                         break;
     611                 : 
     612                 :                                 case 'o':
     613            4056 :                                         convert_to_long(tmp);
     614            4056 :                                         php_sprintf_append2n(&result, &outpos, &size,
     615                 :                                                                                  Z_LVAL_P(tmp),
     616                 :                                                                                  width, padding, alignment, 3,
     617                 :                                                                                  hexchars, expprec);
     618            4056 :                                         break;
     619                 : 
     620                 :                                 case 'x':
     621            2097 :                                         convert_to_long(tmp);
     622            2097 :                                         php_sprintf_append2n(&result, &outpos, &size,
     623                 :                                                                                  Z_LVAL_P(tmp),
     624                 :                                                                                  width, padding, alignment, 4,
     625                 :                                                                                  hexchars, expprec);
     626            2097 :                                         break;
     627                 : 
     628                 :                                 case 'X':
     629             319 :                                         convert_to_long(tmp);
     630             319 :                                         php_sprintf_append2n(&result, &outpos, &size,
     631                 :                                                                                  Z_LVAL_P(tmp),
     632                 :                                                                                  width, padding, alignment, 4,
     633                 :                                                                                  HEXCHARS, expprec);
     634             319 :                                         break;
     635                 : 
     636                 :                                 case 'b':
     637              67 :                                         convert_to_long(tmp);
     638              67 :                                         php_sprintf_append2n(&result, &outpos, &size,
     639                 :                                                                                  Z_LVAL_P(tmp),
     640                 :                                                                                  width, padding, alignment, 1,
     641                 :                                                                                  hexchars, expprec);
     642              67 :                                         break;
     643                 : 
     644                 :                                 case '%':
     645              12 :                                         php_sprintf_appendchar(&result, &outpos, &size, '%' TSRMLS_CC);
     646                 : 
     647                 :                                         break;
     648                 :                                 default:
     649                 :                                         break;
     650                 :                         }
     651           68206 :                         if (multiuse) {
     652             553 :                                 zval_ptr_dtor(&tmp);
     653                 :                         }
     654           68206 :                         inpos++;
     655                 :                 }
     656                 :         }
     657                 :         
     658           41803 :         efree(args);
     659                 :         
     660                 :         /* possibly, we have to make sure we have room for the terminating null? */
     661           41803 :         result[outpos]=0;
     662           41803 :         *len = outpos;  
     663           41803 :         return result;
     664                 : }
     665                 : /* }}} */
     666                 : 
     667                 : /* {{{ proto string sprintf(string format [, mixed arg1 [, mixed ...]])
     668                 :    Return a formatted string */
     669                 : PHP_FUNCTION(user_sprintf)
     670           29941 : {
     671                 :         char *result;
     672                 :         int len;
     673                 :         
     674           29941 :         if ((result=php_formatted_print(ht, &len, 0, 0 TSRMLS_CC))==NULL) {
     675               7 :                 RETURN_FALSE;
     676                 :         }
     677           29934 :         RETVAL_STRINGL(result, len, 0);
     678                 : }
     679                 : /* }}} */
     680                 : 
     681                 : /* {{{ proto string vsprintf(string format, array args)
     682                 :    Return a formatted string */
     683                 : PHP_FUNCTION(vsprintf)
     684             204 : {
     685                 :         char *result;
     686                 :         int len;
     687                 :         
     688             204 :         if ((result=php_formatted_print(ht, &len, 1, 0 TSRMLS_CC))==NULL) {
     689               8 :                 RETURN_FALSE;
     690                 :         }
     691             196 :         RETVAL_STRINGL(result, len, 0);
     692                 : }
     693                 : /* }}} */
     694                 : 
     695                 : /* {{{ proto int printf(string format [, mixed arg1 [, mixed ...]])
     696                 :    Output a formatted string */
     697                 : PHP_FUNCTION(user_printf)
     698            9546 : {
     699                 :         char *result;
     700                 :         int len, rlen;
     701                 :         
     702            9546 :         if ((result=php_formatted_print(ht, &len, 0, 0 TSRMLS_CC))==NULL) {
     703              10 :                 RETURN_FALSE;
     704                 :         }
     705            9536 :         rlen = PHPWRITE(result, len);
     706            9536 :         efree(result);
     707            9536 :         RETURN_LONG(rlen);
     708                 : }
     709                 : /* }}} */
     710                 : 
     711                 : /* {{{ proto int vprintf(string format, array args)
     712                 :    Output a formatted string */
     713                 : PHP_FUNCTION(vprintf)
     714             189 : {
     715                 :         char *result;
     716                 :         int len, rlen;
     717                 :         
     718             189 :         if ((result=php_formatted_print(ht, &len, 1, 0 TSRMLS_CC))==NULL) {
     719               8 :                 RETURN_FALSE;
     720                 :         }
     721             181 :         rlen = PHPWRITE(result, len);
     722             181 :         efree(result);
     723             181 :         RETURN_LONG(rlen);
     724                 : }
     725                 : /* }}} */
     726                 : 
     727                 : /* {{{ proto int fprintf(resource stream, string format [, mixed arg1 [, mixed ...]])
     728                 :    Output a formatted string into a stream */
     729                 : PHP_FUNCTION(fprintf)
     730            1763 : {
     731                 :         php_stream *stream;
     732                 :         zval *arg1;
     733                 :         char *result;
     734                 :         int len;
     735                 :         
     736            1763 :         if (ZEND_NUM_ARGS() < 2) {
     737               3 :                 WRONG_PARAM_COUNT;
     738                 :         }
     739                 :         
     740            1760 :         if (zend_parse_parameters(1 TSRMLS_CC, "r", &arg1) == FAILURE) {
     741               0 :                 RETURN_FALSE;
     742                 :         }
     743                 :         
     744            1760 :         php_stream_from_zval(stream, &arg1);
     745                 : 
     746            1760 :         if ((result=php_formatted_print(ht, &len, 0, 1 TSRMLS_CC))==NULL) {
     747               1 :                 RETURN_FALSE;
     748                 :         }
     749                 : 
     750            1759 :         php_stream_write(stream, result, len);
     751                 : 
     752            1759 :         efree(result);
     753                 : 
     754            1759 :         RETURN_LONG(len);
     755                 : }
     756                 : /* }}} */
     757                 : 
     758                 : /* {{{ proto int vfprintf(resource stream, string format, array args)
     759                 :    Output a formatted string into a stream */
     760                 : PHP_FUNCTION(vfprintf)
     761             211 : {
     762                 :         php_stream *stream;
     763                 :         zval *arg1;
     764                 :         char *result;
     765                 :         int len;
     766                 :         
     767             211 :         if (ZEND_NUM_ARGS() != 3) {
     768               5 :                 WRONG_PARAM_COUNT;
     769                 :         }
     770                 :         
     771             206 :         if (zend_parse_parameters(1 TSRMLS_CC, "r", &arg1) == FAILURE) {
     772               3 :                 RETURN_FALSE;
     773                 :         }
     774                 :         
     775             203 :         php_stream_from_zval(stream, &arg1);
     776                 : 
     777             203 :         if ((result=php_formatted_print(ht, &len, 1, 1 TSRMLS_CC))==NULL) {
     778               6 :                 RETURN_FALSE;
     779                 :         }
     780                 : 
     781             197 :         php_stream_write(stream, result, len);
     782                 : 
     783             197 :         efree(result);
     784                 : 
     785             197 :         RETURN_LONG(len);
     786                 : }
     787                 : /* }}} */
     788                 : 
     789                 : /*
     790                 :  * Local variables:
     791                 :  * tab-width: 4
     792                 :  * c-basic-offset: 4
     793                 :  * End:
     794                 :  * vim600: sw=4 ts=4 fdm=marker
     795                 :  * vim<600: sw=4 ts=4
     796                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Sat, 21 Nov 2009 12:27:10 +0000 (3 days ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.