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: 302 319 94.7 %
Date: 2014-11-25 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     1277392 : php_sprintf_appendchar(char **buffer, int *pos, int *size, char add TSRMLS_DC)
      56             : {
      57     1277392 :         if ((*pos + 1) >= *size) {
      58           0 :                 *size <<= 1;
      59             :                 PRINTF_DEBUG(("%s(): ereallocing buffer to %d bytes\n", get_active_function_name(TSRMLS_C), *size));
      60           0 :                 *buffer = erealloc(*buffer, *size);
      61             :         }
      62             :         PRINTF_DEBUG(("sprintf: appending '%c', pos=\n", add, *pos));
      63     1277392 :         (*buffer)[(*pos)++] = add;
      64     1277392 : }
      65             : /* }}} */
      66             : 
      67             : /* php_spintf_appendstring() {{{ */
      68             : inline static void
      69       97308 : php_sprintf_appendstring(char **buffer, int *pos, int *size, char *add,
      70             :                                                    int min_width, int max_width, char padding,
      71             :                                                    int alignment, int len, int neg, int expprec, int always_sign)
      72             : {
      73             :         register int npad;
      74             :         int req_size;
      75             :         int copy_len;
      76             :         int m_width;
      77             : 
      78       97308 :         copy_len = (expprec ? MIN(max_width, len) : len);
      79       97308 :         npad = min_width - copy_len;
      80             : 
      81       97308 :         if (npad < 0) {
      82       83682 :                 npad = 0;
      83             :         }
      84             :         
      85             :         PRINTF_DEBUG(("sprintf: appendstring(%x, %d, %d, \"%s\", %d, '%c', %d)\n",
      86             :                                   *buffer, *pos, *size, add, min_width, padding, alignment));
      87       97308 :         m_width = MAX(min_width, copy_len);
      88             : 
      89       97308 :         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       97308 :         req_size = *pos + m_width + 1;
      94             : 
      95       97308 :         if (req_size > *size) {
      96       36249 :                 while (req_size > *size) {
      97       12091 :                         if(*size > INT_MAX/2) {
      98           0 :                                 zend_error_noreturn(E_ERROR, "Field width %d is too long", req_size); 
      99             :                         }
     100       12091 :                         *size <<= 1;
     101             :                 }
     102             :                 PRINTF_DEBUG(("sprintf ereallocing buffer to %d bytes\n", *size));
     103       12079 :                 *buffer = erealloc(*buffer, *size);
     104             :         }
     105       97308 :         if (alignment == ALIGN_RIGHT) {
     106       95937 :                 if ((neg || always_sign) && padding=='0') {
     107          36 :                         (*buffer)[(*pos)++] = (neg) ? '-' : '+';
     108          36 :                         add++;
     109          36 :                         len--;
     110          36 :                         copy_len--;
     111             :                 }
     112      218899 :                 while (npad-- > 0) {
     113       27025 :                         (*buffer)[(*pos)++] = padding;
     114             :                 }
     115             :         }
     116             :         PRINTF_DEBUG(("sprintf: appending \"%s\"\n", add));
     117       97308 :         memcpy(&(*buffer)[*pos], add, copy_len + 1);
     118       97308 :         *pos += copy_len;
     119       97308 :         if (alignment == ALIGN_LEFT) {
     120        6503 :                 while (npad--) {
     121        3761 :                         (*buffer)[(*pos)++] = padding;
     122             :                 }
     123             :         }
     124       97308 : }
     125             : /* }}} */
     126             : 
     127             : /* php_spintf_appendint() {{{ */
     128             : inline static void
     129       35725 : php_sprintf_appendint(char **buffer, int *pos, int *size, long number,
     130             :                                                 int width, char padding, int alignment, 
     131             :                                                 int always_sign)
     132             : {
     133             :         char numbuf[NUM_BUF_SIZE];
     134             :         register unsigned long magn, nmagn;
     135       35725 :         register unsigned int i = NUM_BUF_SIZE - 1, neg = 0;
     136             : 
     137             :         PRINTF_DEBUG(("sprintf: appendint(%x, %x, %x, %d, %d, '%c', %d)\n",
     138             :                                   *buffer, pos, size, number, width, padding, alignment));
     139       35725 :         if (number < 0) {
     140         663 :                 neg = 1;
     141         663 :                 magn = ((unsigned long) -(number + 1)) + 1;
     142             :         } else {
     143       35062 :                 magn = (unsigned long) number;
     144             :         }
     145             : 
     146             :         /* Can't right-pad 0's on integers */
     147       35725 :         if(alignment==0 && padding=='0') padding=' ';
     148             : 
     149       35725 :         numbuf[i] = '\0';
     150             : 
     151             :         do {
     152      117236 :                 nmagn = magn / 10;
     153             : 
     154      117236 :                 numbuf[--i] = (unsigned char)(magn - (nmagn * 10)) + '0';
     155      117236 :                 magn = nmagn;
     156             :         }
     157      117236 :         while (magn > 0 && i > 0);
     158       35725 :         if (neg) {
     159         663 :                 numbuf[--i] = '-';
     160       35062 :         } else if (always_sign) {
     161          24 :                 numbuf[--i] = '+';
     162             :         }
     163             :         PRINTF_DEBUG(("sprintf: appending %d as \"%s\", i=%d\n",
     164             :                                   number, &numbuf[i], i));
     165       71450 :         php_sprintf_appendstring(buffer, pos, size, &numbuf[i], width, 0,
     166       35725 :                                                          padding, alignment, (NUM_BUF_SIZE - 1) - i,
     167             :                                                          neg, 0, always_sign);
     168       35725 : }
     169             : /* }}} */
     170             : 
     171             : /* php_spintf_appenduint() {{{ */
     172             : inline static void
     173         921 : php_sprintf_appenduint(char **buffer, int *pos, int *size,
     174             :                                            unsigned long number,
     175             :                                            int width, char padding, int alignment)
     176             : {
     177             :         char numbuf[NUM_BUF_SIZE];
     178             :         register unsigned long magn, nmagn;
     179         921 :         register unsigned int i = NUM_BUF_SIZE - 1;
     180             : 
     181             :         PRINTF_DEBUG(("sprintf: appenduint(%x, %x, %x, %d, %d, '%c', %d)\n",
     182             :                                   *buffer, pos, size, number, width, padding, alignment));
     183         921 :         magn = (unsigned long) number;
     184             : 
     185             :         /* Can't right-pad 0's on integers */
     186         921 :         if (alignment == 0 && padding == '0') padding = ' ';
     187             : 
     188         921 :         numbuf[i] = '\0';
     189             : 
     190             :         do {
     191        4519 :                 nmagn = magn / 10;
     192             : 
     193        4519 :                 numbuf[--i] = (unsigned char)(magn - (nmagn * 10)) + '0';
     194        4519 :                 magn = nmagn;
     195        4519 :         } while (magn > 0 && i > 0);
     196             : 
     197             :         PRINTF_DEBUG(("sprintf: appending %d as \"%s\", i=%d\n", number, &numbuf[i], i));
     198         921 :         php_sprintf_appendstring(buffer, pos, size, &numbuf[i], width, 0,
     199         921 :                                                          padding, alignment, (NUM_BUF_SIZE - 1) - i, 0, 0, 0);
     200         921 : }
     201             : /* }}} */
     202             : 
     203             : /* php_spintf_appenddouble() {{{ */
     204             : inline static void
     205        3806 : php_sprintf_appenddouble(char **buffer, int *pos,
     206             :                                                  int *size, double number,
     207             :                                                  int width, char padding,
     208             :                                                  int alignment, int precision,
     209             :                                                  int adjust, char fmt,
     210             :                                                  int always_sign
     211             :                                                  TSRMLS_DC)
     212             : {
     213             :         char num_buf[NUM_BUF_SIZE];
     214        3806 :         char *s = NULL;
     215        3806 :         int s_len = 0, is_negative = 0;
     216             : #ifdef HAVE_LOCALE_H
     217             :         struct lconv *lconv;
     218             : #endif
     219             : 
     220             :         PRINTF_DEBUG(("sprintf: appenddouble(%x, %x, %x, %f, %d, '%c', %d, %c)\n",
     221             :                                   *buffer, pos, size, number, width, padding, alignment, fmt));
     222        3806 :         if ((adjust & ADJ_PRECISION) == 0) {
     223        3474 :                 precision = FLOAT_PRECISION;
     224         332 :         } else if (precision > MAX_FLOAT_PRECISION) {
     225           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);
     226           2 :                 precision = MAX_FLOAT_PRECISION;
     227             :         }
     228             :         
     229        3806 :         if (zend_isnan(number)) {
     230          40 :                 is_negative = (number<0);
     231          40 :                 php_sprintf_appendstring(buffer, pos, size, "NaN", 3, 0, padding,
     232             :                                                                  alignment, 3, is_negative, 0, always_sign);
     233          40 :                 return;
     234             :         }
     235             : 
     236        3766 :         if (zend_isinf(number)) {
     237           0 :                 is_negative = (number<0);
     238           0 :                 php_sprintf_appendstring(buffer, pos, size, "INF", 3, 0, padding,
     239             :                                                                  alignment, 3, is_negative, 0, always_sign);
     240           0 :                 return;
     241             :         }
     242             : 
     243        3766 :         switch (fmt) {                  
     244             :                 case 'e':
     245             :                 case 'E':
     246             :                 case 'f':
     247             :                 case 'F':
     248             : #ifdef HAVE_LOCALE_H
     249        3742 :                         lconv = localeconv();
     250             : #endif
     251        6450 :                         s = php_conv_fp((fmt == 'f')?'F':fmt, number, 0, precision,
     252        2708 :                                                 (fmt == 'f')?LCONV_DECIMAL_POINT:'.',
     253             :                                                 &is_negative, &num_buf[1], &s_len);
     254        3742 :                         if (is_negative) {
     255         852 :                                 num_buf[0] = '-';
     256         852 :                                 s = num_buf;
     257         852 :                                 s_len++;
     258        2890 :                         } else if (always_sign) {
     259          36 :                                 num_buf[0] = '+';
     260          36 :                                 s = num_buf;
     261          36 :                                 s_len++;
     262             :                         }
     263        3742 :                         break;
     264             : 
     265             :                 case 'g':
     266             :                 case 'G':
     267          24 :                         if (precision == 0)
     268           4 :                                 precision = 1;
     269             :                         /*
     270             :                          * * We use &num_buf[ 1 ], so that we have room for the sign
     271             :                          */
     272             : #ifdef HAVE_LOCALE_H
     273          24 :                         lconv = localeconv();
     274             : #endif
     275          24 :                         s = php_gcvt(number, precision, LCONV_DECIMAL_POINT, (fmt == 'G')?'E':'e', &num_buf[1]);
     276          24 :                         is_negative = 0;
     277          24 :                         if (*s == '-') {
     278          12 :                                 is_negative = 1;
     279          12 :                                 s = &num_buf[1];
     280          12 :                         } else if (always_sign) {
     281           4 :                                 num_buf[0] = '+';
     282           4 :                                 s = num_buf;
     283             :                         }
     284             : 
     285          24 :                         s_len = strlen(s);
     286             :                         break;
     287             :         }
     288             : 
     289        3766 :         php_sprintf_appendstring(buffer, pos, size, s, width, 0, padding,
     290             :                                                          alignment, s_len, is_negative, 0, always_sign);
     291             : }
     292             : /* }}} */
     293             : 
     294             : /* php_spintf_appendd2n() {{{ */
     295             : inline static void
     296       10089 : php_sprintf_append2n(char **buffer, int *pos, int *size, long number,
     297             :                                          int width, char padding, int alignment, int n,
     298             :                                          char *chartable, int expprec)
     299             : {
     300             :         char numbuf[NUM_BUF_SIZE];
     301             :         register unsigned long num;
     302       10089 :         register unsigned int  i = NUM_BUF_SIZE - 1;
     303       10089 :         register int andbits = (1 << n) - 1;
     304             : 
     305             :         PRINTF_DEBUG(("sprintf: append2n(%x, %x, %x, %d, %d, '%c', %d, %d, %x)\n",
     306             :                                   *buffer, pos, size, number, width, padding, alignment, n,
     307             :                                   chartable));
     308             :         PRINTF_DEBUG(("sprintf: append2n 2^%d andbits=%x\n", n, andbits));
     309             : 
     310       10089 :         num = (unsigned long) number;
     311       10089 :         numbuf[i] = '\0';
     312             : 
     313             :         do {
     314       37562 :                 numbuf[--i] = chartable[(num & andbits)];
     315       37562 :                 num >>= n;
     316             :         }
     317       37562 :         while (num > 0);
     318             : 
     319       10089 :         php_sprintf_appendstring(buffer, pos, size, &numbuf[i], width, 0,
     320       10089 :                                                          padding, alignment, (NUM_BUF_SIZE - 1) - i,
     321             :                                                          0, expprec, 0);
     322       10089 : }
     323             : /* }}} */
     324             : 
     325             : /* php_spintf_getnumber() {{{ */
     326             : inline static int
     327       15712 : php_sprintf_getnumber(char *buffer, int *pos)
     328             : {
     329             :         char *endptr;
     330       15712 :         register long num = strtol(&buffer[*pos], &endptr, 10);
     331       15712 :         register int i = 0;
     332             : 
     333       15712 :         if (endptr != NULL) {
     334       15712 :                 i = (endptr - &buffer[*pos]);
     335             :         }
     336             :         PRINTF_DEBUG(("sprintf_getnumber: number was %d bytes long\n", i));
     337       15712 :         *pos += i;
     338             : 
     339       15712 :         if (num >= INT_MAX || num < 0) {
     340           0 :                 return -1;
     341             :         } else {
     342       15712 :                 return (int) num;
     343             :         }
     344             : }
     345             : /* }}} */
     346             : 
     347             : /* php_formatted_print() {{{
     348             :  * New sprintf implementation for PHP.
     349             :  *
     350             :  * Modifiers:
     351             :  *
     352             :  *  " "   pad integers with spaces
     353             :  *  "-"   left adjusted field
     354             :  *   n    field size
     355             :  *  "."n  precision (floats only)
     356             :  *  "+"   Always place a sign (+ or -) in front of a number
     357             :  *
     358             :  * Type specifiers:
     359             :  *
     360             :  *  "%"   literal "%", modifiers are ignored.
     361             :  *  "b"   integer argument is printed as binary
     362             :  *  "c"   integer argument is printed as a single character
     363             :  *  "d"   argument is an integer
     364             :  *  "f"   the argument is a float
     365             :  *  "o"   integer argument is printed as octal
     366             :  *  "s"   argument is a string
     367             :  *  "x"   integer argument is printed as lowercase hexadecimal
     368             :  *  "X"   integer argument is printed as uppercase hexadecimal
     369             :  *
     370             :  */
     371             : static char *
     372      211973 : php_formatted_print(int ht, int *len, int use_array, int format_offset TSRMLS_DC)
     373             : {
     374             :         zval ***args, **z_format;
     375      211973 :         int argc, size = 240, inpos = 0, outpos = 0, temppos;
     376             :         int alignment, currarg, adjusting, argnum, width, precision;
     377             :         char *format, *result, padding;
     378             :         int always_sign;
     379             :         int format_len;
     380             : 
     381      211973 :         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      423342 :         if ((use_array && argc != (2 + format_offset)) 
     387      211374 :                         || (!use_array && argc < (1 + format_offset))) {
     388           4 :                 efree(args);
     389           4 :                 WRONG_PARAM_COUNT_WITH_RETVAL(NULL);
     390             :         }
     391             :         
     392      211964 :         if (use_array) {
     393         590 :                 int i = 1;
     394             :                 zval ***newargs;
     395             :                 zval **array;
     396             : 
     397         590 :                 z_format = args[format_offset];
     398         590 :                 array = args[1 + format_offset];
     399             :                 
     400        2340 :                 SEPARATE_ZVAL(array);
     401         806 :                 convert_to_array_ex(array);
     402             :                 
     403         590 :                 argc = 1 + zend_hash_num_elements(Z_ARRVAL_PP(array));
     404         590 :                 newargs = (zval ***)safe_emalloc(argc, sizeof(zval *), 0);
     405         590 :                 newargs[0] = z_format;
     406             :                 
     407        4386 :                 for (zend_hash_internal_pointer_reset(Z_ARRVAL_PP(array));
     408        3796 :                          zend_hash_get_current_data(Z_ARRVAL_PP(array), (void **)&newargs[i++]) == SUCCESS;
     409        3206 :                          zend_hash_move_forward(Z_ARRVAL_PP(array)));
     410             : 
     411         590 :                 efree(args);
     412         590 :                 args = newargs;
     413         590 :                 format_offset = 0;
     414             :         }
     415             :         
     416      214667 :         convert_to_string_ex(args[format_offset]);
     417      211964 :         format = Z_STRVAL_PP(args[format_offset]);
     418      211964 :         format_len = Z_STRLEN_PP(args[format_offset]);
     419      211964 :         result = emalloc(size);
     420             : 
     421      211964 :         currarg = 1;
     422             : 
     423     1801069 :         while (inpos<format_len) {
     424     1377172 :                 int expprec = 0, multiuse = 0;
     425             :                 zval *tmp;
     426             : 
     427             :                 PRINTF_DEBUG(("sprintf: format[%d]='%c'\n", inpos, format[inpos]));
     428             :                 PRINTF_DEBUG(("sprintf: outpos=%d\n", outpos));
     429     1377172 :                 if (format[inpos] != '%') {
     430     1125961 :                         php_sprintf_appendchar(&result, &outpos, &size, format[inpos++] TSRMLS_CC);
     431      251211 :                 } else if (format[inpos + 1] == '%') {
     432          46 :                         php_sprintf_appendchar(&result, &outpos, &size, '%' TSRMLS_CC);
     433          46 :                         inpos += 2;
     434             :                 } else {
     435             :                         /* starting a new format specifier, reset variables */
     436      251165 :                         alignment = ALIGN_RIGHT;
     437      251165 :                         adjusting = 0;
     438      251165 :                         padding = ' ';
     439      251165 :                         always_sign = 0;
     440      251165 :                         inpos++;                        /* skip the '%' */
     441             : 
     442             :                         PRINTF_DEBUG(("sprintf: first looking at '%c', inpos=%d\n",
     443             :                                                   format[inpos], inpos));
     444      268126 :                         if (isascii((int)format[inpos]) && !isalpha((int)format[inpos])) {
     445             :                                 /* first look for argnum */
     446       16963 :                                 temppos = inpos;
     447       16963 :                                 while (isdigit((int)format[temppos])) temppos++;
     448       16963 :                                 if (format[temppos] == '$') {
     449         555 :                                         argnum = php_sprintf_getnumber(format, &inpos);
     450             : 
     451         555 :                                         if (argnum <= 0) {
     452           2 :                                                 efree(result);
     453           2 :                                                 efree(args);
     454           2 :                                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument number must be greater than zero");
     455           2 :                                                 return NULL;
     456             :                                         }
     457             : 
     458         553 :                                         multiuse = 1;
     459         553 :                                         inpos++;  /* skip the '$' */
     460             :                                 } else {
     461       16408 :                                         argnum = currarg++;
     462             :                                 }
     463             : 
     464       16961 :                                 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       12130 :                                 for (;; inpos++) {
     471       39060 :                                         if (format[inpos] == ' ' || format[inpos] == '0') {
     472        9969 :                                                 padding = format[inpos];
     473       19122 :                                         } else if (format[inpos] == '-') {
     474        1425 :                                                 alignment = ALIGN_LEFT;
     475             :                                                 /* space padding, the default */
     476       17697 :                                         } else if (format[inpos] == '+') {
     477         179 :                                                 always_sign = 1;
     478       17518 :                                         } 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       12130 :                                 }
     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       16961 :                                 if (isdigit((int)format[inpos])) {
     492             :                                         PRINTF_DEBUG(("sprintf: getting width\n"));
     493       14430 :                                         if ((width = php_sprintf_getnumber(format, &inpos)) < 0) {
     494           0 :                                                 efree(result);
     495           0 :                                                 efree(args);
     496           0 :                                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Width must be greater than zero and less than %d", INT_MAX);
     497           0 :                                                 return NULL;
     498             :                                         }
     499       14430 :                                         adjusting |= ADJ_WIDTH;
     500             :                                 } else {
     501        2531 :                                         width = 0;
     502             :                                 }
     503             :                                 PRINTF_DEBUG(("sprintf: width=%d\n", width));
     504             : 
     505             :                                 /* after width and argnum comes precision */
     506       16961 :                                 if (format[inpos] == '.') {
     507         729 :                                         inpos++;
     508             :                                         PRINTF_DEBUG(("sprintf: getting precision\n"));
     509         729 :                                         if (isdigit((int)format[inpos])) {
     510         727 :                                                 if ((precision = php_sprintf_getnumber(format, &inpos)) < 0) {
     511           0 :                                                         efree(result);
     512           0 :                                                         efree(args);
     513           0 :                                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Precision must be greater than zero and less than %d", INT_MAX);
     514           0 :                                                         return NULL;
     515             :                                                 }
     516         727 :                                                 adjusting |= ADJ_PRECISION;
     517         727 :                                                 expprec = 1;
     518             :                                         } else {
     519           2 :                                                 precision = 0;
     520             :                                         }
     521             :                                 } else {
     522       16232 :                                         precision = 0;
     523             :                                 }
     524             :                                 PRINTF_DEBUG(("sprintf: precision=%d\n", precision));
     525             :                         } else {
     526      234202 :                                 width = precision = 0;
     527      234202 :                                 argnum = currarg++ + format_offset;
     528             :                         }
     529             : 
     530      251163 :                         if (argnum >= argc) {
     531          29 :                                 efree(result);
     532          29 :                                 efree(args);
     533          29 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too few arguments");
     534          29 :                                 return NULL;
     535             :                         }
     536             : 
     537      251134 :                         if (format[inpos] == 'l') {
     538        1711 :                                 inpos++;
     539             :                         }
     540             :                         PRINTF_DEBUG(("sprintf: format character='%c'\n", format[inpos]));
     541             :                         /* now we expect to find a type specifier */
     542      251134 :                         if (multiuse) {
     543         553 :                                 MAKE_STD_ZVAL(tmp);
     544         553 :                                 *tmp = **(args[argnum]);
     545         553 :                                 INIT_PZVAL(tmp);
     546         553 :                                 zval_copy_ctor(tmp);
     547             :                         } else {
     548      645884 :                                 SEPARATE_ZVAL(args[argnum]);
     549      250581 :                                 tmp = *(args[argnum]);
     550             :                         }
     551             : 
     552      251134 :                         switch (format[inpos]) {
     553             :                                 case 's': {
     554             :                                         zval *var, var_copy;
     555             :                                         int use_copy;
     556             : 
     557       46767 :                                         zend_make_printable_zval(tmp, &var_copy, &use_copy);
     558       46767 :                                         if (use_copy) {
     559        3740 :                                                 var = &var_copy;
     560             :                                         } else {
     561       43027 :                                                 var = tmp;
     562             :                                         }
     563       46767 :                                         php_sprintf_appendstring(&result, &outpos, &size,
     564             :                                                                                          Z_STRVAL_P(var),
     565             :                                                                                          width, precision, padding,
     566             :                                                                                          alignment,
     567             :                                                                                          Z_STRLEN_P(var),
     568             :                                                                                          0, expprec, 0);
     569       46767 :                                         if (use_copy) {
     570             :                                                 zval_dtor(&var_copy);
     571             :                                         }
     572       46767 :                                         break;
     573             :                                 }
     574             : 
     575             :                                 case 'd':
     576       35725 :                                         convert_to_long(tmp);
     577       71450 :                                         php_sprintf_appendint(&result, &outpos, &size,
     578       35725 :                                                                                   Z_LVAL_P(tmp),
     579             :                                                                                   width, padding, alignment,
     580             :                                                                                   always_sign);
     581       35725 :                                         break;
     582             : 
     583             :                                 case 'u':
     584         921 :                                         convert_to_long(tmp);
     585        1842 :                                         php_sprintf_appenduint(&result, &outpos, &size,
     586         921 :                                                                                   Z_LVAL_P(tmp),
     587             :                                                                                   width, padding, alignment);
     588         921 :                                         break;
     589             : 
     590             :                                 case 'g':
     591             :                                 case 'G':
     592             :                                 case 'e':
     593             :                                 case 'E':
     594             :                                 case 'f':
     595             :                                 case 'F':
     596        3806 :                                         convert_to_double(tmp);
     597        7612 :                                         php_sprintf_appenddouble(&result, &outpos, &size,
     598        3806 :                                                                                          Z_DVAL_P(tmp),
     599             :                                                                                          width, padding, alignment,
     600             :                                                                                          precision, adjusting,
     601        3806 :                                                                                          format[inpos], always_sign
     602             :                                                                                          TSRMLS_CC);
     603        3806 :                                         break;
     604             :                                         
     605             :                                 case 'c':
     606      151373 :                                         convert_to_long(tmp);
     607      151373 :                                         php_sprintf_appendchar(&result, &outpos, &size,
     608      151373 :                                                                                 (char) Z_LVAL_P(tmp) TSRMLS_CC);
     609      151373 :                                         break;
     610             : 
     611             :                                 case 'o':
     612        4049 :                                         convert_to_long(tmp);
     613        8098 :                                         php_sprintf_append2n(&result, &outpos, &size,
     614        4049 :                                                                                  Z_LVAL_P(tmp),
     615             :                                                                                  width, padding, alignment, 3,
     616             :                                                                                  hexchars, expprec);
     617        4049 :                                         break;
     618             : 
     619             :                                 case 'x':
     620        2137 :                                         convert_to_long(tmp);
     621        4274 :                                         php_sprintf_append2n(&result, &outpos, &size,
     622        2137 :                                                                                  Z_LVAL_P(tmp),
     623             :                                                                                  width, padding, alignment, 4,
     624             :                                                                                  hexchars, expprec);
     625        2137 :                                         break;
     626             : 
     627             :                                 case 'X':
     628        3836 :                                         convert_to_long(tmp);
     629        7672 :                                         php_sprintf_append2n(&result, &outpos, &size,
     630        3836 :                                                                                  Z_LVAL_P(tmp),
     631             :                                                                                  width, padding, alignment, 4,
     632             :                                                                                  HEXCHARS, expprec);
     633        3836 :                                         break;
     634             : 
     635             :                                 case 'b':
     636          67 :                                         convert_to_long(tmp);
     637         134 :                                         php_sprintf_append2n(&result, &outpos, &size,
     638          67 :                                                                                  Z_LVAL_P(tmp),
     639             :                                                                                  width, padding, alignment, 1,
     640             :                                                                                  hexchars, expprec);
     641          67 :                                         break;
     642             : 
     643             :                                 case '%':
     644          12 :                                         php_sprintf_appendchar(&result, &outpos, &size, '%' TSRMLS_CC);
     645             : 
     646             :                                         break;
     647             :                                 default:
     648             :                                         break;
     649             :                         }
     650      251134 :                         if (multiuse) {
     651         553 :                                 zval_ptr_dtor(&tmp);
     652             :                         }
     653      251134 :                         inpos++;
     654             :                 }
     655             :         }
     656             :         
     657      211933 :         efree(args);
     658             :         
     659             :         /* possibly, we have to make sure we have room for the terminating null? */
     660      211933 :         result[outpos]=0;
     661      211933 :         *len = outpos;  
     662      211933 :         return result;
     663             : }
     664             : /* }}} */
     665             : 
     666             : /* {{{ proto string sprintf(string format [, mixed arg1 [, mixed ...]])
     667             :    Return a formatted string */
     668      197774 : PHP_FUNCTION(user_sprintf)
     669             : {
     670             :         char *result;
     671             :         int len;
     672             :         
     673      197774 :         if ((result=php_formatted_print(ht, &len, 0, 0 TSRMLS_CC))==NULL) {
     674           7 :                 RETURN_FALSE;
     675             :         }
     676      197767 :         RETVAL_STRINGL(result, len, 0);
     677             : }
     678             : /* }}} */
     679             : 
     680             : /* {{{ proto string vsprintf(string format, array args)
     681             :    Return a formatted string */
     682         204 : PHP_FUNCTION(vsprintf)
     683             : {
     684             :         char *result;
     685             :         int len;
     686             :         
     687         204 :         if ((result=php_formatted_print(ht, &len, 1, 0 TSRMLS_CC))==NULL) {
     688           8 :                 RETURN_FALSE;
     689             :         }
     690         196 :         RETVAL_STRINGL(result, len, 0);
     691             : }
     692             : /* }}} */
     693             : 
     694             : /* {{{ proto int printf(string format [, mixed arg1 [, mixed ...]])
     695             :    Output a formatted string */
     696       12065 : PHP_FUNCTION(user_printf)
     697             : {
     698             :         char *result;
     699             :         int len, rlen;
     700             :         
     701       12065 :         if ((result=php_formatted_print(ht, &len, 0, 0 TSRMLS_CC))==NULL) {
     702          10 :                 RETURN_FALSE;
     703             :         }
     704       12055 :         rlen = PHPWRITE(result, len);
     705       12055 :         efree(result);
     706       12055 :         RETURN_LONG(rlen);
     707             : }
     708             : /* }}} */
     709             : 
     710             : /* {{{ proto int vprintf(string format, array args)
     711             :    Output a formatted string */
     712         189 : PHP_FUNCTION(vprintf)
     713             : {
     714             :         char *result;
     715             :         int len, rlen;
     716             :         
     717         189 :         if ((result=php_formatted_print(ht, &len, 1, 0 TSRMLS_CC))==NULL) {
     718           8 :                 RETURN_FALSE;
     719             :         }
     720         181 :         rlen = PHPWRITE(result, len);
     721         181 :         efree(result);
     722         181 :         RETURN_LONG(rlen);
     723             : }
     724             : /* }}} */
     725             : 
     726             : /* {{{ proto int fprintf(resource stream, string format [, mixed arg1 [, mixed ...]])
     727             :    Output a formatted string into a stream */
     728        1541 : PHP_FUNCTION(fprintf)
     729             : {
     730             :         php_stream *stream;
     731             :         zval *arg1;
     732             :         char *result;
     733             :         int len;
     734             :         
     735        1541 :         if (ZEND_NUM_ARGS() < 2) {
     736           3 :                 WRONG_PARAM_COUNT;
     737             :         }
     738             :         
     739        1538 :         if (zend_parse_parameters(1 TSRMLS_CC, "r", &arg1) == FAILURE) {
     740           0 :                 RETURN_FALSE;
     741             :         }
     742             :         
     743        1538 :         php_stream_from_zval(stream, &arg1);
     744             : 
     745        1538 :         if ((result=php_formatted_print(ht, &len, 0, 1 TSRMLS_CC))==NULL) {
     746           1 :                 RETURN_FALSE;
     747             :         }
     748             : 
     749        1537 :         php_stream_write(stream, result, len);
     750             : 
     751        1537 :         efree(result);
     752             : 
     753        1537 :         RETURN_LONG(len);
     754             : }
     755             : /* }}} */
     756             : 
     757             : /* {{{ proto int vfprintf(resource stream, string format, array args)
     758             :    Output a formatted string into a stream */
     759         211 : PHP_FUNCTION(vfprintf)
     760             : {
     761             :         php_stream *stream;
     762             :         zval *arg1;
     763             :         char *result;
     764             :         int len;
     765             :         
     766         211 :         if (ZEND_NUM_ARGS() != 3) {
     767           5 :                 WRONG_PARAM_COUNT;
     768             :         }
     769             :         
     770         206 :         if (zend_parse_parameters(1 TSRMLS_CC, "r", &arg1) == FAILURE) {
     771           3 :                 RETURN_FALSE;
     772             :         }
     773             :         
     774         203 :         php_stream_from_zval(stream, &arg1);
     775             : 
     776         203 :         if ((result=php_formatted_print(ht, &len, 1, 1 TSRMLS_CC))==NULL) {
     777           6 :                 RETURN_FALSE;
     778             :         }
     779             : 
     780         197 :         php_stream_write(stream, result, len);
     781             : 
     782         197 :         efree(result);
     783             : 
     784         197 :         RETURN_LONG(len);
     785             : }
     786             : /* }}} */
     787             : 
     788             : /*
     789             :  * Local variables:
     790             :  * tab-width: 4
     791             :  * c-basic-offset: 4
     792             :  * End:
     793             :  * vim600: sw=4 ts=4 fdm=marker
     794             :  * vim<600: sw=4 ts=4
     795             :  */

Generated by: LCOV version 1.10

Generated at Tue, 25 Nov 2014 09:11:05 +0000 (2 days ago)

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