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: 272 294 92.5 %
Date: 2014-09-19 Functions: 14 14 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Fri, 19 Sep 2014 17:11:18 +0000 (44 hours ago)

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