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

LCOV - code coverage report
Current view: top level - ext/standard - formatted_print.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 273 295 92.5 %
Date: 2015-08-29 Functions: 14 14 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 7                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2015 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$ */
      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             : #ifdef ZTS
      31             : #include "ext/standard/php_string.h"
      32             : #define LCONV_DECIMAL_POINT (*lconv.decimal_point)
      33             : #else
      34             : #define LCONV_DECIMAL_POINT (*lconv->decimal_point)
      35             : #endif
      36             : #else
      37             : #define LCONV_DECIMAL_POINT '.'
      38             : #endif
      39             : 
      40             : #define ALIGN_LEFT 0
      41             : #define ALIGN_RIGHT 1
      42             : #define ADJ_WIDTH 1
      43             : #define ADJ_PRECISION 2
      44             : #define NUM_BUF_SIZE 500
      45             : #define FLOAT_PRECISION 6
      46             : #define MAX_FLOAT_PRECISION 53
      47             : 
      48             : #if 0
      49             : /* trick to control varargs functions through cpp */
      50             : # define PRINTF_DEBUG(arg) php_printf arg
      51             : #else
      52             : # define PRINTF_DEBUG(arg)
      53             : #endif
      54             : 
      55             : static char hexchars[] = "0123456789abcdef";
      56             : static char HEXCHARS[] = "0123456789ABCDEF";
      57             : 
      58             : /* php_spintf_appendchar() {{{ */
      59             : inline static void
      60     1231732 : php_sprintf_appendchar(zend_string **buffer, size_t *pos, char add)
      61             : {
      62     1231732 :         if (!*buffer || (*pos + 1) >= ZSTR_LEN(*buffer)) {
      63             :                 PRINTF_DEBUG(("%s(): ereallocing buffer to %d bytes\n", get_active_function_name(), ZSTR_LEN(*buffer)));
      64           0 :                 *buffer = zend_string_extend(*buffer, ZSTR_LEN(*buffer) << 1, 0);
      65             :         }
      66             :         PRINTF_DEBUG(("sprintf: appending '%c', pos=\n", add, *pos));
      67     1231732 :         ZSTR_VAL(*buffer)[(*pos)++] = add;
      68     1231732 : }
      69             : /* }}} */
      70             : 
      71             : /* php_spintf_appendstring() {{{ */
      72             : inline static void
      73      102374 : php_sprintf_appendstring(zend_string **buffer, size_t *pos, char *add,
      74             :                                                    size_t min_width, size_t max_width, char padding,
      75             :                                                    size_t alignment, size_t len, int neg, int expprec, int always_sign)
      76             : {
      77             :         register size_t npad;
      78             :         size_t req_size;
      79             :         size_t copy_len;
      80             :         size_t m_width;
      81             : 
      82      102374 :         copy_len = (expprec ? MIN(max_width, len) : len);
      83      102374 :         npad = (min_width < copy_len) ? 0 : min_width - copy_len;
      84             : 
      85             :         PRINTF_DEBUG(("sprintf: appendstring(%x, %d, %d, \"%s\", %d, '%c', %d)\n",
      86             :                                   *buffer, *pos, ZSTR_LEN(*buffer), add, min_width, padding, alignment));
      87      102374 :         m_width = MAX(min_width, copy_len);
      88             : 
      89      102374 :         if(m_width > INT_MAX - *pos - 1) {
      90           0 :                 zend_error_noreturn(E_ERROR, "Field width %d is too long", m_width);
      91             :         }
      92             : 
      93      102374 :         req_size = *pos + m_width + 1;
      94             : 
      95      102374 :         if (!*buffer || req_size > ZSTR_LEN(*buffer)) {
      96       12077 :                 size_t size = ZSTR_LEN(*buffer);
      97       36236 :                 while (req_size > size) {
      98       12082 :                         if (size > ZEND_SIZE_MAX/2) {
      99           0 :                                 zend_error_noreturn(E_ERROR, "Field width %zd is too long", req_size);
     100             :                         }
     101       12082 :                         size <<= 1;
     102             :                 }
     103             :                 PRINTF_DEBUG(("sprintf ereallocing buffer to %d bytes\n", size));
     104       24154 :                 *buffer = zend_string_extend(*buffer, size, 0);
     105             :         }
     106      102374 :         if (alignment == ALIGN_RIGHT) {
     107      100962 :                 if ((neg || always_sign) && padding=='0') {
     108          36 :                         ZSTR_VAL(*buffer)[(*pos)++] = (neg) ? '-' : '+';
     109          36 :                         add++;
     110          36 :                         len--;
     111          36 :                         copy_len--;
     112             :                 }
     113      228431 :                 while (npad-- > 0) {
     114       26507 :                         ZSTR_VAL(*buffer)[(*pos)++] = padding;
     115             :                 }
     116             :         }
     117             :         PRINTF_DEBUG(("sprintf: appending \"%s\"\n", add));
     118      102374 :         memcpy(&ZSTR_VAL(*buffer)[*pos], add, copy_len + 1);
     119      102374 :         *pos += copy_len;
     120      102374 :         if (alignment == ALIGN_LEFT) {
     121        6816 :                 while (npad--) {
     122        3992 :                         ZSTR_VAL(*buffer)[(*pos)++] = padding;
     123             :                 }
     124             :         }
     125      102374 : }
     126             : /* }}} */
     127             : 
     128             : /* php_spintf_appendint() {{{ */
     129             : inline static void
     130       37788 : php_sprintf_appendint(zend_string **buffer, size_t *pos, zend_long number,
     131             :                                                 size_t width, char padding, size_t alignment,
     132             :                                                 int always_sign)
     133             : {
     134             :         char numbuf[NUM_BUF_SIZE];
     135             :         register zend_ulong magn, nmagn;
     136       37788 :         register unsigned int i = NUM_BUF_SIZE - 1, neg = 0;
     137             : 
     138             :         PRINTF_DEBUG(("sprintf: appendint(%x, %x, %x, %d, %d, '%c', %d)\n",
     139             :                                   *buffer, pos, &ZSTR_LEN(*buffer), number, width, padding, alignment));
     140       37788 :         if (number < 0) {
     141         698 :                 neg = 1;
     142         698 :                 magn = ((zend_ulong) -(number + 1)) + 1;
     143             :         } else {
     144       37090 :                 magn = (zend_ulong) number;
     145             :         }
     146             : 
     147             :         /* Can't right-pad 0's on integers */
     148       37788 :         if(alignment==0 && padding=='0') padding=' ';
     149             : 
     150       37788 :         numbuf[i] = '\0';
     151             : 
     152             :         do {
     153      130693 :                 nmagn = magn / 10;
     154             : 
     155      130693 :                 numbuf[--i] = (unsigned char)(magn - (nmagn * 10)) + '0';
     156      130693 :                 magn = nmagn;
     157             :         }
     158      130693 :         while (magn > 0 && i > 1);
     159       37788 :         if (neg) {
     160         698 :                 numbuf[--i] = '-';
     161       37090 :         } else if (always_sign) {
     162          36 :                 numbuf[--i] = '+';
     163             :         }
     164             :         PRINTF_DEBUG(("sprintf: appending %d as \"%s\", i=%d\n",
     165             :                                   number, &numbuf[i], i));
     166       75576 :         php_sprintf_appendstring(buffer, pos, &numbuf[i], width, 0,
     167       37788 :                                                          padding, alignment, (NUM_BUF_SIZE - 1) - i,
     168             :                                                          neg, 0, always_sign);
     169       37788 : }
     170             : /* }}} */
     171             : 
     172             : /* php_spintf_appenduint() {{{ */
     173             : inline static void
     174         921 : php_sprintf_appenduint(zend_string **buffer, size_t *pos,
     175             :                                            zend_ulong number,
     176             :                                            size_t width, char padding, size_t alignment)
     177             : {
     178             :         char numbuf[NUM_BUF_SIZE];
     179             :         register zend_ulong magn, nmagn;
     180         921 :         register unsigned int i = NUM_BUF_SIZE - 1;
     181             : 
     182             :         PRINTF_DEBUG(("sprintf: appenduint(%x, %x, %x, %d, %d, '%c', %d)\n",
     183             :                                   *buffer, pos, &ZSTR_LEN(*buffer), number, width, padding, alignment));
     184         921 :         magn = (zend_ulong) number;
     185             : 
     186             :         /* Can't right-pad 0's on integers */
     187         921 :         if (alignment == 0 && padding == '0') padding = ' ';
     188             : 
     189         921 :         numbuf[i] = '\0';
     190             : 
     191             :         do {
     192        4555 :                 nmagn = magn / 10;
     193             : 
     194        4555 :                 numbuf[--i] = (unsigned char)(magn - (nmagn * 10)) + '0';
     195        4555 :                 magn = nmagn;
     196        4555 :         } while (magn > 0 && i > 0);
     197             : 
     198             :         PRINTF_DEBUG(("sprintf: appending %d as \"%s\", i=%d\n", number, &numbuf[i], i));
     199         921 :         php_sprintf_appendstring(buffer, pos, &numbuf[i], width, 0,
     200         921 :                                                          padding, alignment, (NUM_BUF_SIZE - 1) - i, 0, 0, 0);
     201         921 : }
     202             : /* }}} */
     203             : 
     204             : /* php_spintf_appenddouble() {{{ */
     205             : inline static void
     206        3806 : php_sprintf_appenddouble(zend_string **buffer, size_t *pos,
     207             :                                                  double number,
     208             :                                                  size_t width, char padding,
     209             :                                                  size_t alignment, int precision,
     210             :                                                  int adjust, char fmt,
     211             :                                                  int always_sign
     212             :                                                 )
     213             : {
     214             :         char num_buf[NUM_BUF_SIZE];
     215        3806 :         char *s = NULL;
     216        3806 :         size_t s_len = 0;
     217        3806 :         int is_negative = 0;
     218             : #ifdef HAVE_LOCALE_H
     219             : #ifdef ZTS
     220             :         struct lconv lconv;
     221             : #else
     222             :         struct lconv *lconv;
     223             : #endif
     224             : #endif
     225             : 
     226             :         PRINTF_DEBUG(("sprintf: appenddouble(%x, %x, %x, %f, %d, '%c', %d, %c)\n",
     227             :                                   *buffer, pos, &ZSTR_LEN(*buffer), number, width, padding, alignment, fmt));
     228        3806 :         if ((adjust & ADJ_PRECISION) == 0) {
     229        3474 :                 precision = FLOAT_PRECISION;
     230         332 :         } else if (precision > MAX_FLOAT_PRECISION) {
     231           2 :                 php_error_docref(NULL, E_NOTICE, "Requested precision of %d digits was truncated to PHP maximum of %d digits", precision, MAX_FLOAT_PRECISION);
     232           2 :                 precision = MAX_FLOAT_PRECISION;
     233             :         }
     234             : 
     235        3806 :         if (zend_isnan(number)) {
     236          40 :                 is_negative = (number<0);
     237          40 :                 php_sprintf_appendstring(buffer, pos, "NaN", 3, 0, padding,
     238             :                                                                  alignment, 3, is_negative, 0, always_sign);
     239          40 :                 return;
     240             :         }
     241             : 
     242        3766 :         if (zend_isinf(number)) {
     243           0 :                 is_negative = (number<0);
     244           0 :                 php_sprintf_appendstring(buffer, pos, "INF", 3, 0, padding,
     245             :                                                                  alignment, 3, is_negative, 0, always_sign);
     246           0 :                 return;
     247             :         }
     248             : 
     249        3766 :         switch (fmt) {
     250             :                 case 'e':
     251             :                 case 'E':
     252             :                 case 'f':
     253             :                 case 'F':
     254             : #ifdef HAVE_LOCALE_H
     255             : #ifdef ZTS
     256             :                         localeconv_r(&lconv);
     257             : #else
     258        3742 :                         lconv = localeconv();
     259             : #endif
     260             : #endif
     261        6450 :                         s = php_conv_fp((fmt == 'f')?'F':fmt, number, 0, precision,
     262        2708 :                                                 (fmt == 'f')?LCONV_DECIMAL_POINT:'.',
     263             :                                                 &is_negative, &num_buf[1], &s_len);
     264        3742 :                         if (is_negative) {
     265         845 :                                 num_buf[0] = '-';
     266         845 :                                 s = num_buf;
     267         845 :                                 s_len++;
     268        2897 :                         } else if (always_sign) {
     269          36 :                                 num_buf[0] = '+';
     270          36 :                                 s = num_buf;
     271          36 :                                 s_len++;
     272             :                         }
     273        3742 :                         break;
     274             : 
     275             :                 case 'g':
     276             :                 case 'G':
     277          24 :                         if (precision == 0)
     278           4 :                                 precision = 1;
     279             :                         /*
     280             :                          * * We use &num_buf[ 1 ], so that we have room for the sign
     281             :                          */
     282             : #ifdef HAVE_LOCALE_H
     283             : #ifdef ZTS
     284             :                         localeconv_r(&lconv);
     285             : #else
     286          24 :                         lconv = localeconv();
     287             : #endif
     288             : #endif
     289          24 :                         s = php_gcvt(number, precision, LCONV_DECIMAL_POINT, (fmt == 'G')?'E':'e', &num_buf[1]);
     290          24 :                         is_negative = 0;
     291          24 :                         if (*s == '-') {
     292          12 :                                 is_negative = 1;
     293          12 :                                 s = &num_buf[1];
     294          12 :                         } else if (always_sign) {
     295           4 :                                 num_buf[0] = '+';
     296           4 :                                 s = num_buf;
     297             :                         }
     298             : 
     299          24 :                         s_len = strlen(s);
     300             :                         break;
     301             :         }
     302             : 
     303        3766 :         php_sprintf_appendstring(buffer, pos, s, width, 0, padding,
     304             :                                                          alignment, s_len, is_negative, 0, always_sign);
     305             : }
     306             : /* }}} */
     307             : 
     308             : /* php_spintf_appendd2n() {{{ */
     309             : inline static void
     310       10874 : php_sprintf_append2n(zend_string **buffer, size_t *pos, zend_long number,
     311             :                                          size_t width, char padding, size_t alignment, int n,
     312             :                                          char *chartable, int expprec)
     313             : {
     314             :         char numbuf[NUM_BUF_SIZE];
     315             :         register zend_ulong num;
     316       10874 :         register zend_ulong  i = NUM_BUF_SIZE - 1;
     317       10874 :         register int andbits = (1 << n) - 1;
     318             : 
     319             :         PRINTF_DEBUG(("sprintf: append2n(%x, %x, %x, %d, %d, '%c', %d, %d, %x)\n",
     320             :                                   *buffer, pos, &ZSTR_LEN(*buffer), number, width, padding, alignment, n,
     321             :                                   chartable));
     322             :         PRINTF_DEBUG(("sprintf: append2n 2^%d andbits=%x\n", n, andbits));
     323             : 
     324       10874 :         num = (zend_ulong) number;
     325       10874 :         numbuf[i] = '\0';
     326             : 
     327             :         do {
     328       40611 :                 numbuf[--i] = chartable[(num & andbits)];
     329       40611 :                 num >>= n;
     330             :         }
     331       40611 :         while (num > 0);
     332             : 
     333       10874 :         php_sprintf_appendstring(buffer, pos, &numbuf[i], width, 0,
     334             :                                                          padding, alignment, (NUM_BUF_SIZE - 1) - i,
     335             :                                                          0, expprec, 0);
     336       10874 : }
     337             : /* }}} */
     338             : 
     339             : /* php_spintf_getnumber() {{{ */
     340             : inline static int
     341       15648 : php_sprintf_getnumber(char *buffer, size_t *pos)
     342             : {
     343             :         char *endptr;
     344       15648 :         register zend_long num = ZEND_STRTOL(&buffer[*pos], &endptr, 10);
     345       15648 :         register size_t i = 0;
     346             : 
     347       15648 :         if (endptr != NULL) {
     348       15648 :                 i = (endptr - &buffer[*pos]);
     349             :         }
     350             :         PRINTF_DEBUG(("sprintf_getnumber: number was %d bytes long\n", i));
     351       15648 :         *pos += i;
     352             : 
     353       15648 :         if (num >= INT_MAX || num < 0) {
     354           0 :                 return -1;
     355             :         } else {
     356       15648 :                 return (int) num;
     357             :         }
     358             : }
     359             : /* }}} */
     360             : 
     361             : /* php_formatted_print() {{{
     362             :  * New sprintf implementation for PHP.
     363             :  *
     364             :  * Modifiers:
     365             :  *
     366             :  *  " "   pad integers with spaces
     367             :  *  "-"   left adjusted field
     368             :  *   n    field size
     369             :  *  "."n  precision (floats only)
     370             :  *  "+"   Always place a sign (+ or -) in front of a number
     371             :  *
     372             :  * Type specifiers:
     373             :  *
     374             :  *  "%"   literal "%", modifiers are ignored.
     375             :  *  "b"   integer argument is printed as binary
     376             :  *  "c"   integer argument is printed as a single character
     377             :  *  "d"   argument is an integer
     378             :  *  "f"   the argument is a float
     379             :  *  "o"   integer argument is printed as octal
     380             :  *  "s"   argument is a string
     381             :  *  "x"   integer argument is printed as lowercase hexadecimal
     382             :  *  "X"   integer argument is printed as uppercase hexadecimal
     383             :  *
     384             :  */
     385             : static zend_string *
     386       63660 : php_formatted_print(zend_execute_data *execute_data, int use_array, int format_offset)
     387             : {
     388       63660 :         zval *newargs = NULL;
     389             :         zval *args, *z_format;
     390             :         int argc;
     391       63660 :         size_t size = 240, inpos = 0, outpos = 0, temppos;
     392             :         int alignment, currarg, adjusting, argnum, width, precision;
     393             :         char *format, padding;
     394             :         zend_string *result;
     395             :         int always_sign;
     396             :         size_t format_len;
     397             : 
     398             : #ifndef FAST_ZPP
     399             :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "+", &args, &argc) == FAILURE) {
     400             :                 return NULL;
     401             :         }
     402             : #else
     403       63660 :         ZEND_PARSE_PARAMETERS_START(1, -1)
     404       63655 :                 Z_PARAM_VARIADIC('+', args, argc)
     405       63660 :         ZEND_PARSE_PARAMETERS_END_EX(return NULL);
     406             : #endif
     407             : 
     408             :         /* verify the number of args */
     409      126716 :         if ((use_array && argc != (2 + format_offset))
     410       63061 :                         || (!use_array && argc < (1 + format_offset))) {
     411           4 :                 WRONG_PARAM_COUNT_WITH_RETVAL(NULL);
     412             :         }
     413             : 
     414      127851 :         convert_to_string_ex(&args[format_offset]);
     415       63651 :         if (use_array) {
     416         590 :                 int i = 1;
     417             :                 zval *zv;
     418             :                 zval *array;
     419             : 
     420         590 :                 z_format = &args[format_offset];
     421         590 :                 array = &args[1 + format_offset];
     422         590 :                 if (Z_TYPE_P(array) != IS_ARRAY) {
     423          84 :                         SEPARATE_ZVAL(array);
     424          72 :                         convert_to_array(array);
     425             :                 }
     426             : 
     427         590 :                 argc = 1 + zend_hash_num_elements(Z_ARRVAL_P(array));
     428         590 :                 newargs = (zval *)safe_emalloc(argc, sizeof(zval), 0);
     429         590 :                 ZVAL_COPY_VALUE(&newargs[0], z_format);
     430             : 
     431        7002 :                 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(array), zv) {
     432        3206 :                         ZVAL_COPY_VALUE(&newargs[i], zv);
     433        3206 :                         i++;
     434             :                 } ZEND_HASH_FOREACH_END();
     435         590 :                 args = newargs;
     436         590 :                 format_offset = 0;
     437             :         }
     438             : 
     439       63651 :         format = Z_STRVAL(args[format_offset]);
     440       63651 :         format_len = Z_STRLEN(args[format_offset]);
     441       63651 :         result = zend_string_alloc(size, 0);
     442             : 
     443       63651 :         currarg = 1;
     444             : 
     445     1463849 :         while (inpos < Z_STRLEN(args[format_offset])) {
     446     1336578 :                 int expprec = 0;
     447             :                 zval *tmp;
     448             : 
     449             :                 PRINTF_DEBUG(("sprintf: format[%d]='%c'\n", inpos, format[inpos]));
     450             :                 PRINTF_DEBUG(("sprintf: outpos=%d\n", outpos));
     451     1336578 :                 if (format[inpos] != '%') {
     452     1230678 :                         php_sprintf_appendchar(&result, &outpos, format[inpos++]);
     453      105900 :                 } else if (format[inpos + 1] == '%') {
     454          45 :                         php_sprintf_appendchar(&result, &outpos, '%');
     455          45 :                         inpos += 2;
     456             :                 } else {
     457             :                         /* starting a new format specifier, reset variables */
     458      105855 :                         alignment = ALIGN_RIGHT;
     459      105855 :                         adjusting = 0;
     460      105855 :                         padding = ' ';
     461      105855 :                         always_sign = 0;
     462      105855 :                         inpos++;                        /* skip the '%' */
     463             : 
     464             :                         PRINTF_DEBUG(("sprintf: first looking at '%c', inpos=%d\n",
     465             :                                                   format[inpos], inpos));
     466      122752 :                         if (isascii((int)format[inpos]) && !isalpha((int)format[inpos])) {
     467             :                                 /* first look for argnum */
     468       16899 :                                 temppos = inpos;
     469       16899 :                                 while (isdigit((int)format[temppos])) temppos++;
     470       16899 :                                 if (format[temppos] == '$') {
     471         555 :                                         argnum = php_sprintf_getnumber(format, &inpos);
     472             : 
     473         555 :                                         if (argnum <= 0) {
     474           2 :                                                 efree(result);
     475           2 :                                                 if (newargs) {
     476           1 :                                                         efree(newargs);
     477             :                                                 }
     478           2 :                                                 php_error_docref(NULL, E_WARNING, "Argument number must be greater than zero");
     479           2 :                                                 return NULL;
     480             :                                         }
     481             : 
     482         553 :                                         inpos++;  /* skip the '$' */
     483             :                                 } else {
     484       16344 :                                         argnum = currarg++;
     485             :                                 }
     486             : 
     487       16897 :                                 argnum += format_offset;
     488             : 
     489             :                                 /* after argnum comes modifiers */
     490             :                                 PRINTF_DEBUG(("sprintf: looking for modifiers\n"
     491             :                                                           "sprintf: now looking at '%c', inpos=%d\n",
     492             :                                                           format[inpos], inpos));
     493       12109 :                                 for (;; inpos++) {
     494       38890 :                                         if (format[inpos] == ' ' || format[inpos] == '0') {
     495        9884 :                                                 padding = format[inpos];
     496       19122 :                                         } else if (format[inpos] == '-') {
     497        1466 :                                                 alignment = ALIGN_LEFT;
     498             :                                                 /* space padding, the default */
     499       17656 :                                         } else if (format[inpos] == '+') {
     500         202 :                                                 always_sign = 1;
     501       17454 :                                         } else if (format[inpos] == '\'' && inpos+1<format_len) {
     502         557 :                                                 padding = format[++inpos];
     503             :                                         } else {
     504             :                                                 PRINTF_DEBUG(("sprintf: end of modifiers\n"));
     505             :                                                 break;
     506             :                                         }
     507       12109 :                                 }
     508             :                                 PRINTF_DEBUG(("sprintf: padding='%c'\n", padding));
     509             :                                 PRINTF_DEBUG(("sprintf: alignment=%s\n",
     510             :                                                           (alignment == ALIGN_LEFT) ? "left" : "right"));
     511             : 
     512             : 
     513             :                                 /* after modifiers comes width */
     514       16897 :                                 if (isdigit((int)format[inpos])) {
     515             :                                         PRINTF_DEBUG(("sprintf: getting width\n"));
     516       14366 :                                         if ((width = php_sprintf_getnumber(format, &inpos)) < 0) {
     517           0 :                                                 efree(result);
     518           0 :                                                 if (newargs) {
     519           0 :                                                         efree(newargs);
     520             :                                                 }
     521           0 :                                                 php_error_docref(NULL, E_WARNING, "Width must be greater than zero and less than %d", INT_MAX);
     522           0 :                                                 if (newargs) {
     523           0 :                                                         efree(newargs);
     524             :                                                 }
     525           0 :                                                 return NULL;
     526             :                                         }
     527       14366 :                                         adjusting |= ADJ_WIDTH;
     528             :                                 } else {
     529        2531 :                                         width = 0;
     530             :                                 }
     531             :                                 PRINTF_DEBUG(("sprintf: width=%d\n", width));
     532             : 
     533             :                                 /* after width and argnum comes precision */
     534       16897 :                                 if (format[inpos] == '.') {
     535         729 :                                         inpos++;
     536             :                                         PRINTF_DEBUG(("sprintf: getting precision\n"));
     537         729 :                                         if (isdigit((int)format[inpos])) {
     538         727 :                                                 if ((precision = php_sprintf_getnumber(format, &inpos)) < 0) {
     539           0 :                                                         efree(result);
     540           0 :                                                         if (newargs) {
     541           0 :                                                                 efree(newargs);
     542             :                                                         }
     543           0 :                                                         php_error_docref(NULL, E_WARNING, "Precision must be greater than zero and less than %d", INT_MAX);
     544           0 :                                                         if (newargs) {
     545           0 :                                                                 efree(newargs);
     546             :                                                         }
     547           0 :                                                         return NULL;
     548             :                                                 }
     549         727 :                                                 adjusting |= ADJ_PRECISION;
     550         727 :                                                 expprec = 1;
     551             :                                         } else {
     552           2 :                                                 precision = 0;
     553             :                                         }
     554             :                                 } else {
     555       16168 :                                         precision = 0;
     556             :                                 }
     557             :                                 PRINTF_DEBUG(("sprintf: precision=%d\n", precision));
     558             :                         } else {
     559       88956 :                                 width = precision = 0;
     560       88956 :                                 argnum = currarg++ + format_offset;
     561             :                         }
     562             : 
     563      105853 :                         if (argnum >= argc) {
     564          29 :                                 efree(result);
     565          29 :                                 if (newargs) {
     566          15 :                                         efree(newargs);
     567             :                                 }
     568          29 :                                 php_error_docref(NULL, E_WARNING, "Too few arguments");
     569          29 :                                 return NULL;
     570             :                         }
     571             : 
     572      105824 :                         if (format[inpos] == 'l') {
     573        1711 :                                 inpos++;
     574             :                         }
     575             :                         PRINTF_DEBUG(("sprintf: format character='%c'\n", format[inpos]));
     576             :                         /* now we expect to find a type specifier */
     577      105824 :                         tmp = &args[argnum];
     578      105824 :                         switch (format[inpos]) {
     579             :                                 case 's': {
     580       48985 :                                         zend_string *str = zval_get_string(tmp);
     581       48985 :                                         php_sprintf_appendstring(&result, &outpos,
     582             :                                                                                          ZSTR_VAL(str),
     583             :                                                                                          width, precision, padding,
     584             :                                                                                          alignment,
     585             :                                                                                          ZSTR_LEN(str),
     586             :                                                                                          0, expprec, 0);
     587             :                                         zend_string_release(str);
     588       48985 :                                         break;
     589             :                                 }
     590             : 
     591             :                                 case 'd':
     592       75576 :                                         php_sprintf_appendint(&result, &outpos,
     593             :                                                                                   zval_get_long(tmp),
     594             :                                                                                   width, padding, alignment,
     595             :                                                                                   always_sign);
     596       37788 :                                         break;
     597             : 
     598             :                                 case 'u':
     599        1842 :                                         php_sprintf_appenduint(&result, &outpos,
     600             :                                                                                   zval_get_long(tmp),
     601             :                                                                                   width, padding, alignment);
     602         921 :                                         break;
     603             : 
     604             :                                 case 'g':
     605             :                                 case 'G':
     606             :                                 case 'e':
     607             :                                 case 'E':
     608             :                                 case 'f':
     609             :                                 case 'F':
     610        7612 :                                         php_sprintf_appenddouble(&result, &outpos,
     611             :                                                                                          zval_get_double(tmp),
     612             :                                                                                          width, padding, alignment,
     613             :                                                                                          precision, adjusting,
     614        3806 :                                                                                          format[inpos], always_sign
     615             :                                                                                         );
     616        3806 :                                         break;
     617             : 
     618             :                                 case 'c':
     619         997 :                                         php_sprintf_appendchar(&result, &outpos,
     620         997 :                                                                                 (char) zval_get_long(tmp));
     621         997 :                                         break;
     622             : 
     623             :                                 case 'o':
     624        8096 :                                         php_sprintf_append2n(&result, &outpos,
     625             :                                                                                  zval_get_long(tmp),
     626             :                                                                                  width, padding, alignment, 3,
     627             :                                                                                  hexchars, expprec);
     628        4048 :                                         break;
     629             : 
     630             :                                 case 'x':
     631        5756 :                                         php_sprintf_append2n(&result, &outpos,
     632             :                                                                                  zval_get_long(tmp),
     633             :                                                                                  width, padding, alignment, 4,
     634             :                                                                                  hexchars, expprec);
     635        2878 :                                         break;
     636             : 
     637             :                                 case 'X':
     638        7762 :                                         php_sprintf_append2n(&result, &outpos,
     639             :                                                                                  zval_get_long(tmp),
     640             :                                                                                  width, padding, alignment, 4,
     641             :                                                                                  HEXCHARS, expprec);
     642        3881 :                                         break;
     643             : 
     644             :                                 case 'b':
     645         134 :                                         php_sprintf_append2n(&result, &outpos,
     646             :                                                                                  zval_get_long(tmp),
     647             :                                                                                  width, padding, alignment, 1,
     648             :                                                                                  hexchars, expprec);
     649          67 :                                         break;
     650             : 
     651             :                                 case '%':
     652          12 :                                         php_sprintf_appendchar(&result, &outpos, '%');
     653             : 
     654             :                                         break;
     655             :                                 default:
     656             :                                         break;
     657             :                         }
     658      105824 :                         inpos++;
     659             :                 }
     660             :         }
     661             : 
     662       63620 :         if (newargs) {
     663         574 :                 efree(newargs);
     664             :         }
     665             : 
     666             :         /* possibly, we have to make sure we have room for the terminating null? */
     667       63620 :         ZSTR_VAL(result)[outpos]=0;
     668       63620 :         ZSTR_LEN(result) = outpos;
     669       63620 :         return result;
     670             : }
     671             : /* }}} */
     672             : 
     673             : /* {{{ proto string sprintf(string format [, mixed arg1 [, mixed ...]])
     674             :    Return a formatted string */
     675       49276 : PHP_FUNCTION(user_sprintf)
     676             : {
     677             :         zend_string *result;
     678             : 
     679       49276 :         if ((result=php_formatted_print(execute_data, 0, 0))==NULL) {
     680           7 :                 RETURN_FALSE;
     681             :         }
     682       49269 :         RETVAL_STR(result);
     683             : }
     684             : /* }}} */
     685             : 
     686             : /* {{{ proto string vsprintf(string format, array args)
     687             :    Return a formatted string */
     688         204 : PHP_FUNCTION(vsprintf)
     689             : {
     690             :         zend_string *result;
     691             : 
     692         204 :         if ((result=php_formatted_print(execute_data, 1, 0))==NULL) {
     693           8 :                 RETURN_FALSE;
     694             :         }
     695         196 :         RETVAL_STR(result);
     696             : }
     697             : /* }}} */
     698             : 
     699             : /* {{{ proto int printf(string format [, mixed arg1 [, mixed ...]])
     700             :    Output a formatted string */
     701       12250 : PHP_FUNCTION(user_printf)
     702             : {
     703             :         zend_string *result;
     704             :         size_t rlen;
     705             : 
     706       12250 :         if ((result=php_formatted_print(execute_data, 0, 0))==NULL) {
     707          10 :                 RETURN_FALSE;
     708             :         }
     709       12240 :         rlen = PHPWRITE(ZSTR_VAL(result), ZSTR_LEN(result));
     710             :         zend_string_free(result);
     711       12240 :         RETURN_LONG(rlen);
     712             : }
     713             : /* }}} */
     714             : 
     715             : /* {{{ proto int vprintf(string format, array args)
     716             :    Output a formatted string */
     717         189 : PHP_FUNCTION(vprintf)
     718             : {
     719             :         zend_string *result;
     720             :         size_t rlen;
     721             : 
     722         189 :         if ((result=php_formatted_print(execute_data, 1, 0))==NULL) {
     723           8 :                 RETURN_FALSE;
     724             :         }
     725         181 :         rlen = PHPWRITE(ZSTR_VAL(result), ZSTR_LEN(result));
     726             :         zend_string_free(result);
     727         181 :         RETURN_LONG(rlen);
     728             : }
     729             : /* }}} */
     730             : 
     731             : /* {{{ proto int fprintf(resource stream, string format [, mixed arg1 [, mixed ...]])
     732             :    Output a formatted string into a stream */
     733        1541 : PHP_FUNCTION(fprintf)
     734             : {
     735             :         php_stream *stream;
     736             :         zval *arg1;
     737             :         zend_string *result;
     738             : 
     739        1541 :         if (ZEND_NUM_ARGS() < 2) {
     740           3 :                 WRONG_PARAM_COUNT;
     741             :         }
     742             : 
     743        1538 :         if (zend_parse_parameters(1, "r", &arg1) == FAILURE) {
     744           0 :                 RETURN_FALSE;
     745             :         }
     746             : 
     747        1538 :         php_stream_from_zval(stream, arg1);
     748             : 
     749        1538 :         if ((result=php_formatted_print(execute_data, 0, 1))==NULL) {
     750           1 :                 RETURN_FALSE;
     751             :         }
     752             : 
     753        1537 :         php_stream_write(stream, ZSTR_VAL(result), ZSTR_LEN(result));
     754             : 
     755        1537 :         RETVAL_LONG(ZSTR_LEN(result));
     756             :         zend_string_free(result);
     757             : }
     758             : /* }}} */
     759             : 
     760             : /* {{{ proto int vfprintf(resource stream, string format, array args)
     761             :    Output a formatted string into a stream */
     762         211 : PHP_FUNCTION(vfprintf)
     763             : {
     764             :         php_stream *stream;
     765             :         zval *arg1;
     766             :         zend_string *result;
     767             : 
     768         211 :         if (ZEND_NUM_ARGS() != 3) {
     769           5 :                 WRONG_PARAM_COUNT;
     770             :         }
     771             : 
     772         206 :         if (zend_parse_parameters(1, "r", &arg1) == FAILURE) {
     773           3 :                 RETURN_FALSE;
     774             :         }
     775             : 
     776         203 :         php_stream_from_zval(stream, arg1);
     777             : 
     778         203 :         if ((result=php_formatted_print(execute_data, 1, 1))==NULL) {
     779           6 :                 RETURN_FALSE;
     780             :         }
     781             : 
     782         197 :         php_stream_write(stream, ZSTR_VAL(result), ZSTR_LEN(result));
     783             : 
     784         197 :         RETVAL_LONG(ZSTR_LEN(result));
     785             :         zend_string_free(result);
     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: LCOV version 1.10

Generated at Sat, 29 Aug 2015 10:22:25 +0000 (2 days ago)

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