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

LTP GCOV extension - code coverage report
Current view: directory - var/php_gcov/PHP_5_3/main - spprintf.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 294
Code covered: 63.9 % Executed lines: 188
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 5                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2009 The PHP Group                                |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 3.01 of the PHP license,      |
       8                 :    | that is bundled with this package in the file LICENSE, and is        |
       9                 :    | available through the world-wide-web at the following url:           |
      10                 :    | http://www.php.net/license/3_01.txt                                  |
      11                 :    | If you did not receive a copy of the PHP license and are unable to   |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@php.net so we can mail you a copy immediately.               |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Author: Marcus Boerger <helly@php.net>                               |
      16                 :    +----------------------------------------------------------------------+
      17                 : */
      18                 : 
      19                 : /* $Id: spprintf.c 272370 2008-12-31 11:15:49Z sebastian $ */
      20                 : 
      21                 : /* This is the spprintf implementation.
      22                 :  * It has emerged from apache snprintf. See original header:
      23                 :  */
      24                 : 
      25                 : /* ====================================================================
      26                 :  * Copyright (c) 1995-1998 The Apache Group.  All rights reserved.
      27                 :  *
      28                 :  * Redistribution and use in source and binary forms, with or without
      29                 :  * modification, are permitted provided that the following conditions
      30                 :  * are met:
      31                 :  *
      32                 :  * 1. Redistributions of source code must retain the above copyright
      33                 :  *    notice, this list of conditions and the following disclaimer.
      34                 :  *
      35                 :  * 2. Redistributions in binary form must reproduce the above copyright
      36                 :  *    notice, this list of conditions and the following disclaimer in
      37                 :  *    the documentation and/or other materials provided with the
      38                 :  *    distribution.
      39                 :  *
      40                 :  * 3. All advertising materials mentioning features or use of this
      41                 :  *    software must display the following acknowledgment:
      42                 :  *    "This product includes software developed by the Apache Group
      43                 :  *    for use in the Apache HTTP server project (http://www.apache.org/)."
      44                 :  *
      45                 :  * 4. The names "Apache Server" and "Apache Group" must not be used to
      46                 :  *    endorse or promote products derived from this software without
      47                 :  *    prior written permission.
      48                 :  *
      49                 :  * 5. Redistributions of any form whatsoever must retain the following
      50                 :  *    acknowledgment:
      51                 :  *    "This product includes software developed by the Apache Group
      52                 :  *    for use in the Apache HTTP server project (http://www.apache.org/)."
      53                 :  *
      54                 :  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
      55                 :  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      56                 :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      57                 :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
      58                 :  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      59                 :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      60                 :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      61                 :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      62                 :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      63                 :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      64                 :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      65                 :  * OF THE POSSIBILITY OF SUCH DAMAGE.
      66                 :  * ====================================================================
      67                 :  *
      68                 :  * This software consists of voluntary contributions made by many
      69                 :  * individuals on behalf of the Apache Group and was originally based
      70                 :  * on public domain software written at the National Center for
      71                 :  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
      72                 :  * For more information on the Apache Group and the Apache HTTP server
      73                 :  * project, please see <http://www.apache.org/>.
      74                 :  *
      75                 :  * This code is based on, and used with the permission of, the
      76                 :  * SIO stdio-replacement strx_* functions by Panos Tsirigotis
      77                 :  * <panos@alumni.cs.colorado.edu> for xinetd.
      78                 :  */
      79                 : #define _GNU_SOURCE
      80                 : #include "php.h"
      81                 : 
      82                 : #include <stddef.h>
      83                 : #include <stdio.h>
      84                 : #include <ctype.h>
      85                 : #include <sys/types.h>
      86                 : #include <stdarg.h>
      87                 : #include <string.h>
      88                 : #include <stdlib.h>
      89                 : #include <math.h>
      90                 : #ifdef HAVE_INTTYPES_H
      91                 : #include <inttypes.h>
      92                 : #endif
      93                 : 
      94                 : #ifdef HAVE_LOCALE_H
      95                 : #include <locale.h>
      96                 : #define LCONV_DECIMAL_POINT (*lconv->decimal_point)
      97                 : #else
      98                 : #define LCONV_DECIMAL_POINT '.'
      99                 : #endif
     100                 : 
     101                 : #include "snprintf.h"
     102                 : 
     103                 : #define FALSE           0
     104                 : #define TRUE            1
     105                 : #define NUL             '\0'
     106                 : #define INT_NULL        ((int *)0)
     107                 : 
     108                 : #define S_NULL          "(null)"
     109                 : #define S_NULL_LEN      6
     110                 : 
     111                 : #define FLOAT_DIGITS    6
     112                 : #define EXPONENT_LENGTH 10
     113                 : 
     114                 : #include "ext/standard/php_smart_str.h"
     115                 : 
     116                 : /* {{{ macros */
     117                 : 
     118                 : /*
     119                 :  * NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions
     120                 :  *
     121                 :  * XXX: this is a magic number; do not decrease it
     122                 :  */
     123                 : #define NUM_BUF_SIZE    512
     124                 : 
     125                 : /*
     126                 :  * The INS_CHAR macro inserts a character in the buffer.
     127                 :  *
     128                 :  * NOTE: Evaluation of the ch argument should not have any side-effects
     129                 :  */
     130                 : #define INS_CHAR_NR(xbuf, ch) do {      \
     131                 :         smart_str_appendc(xbuf, ch);    \
     132                 : } while (0)
     133                 : 
     134                 : #define INS_STRING(xbuf, s, slen) do {  \
     135                 :         smart_str_appendl(xbuf, s, slen);       \
     136                 : } while (0)
     137                 : 
     138                 : #define INS_CHAR(xbuf, ch)          \
     139                 :         INS_CHAR_NR(xbuf, ch)
     140                 : 
     141                 : /*
     142                 :  * Macro that does padding. The padding is done by printing
     143                 :  * the character ch.
     144                 :  */
     145                 : #define PAD(xbuf, count, ch) do {                                       \
     146                 :         if ((count) > 0) {                                   \
     147                 :                 size_t newlen;                                                          \
     148                 :                 smart_str_alloc(xbuf, (count), 0);                      \
     149                 :                 memset(xbuf->c + xbuf->len, ch, (count)); \
     150                 :                 xbuf->len += (count);                                \
     151                 :         }                                                                                               \
     152                 : } while (0)
     153                 : 
     154                 : #define NUM(c) (c - '0')
     155                 : 
     156                 : #define STR_TO_DEC(str, num) do {                       \
     157                 :         num = NUM(*str++);                      \
     158                 :         while (isdigit((int)*str)) {            \
     159                 :                 num *= 10;                              \
     160                 :                 num += NUM(*str++);                     \
     161                 :                 if (num >= INT_MAX / 10) {                   \
     162                 :                         while (isdigit((int)*str++));   \
     163                 :                         break;                                                  \
     164                 :                 }                                                                       \
     165                 :     }                                                                           \
     166                 : } while (0)
     167                 : 
     168                 : /*
     169                 :  * This macro does zero padding so that the precision
     170                 :  * requirement is satisfied. The padding is done by
     171                 :  * adding '0's to the left of the string that is going
     172                 :  * to be printed.
     173                 :  */
     174                 : #define FIX_PRECISION(adjust, precision, s, s_len) do { \
     175                 :     if (adjust)                                                         \
     176                 :                 while (s_len < precision) {                  \
     177                 :                         *--s = '0';                                     \
     178                 :                         s_len++;                                        \
     179                 :                 }                                                                                               \
     180                 : } while (0)
     181                 : 
     182                 : /* }}} */
     183                 : 
     184                 : 
     185                 : #if !HAVE_STRNLEN
     186                 : static size_t strnlen(const char *s, size_t maxlen) {
     187                 :         char *r = memchr(s, '\0', maxlen);
     188                 :         return r ? r-s : maxlen;
     189                 : }
     190                 : #endif
     191                 : 
     192                 : /*
     193                 :  * Do format conversion placing the output in buffer
     194                 :  */
     195                 : static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) /* {{{ */
     196         7350884 : {
     197         7350884 :         char *s = NULL;
     198                 :         char *q;
     199                 :         int s_len, free_zcopy;
     200                 :         zval *zvp, zcopy;
     201                 : 
     202         7350884 :         int min_width = 0;
     203         7350884 :         int precision = 0;
     204                 :         enum {
     205                 :                 LEFT, RIGHT
     206                 :         } adjust;
     207                 :         char pad_char;
     208                 :         char prefix_char;
     209                 : 
     210                 :         double fp_num;
     211         7350884 :         wide_int i_num = (wide_int) 0;
     212                 :         u_wide_int ui_num;
     213                 : 
     214                 :         char num_buf[NUM_BUF_SIZE];
     215                 :         char char_buf[2];                       /* for printing %% and %<unknown> */
     216                 : 
     217                 : #ifdef HAVE_LOCALE_H
     218         7350884 :         struct lconv *lconv = NULL;
     219                 : #endif
     220                 : 
     221                 :         /*
     222                 :          * Flag variables
     223                 :          */
     224                 :         length_modifier_e modifier;
     225                 :         boolean_e alternate_form;
     226                 :         boolean_e print_sign;
     227                 :         boolean_e print_blank;
     228                 :         boolean_e adjust_precision;
     229                 :         boolean_e adjust_width;
     230                 :         bool_int is_negative;
     231                 : 
     232       103890072 :         while (*fmt) {
     233        89188304 :                 if (*fmt != '%') {
     234        70854710 :                         INS_CHAR(xbuf, *fmt);
     235                 :                 } else {
     236                 :                         /*
     237                 :                          * Default variable settings
     238                 :                          */
     239        18333594 :                         adjust = RIGHT;
     240        18333594 :                         alternate_form = print_sign = print_blank = NO;
     241        18333594 :                         pad_char = ' ';
     242        18333594 :                         prefix_char = NUL;
     243        18333594 :                         free_zcopy = 0;
     244                 : 
     245        18333594 :                         fmt++;
     246                 : 
     247                 :                         /*
     248                 :                          * Try to avoid checking for flags, width or precision
     249                 :                          */
     250        18536945 :                         if (isascii((int)*fmt) && !islower((int)*fmt)) {
     251                 :                                 /*
     252                 :                                  * Recognize flags: -, #, BLANK, +
     253                 :                                  */
     254           23651 :                                 for (;; fmt++) {
     255          227002 :                                         if (*fmt == '-')
     256              20 :                                                 adjust = LEFT;
     257          226982 :                                         else if (*fmt == '+')
     258               0 :                                                 print_sign = YES;
     259          226982 :                                         else if (*fmt == '#')
     260               0 :                                                 alternate_form = YES;
     261          226982 :                                         else if (*fmt == ' ')
     262               0 :                                                 print_blank = YES;
     263          226982 :                                         else if (*fmt == '0')
     264           23631 :                                                 pad_char = '0';
     265                 :                                         else
     266          203351 :                                                 break;
     267           23651 :                                 }
     268                 : 
     269                 :                                 /*
     270                 :                                  * Check if a width was specified
     271                 :                                  */
     272          203351 :                                 if (isdigit((int)*fmt)) {
     273           23412 :                                         STR_TO_DEC(fmt, min_width);
     274           23412 :                                         adjust_width = YES;
     275          179939 :                                 } else if (*fmt == '*') {
     276          151212 :                                         min_width = va_arg(ap, int);
     277          151212 :                                         fmt++;
     278          151212 :                                         adjust_width = YES;
     279          151212 :                                         if (min_width < 0) {
     280               0 :                                                 adjust = LEFT;
     281               0 :                                                 min_width = -min_width;
     282                 :                                         }
     283                 :                                 } else
     284           28727 :                                         adjust_width = NO;
     285                 : 
     286                 :                                 /*
     287                 :                                  * Check if a precision was specified
     288                 :                                  *
     289                 :                                  * XXX: an unreasonable amount of precision may be specified
     290                 :                                  * resulting in overflow of num_buf. Currently we
     291                 :                                  * ignore this possibility.
     292                 :                                  */
     293          203351 :                                 if (*fmt == '.') {
     294           28725 :                                         adjust_precision = YES;
     295           28725 :                                         fmt++;
     296           28725 :                                         if (isdigit((int)*fmt)) {
     297             512 :                                                 STR_TO_DEC(fmt, precision);
     298           28213 :                                         } else if (*fmt == '*') {
     299           28213 :                                                 precision = va_arg(ap, int);
     300           28213 :                                                 fmt++;
     301           28213 :                                                 if (precision < 0)
     302               0 :                                                         precision = 0;
     303                 :                                         } else
     304               0 :                                                 precision = 0;
     305                 :                                 } else
     306          174626 :                                         adjust_precision = NO;
     307                 :                         } else
     308        18130243 :                                 adjust_precision = adjust_width = NO;
     309                 : 
     310                 :                         /*
     311                 :                          * Modifier check
     312                 :                          */
     313        18333594 :                         switch (*fmt) {
     314                 :                                 case 'L':
     315               0 :                                         fmt++;
     316               0 :                                         modifier = LM_LONG_DOUBLE;
     317               0 :                                         break;
     318                 :                                 case 'I':
     319               0 :                                         fmt++;
     320                 : #if SIZEOF_LONG_LONG
     321               0 :                                         if (*fmt == '6' && *(fmt+1) == '4') {
     322               0 :                                                 fmt += 2;
     323               0 :                                                 modifier = LM_LONG_LONG;
     324                 :                                         } else
     325                 : #endif
     326               0 :                                                 if (*fmt == '3' && *(fmt+1) == '2') {
     327               0 :                                                         fmt += 2;
     328               0 :                                                         modifier = LM_LONG;
     329                 :                                                 } else {
     330                 : #ifdef _WIN64
     331                 :                                                         modifier = LM_LONG_LONG;
     332                 : #else
     333               0 :                                                         modifier = LM_LONG;
     334                 : #endif
     335                 :                                                 }
     336               0 :                                         break;
     337                 :                                 case 'l':
     338         2572656 :                                         fmt++;
     339                 : #if SIZEOF_LONG_LONG
     340         2572656 :                                         if (*fmt == 'l') {
     341               1 :                                                 fmt++;
     342               1 :                                                 modifier = LM_LONG_LONG;
     343                 :                                         } else
     344                 : #endif
     345         2572655 :                                                 modifier = LM_LONG;
     346         2572656 :                                         break;
     347                 :                                 case 'z':
     348               2 :                                         fmt++;
     349               2 :                                         modifier = LM_SIZE_T;
     350               2 :                                         break;
     351                 :                                 case 'j':
     352               0 :                                         fmt++;
     353                 : #if SIZEOF_INTMAX_T
     354               0 :                                         modifier = LM_INTMAX_T;
     355                 : #else
     356                 :                                         modifier = LM_SIZE_T;
     357                 : #endif
     358               0 :                                         break;
     359                 :                                 case 't':
     360               0 :                                         fmt++;
     361                 : #if SIZEOF_PTRDIFF_T
     362               0 :                                         modifier = LM_PTRDIFF_T;
     363                 : #else
     364                 :                                         modifier = LM_SIZE_T;
     365                 : #endif
     366               0 :                                         break;
     367                 :                                 case 'h':
     368               0 :                                         fmt++;
     369               0 :                                         if (*fmt == 'h') {
     370               0 :                                                 fmt++;
     371                 :                                         }
     372                 :                                         /* these are promoted to int, so no break */
     373                 :                                 default:
     374        15760936 :                                         modifier = LM_STD;
     375                 :                                         break;
     376                 :                         }
     377                 : 
     378                 :                         /*
     379                 :                          * Argument extraction and printing.
     380                 :                          * First we determine the argument type.
     381                 :                          * Then, we convert the argument to a string.
     382                 :                          * On exit from the switch, s points to the string that
     383                 :                          * must be printed, s_len has the length of the string
     384                 :                          * The precision requirements, if any, are reflected in s_len.
     385                 :                          *
     386                 :                          * NOTE: pad_char may be set to '0' because of the 0 flag.
     387                 :                          *   It is reset to ' ' by non-numeric formats
     388                 :                          */
     389        18333594 :                         switch (*fmt) {
     390                 :                                 case 'Z':
     391               0 :                                         zvp = (zval*) va_arg(ap, zval*);
     392               0 :                                         zend_make_printable_zval(zvp, &zcopy, &free_zcopy);
     393               0 :                                         if (free_zcopy) {
     394               0 :                                                 zvp = &zcopy;
     395                 :                                         }
     396               0 :                                         s_len = Z_STRLEN_P(zvp);
     397               0 :                                         s = Z_STRVAL_P(zvp);
     398               0 :                                         if (adjust_precision && precision < s_len) {
     399               0 :                                                 s_len = precision;
     400                 :                                         }
     401               0 :                                         break;
     402                 :                                 case 'u':
     403            1044 :                                         switch(modifier) {
     404                 :                                                 default:
     405            1041 :                                                         i_num = (wide_int) va_arg(ap, unsigned int);
     406            1041 :                                                         break;
     407                 :                                                 case LM_LONG_DOUBLE:
     408               0 :                                                         goto fmt_error;
     409                 :                                                 case LM_LONG:
     410               2 :                                                         i_num = (wide_int) va_arg(ap, unsigned long int);
     411               2 :                                                         break;
     412                 :                                                 case LM_SIZE_T:
     413               0 :                                                         i_num = (wide_int) va_arg(ap, size_t);
     414               0 :                                                         break;
     415                 : #if SIZEOF_LONG_LONG
     416                 :                                                 case LM_LONG_LONG:
     417               1 :                                                         i_num = (wide_int) va_arg(ap, u_wide_int);
     418               1 :                                                         break;
     419                 : #endif
     420                 : #if SIZEOF_INTMAX_T
     421                 :                                                 case LM_INTMAX_T:
     422               0 :                                                         i_num = (wide_int) va_arg(ap, uintmax_t);
     423               0 :                                                         break;
     424                 : #endif
     425                 : #if SIZEOF_PTRDIFF_T
     426                 :                                                 case LM_PTRDIFF_T:
     427               0 :                                                         i_num = (wide_int) va_arg(ap, ptrdiff_t);
     428                 :                                                         break;
     429                 : #endif
     430                 :                                         }
     431                 :                                         /*
     432                 :                                          * The rest also applies to other integer formats, so fall
     433                 :                                          * into that case.
     434                 :                                          */
     435                 :                                 case 'd':
     436                 :                                 case 'i':
     437                 :                                         /*
     438                 :                                          * Get the arg if we haven't already.
     439                 :                                          */
     440         4845010 :                                         if ((*fmt) != 'u') {
     441         4843966 :                                                 switch(modifier) {
     442                 :                                                         default:
     443         2271311 :                                                                 i_num = (wide_int) va_arg(ap, int);
     444         2271311 :                                                                 break;
     445                 :                                                         case LM_LONG_DOUBLE:
     446               0 :                                                                 goto fmt_error;
     447                 :                                                         case LM_LONG:
     448         2572653 :                                                                 i_num = (wide_int) va_arg(ap, long int);
     449         2572653 :                                                                 break;
     450                 :                                                         case LM_SIZE_T:
     451                 : #if SIZEOF_SSIZE_T
     452               2 :                                                                 i_num = (wide_int) va_arg(ap, ssize_t);
     453                 : #else
     454                 :                                                                 i_num = (wide_int) va_arg(ap, size_t);
     455                 : #endif
     456               2 :                                                                 break;
     457                 : #if SIZEOF_LONG_LONG
     458                 :                                                         case LM_LONG_LONG:
     459               0 :                                                                 i_num = (wide_int) va_arg(ap, wide_int);
     460               0 :                                                                 break;
     461                 : #endif
     462                 : #if SIZEOF_INTMAX_T
     463                 :                                                         case LM_INTMAX_T:
     464               0 :                                                                 i_num = (wide_int) va_arg(ap, intmax_t);
     465               0 :                                                                 break;
     466                 : #endif
     467                 : #if SIZEOF_PTRDIFF_T
     468                 :                                                         case LM_PTRDIFF_T:
     469               0 :                                                                 i_num = (wide_int) va_arg(ap, ptrdiff_t);
     470                 :                                                                 break;
     471                 : #endif
     472                 :                                                 }
     473                 :                                         }
     474         4845010 :                                         s = ap_php_conv_10(i_num, (*fmt) == 'u', &is_negative,
     475                 :                                                                 &num_buf[NUM_BUF_SIZE], &s_len);
     476         4845010 :                                         FIX_PRECISION(adjust_precision, precision, s, s_len);
     477                 : 
     478         4845010 :                                         if (*fmt != 'u') {
     479         4843966 :                                                 if (is_negative)
     480            6053 :                                                         prefix_char = '-';
     481         4837913 :                                                 else if (print_sign)
     482               0 :                                                         prefix_char = '+';
     483         4837913 :                                                 else if (print_blank)
     484               0 :                                                         prefix_char = ' ';
     485                 :                                         }
     486         4845010 :                                         break;
     487                 : 
     488                 : 
     489                 :                                 case 'o':
     490               2 :                                         switch(modifier) {
     491                 :                                                 default:
     492               2 :                                                         ui_num = (u_wide_int) va_arg(ap, unsigned int);
     493               2 :                                                         break;
     494                 :                                                 case LM_LONG_DOUBLE:
     495               0 :                                                         goto fmt_error;
     496                 :                                                 case LM_LONG:
     497               0 :                                                         ui_num = (u_wide_int) va_arg(ap, unsigned long int);
     498               0 :                                                         break;
     499                 :                                                 case LM_SIZE_T:
     500               0 :                                                         ui_num = (u_wide_int) va_arg(ap, size_t);
     501               0 :                                                         break;
     502                 : #if SIZEOF_LONG_LONG
     503                 :                                                 case LM_LONG_LONG:
     504               0 :                                                         ui_num = (u_wide_int) va_arg(ap, u_wide_int);
     505               0 :                                                         break;
     506                 : #endif
     507                 : #if SIZEOF_INTMAX_T
     508                 :                                                 case LM_INTMAX_T:
     509               0 :                                                         ui_num = (u_wide_int) va_arg(ap, uintmax_t);
     510               0 :                                                         break;
     511                 : #endif
     512                 : #if SIZEOF_PTRDIFF_T
     513                 :                                                 case LM_PTRDIFF_T:
     514               0 :                                                         ui_num = (u_wide_int) va_arg(ap, ptrdiff_t);
     515                 :                                                         break;
     516                 : #endif
     517                 :                                         }
     518               2 :                                         s = ap_php_conv_p2(ui_num, 3, *fmt,
     519                 :                                                                 &num_buf[NUM_BUF_SIZE], &s_len);
     520               2 :                                         FIX_PRECISION(adjust_precision, precision, s, s_len);
     521               2 :                                         if (alternate_form && *s != '0') {
     522               0 :                                                 *--s = '0';
     523               0 :                                                 s_len++;
     524                 :                                         }
     525               2 :                                         break;
     526                 : 
     527                 : 
     528                 :                                 case 'x':
     529                 :                                 case 'X':
     530           22736 :                                         switch(modifier) {
     531                 :                                                 default:
     532           22736 :                                                         ui_num = (u_wide_int) va_arg(ap, unsigned int);
     533           22736 :                                                         break;
     534                 :                                                 case LM_LONG_DOUBLE:
     535               0 :                                                         goto fmt_error;
     536                 :                                                 case LM_LONG:
     537               0 :                                                         ui_num = (u_wide_int) va_arg(ap, unsigned long int);
     538               0 :                                                         break;
     539                 :                                                 case LM_SIZE_T:
     540               0 :                                                         ui_num = (u_wide_int) va_arg(ap, size_t);
     541               0 :                                                         break;
     542                 : #if SIZEOF_LONG_LONG
     543                 :                                                 case LM_LONG_LONG:
     544               0 :                                                         ui_num = (u_wide_int) va_arg(ap, u_wide_int);
     545               0 :                                                         break;
     546                 : #endif
     547                 : #if SIZEOF_INTMAX_T
     548                 :                                                 case LM_INTMAX_T:
     549               0 :                                                         ui_num = (u_wide_int) va_arg(ap, uintmax_t);
     550               0 :                                                         break;
     551                 : #endif
     552                 : #if SIZEOF_PTRDIFF_T
     553                 :                                                 case LM_PTRDIFF_T:
     554               0 :                                                         ui_num = (u_wide_int) va_arg(ap, ptrdiff_t);
     555                 :                                                         break;
     556                 : #endif
     557                 :                                         }
     558           22736 :                                         s = ap_php_conv_p2(ui_num, 4, *fmt,
     559                 :                                                                 &num_buf[NUM_BUF_SIZE], &s_len);
     560           22736 :                                         FIX_PRECISION(adjust_precision, precision, s, s_len);
     561           22736 :                                         if (alternate_form && i_num != 0) {
     562               0 :                                                 *--s = *fmt;    /* 'x' or 'X' */
     563               0 :                                                 *--s = '0';
     564               0 :                                                 s_len += 2;
     565                 :                                         }
     566           22736 :                                         break;
     567                 : 
     568                 : 
     569                 :                                 case 's':
     570                 :                                 case 'v':
     571        13259534 :                                         s = va_arg(ap, char *);
     572        13259534 :                                         if (s != NULL) {
     573        13259526 :                                                 if (!adjust_precision) {
     574        13259267 :                                                         s_len = strlen(s);
     575                 :                                                 } else {
     576             259 :                                                         s_len = strnlen(s, precision);
     577                 :                                                 }
     578                 :                                         } else {
     579               8 :                                                 s = S_NULL;
     580               8 :                                                 s_len = S_NULL_LEN;
     581                 :                                         }
     582        13259534 :                                         pad_char = ' ';
     583        13259534 :                                         break;
     584                 : 
     585                 : 
     586                 :                                 case 'f':
     587                 :                                 case 'F':
     588                 :                                 case 'e':
     589                 :                                 case 'E':
     590            1576 :                                         switch(modifier) {
     591                 :                                                 case LM_LONG_DOUBLE:
     592               0 :                                                         fp_num = (double) va_arg(ap, long double);
     593               0 :                                                         break;
     594                 :                                                 case LM_STD:
     595            1576 :                                                         fp_num = va_arg(ap, double);
     596            1576 :                                                         break;
     597                 :                                                 default:
     598               0 :                                                         goto fmt_error;
     599                 :                                         }
     600                 : 
     601            1576 :                                         if (zend_isnan(fp_num)) {
     602               0 :                                                 s = "nan";
     603               0 :                                                 s_len = 3;
     604            1576 :                                         } else if (zend_isinf(fp_num)) {
     605               2 :                                                 s = "inf";
     606               2 :                                                 s_len = 3;
     607                 :                                         } else {
     608                 : #ifdef HAVE_LOCALE_H
     609            1574 :                                                 if (!lconv) {
     610            1574 :                                                         lconv = localeconv();
     611                 :                                                 }
     612                 : #endif
     613            1574 :                                                 s = php_conv_fp((*fmt == 'f')?'F':*fmt, fp_num, alternate_form,
     614                 :                                                  (adjust_precision == NO) ? FLOAT_DIGITS : precision,
     615                 :                                                  (*fmt == 'f')?LCONV_DECIMAL_POINT:'.',
     616                 :                                                                         &is_negative, &num_buf[1], &s_len);
     617            1574 :                                                 if (is_negative)
     618               2 :                                                         prefix_char = '-';
     619            1572 :                                                 else if (print_sign)
     620               0 :                                                         prefix_char = '+';
     621            1572 :                                                 else if (print_blank)
     622               0 :                                                         prefix_char = ' ';
     623                 :                                         }
     624            1576 :                                         break;
     625                 : 
     626                 : 
     627                 :                                 case 'g':
     628                 :                                 case 'k':
     629                 :                                 case 'G':
     630                 :                                 case 'H':
     631           26890 :                                         switch(modifier) {
     632                 :                                                 case LM_LONG_DOUBLE:
     633               0 :                                                         fp_num = (double) va_arg(ap, long double);
     634               0 :                                                         break;
     635                 :                                                 case LM_STD:
     636           26890 :                                                         fp_num = va_arg(ap, double);
     637           26890 :                                                         break;
     638                 :                                                 default:
     639               0 :                                                         goto fmt_error;
     640                 :                                         }
     641                 : 
     642           26890 :                                         if (zend_isnan(fp_num)) {
     643            1649 :                                                 s = "NAN";
     644            1649 :                                                 s_len = 3;
     645            1649 :                                                 break;
     646           25241 :                                         } else if (zend_isinf(fp_num)) {
     647            1624 :                                                 if (fp_num > 0) {
     648            1601 :                                                         s = "INF";
     649            1601 :                                                         s_len = 3;
     650                 :                                                 } else {
     651              23 :                                                         s = "-INF";
     652              23 :                                                         s_len = 4;
     653                 :                                                 }
     654            1624 :                                                 break;
     655                 :                                         }
     656                 : 
     657           23617 :                                         if (adjust_precision == NO)
     658               0 :                                                 precision = FLOAT_DIGITS;
     659           23617 :                                         else if (precision == 0)
     660               0 :                                                 precision = 1;
     661                 :                                         /*
     662                 :                                          * * We use &num_buf[ 1 ], so that we have room for the sign
     663                 :                                          */
     664                 : #ifdef HAVE_LOCALE_H
     665           23617 :                                         if (!lconv) {
     666           23617 :                                                 lconv = localeconv();
     667                 :                                         }
     668                 : #endif
     669           23617 :                                         s = php_gcvt(fp_num, precision, (*fmt=='H' || *fmt == 'k') ? '.' : LCONV_DECIMAL_POINT, (*fmt == 'G' || *fmt == 'H')?'E':'e', &num_buf[1]);
     670           23617 :                                         if (*s == '-')
     671            2431 :                                                 prefix_char = *s++;
     672           21186 :                                         else if (print_sign)
     673               0 :                                                 prefix_char = '+';
     674           21186 :                                         else if (print_blank)
     675               0 :                                                 prefix_char = ' ';
     676                 : 
     677           23617 :                                         s_len = strlen(s);
     678                 : 
     679           23617 :                                         if (alternate_form && (q = strchr(s, '.')) == NULL)
     680               0 :                                                 s[s_len++] = '.';
     681           23617 :                                         break;
     682                 : 
     683                 : 
     684                 :                                 case 'c':
     685          176851 :                                         char_buf[0] = (char) (va_arg(ap, int));
     686          176851 :                                         s = &char_buf[0];
     687          176851 :                                         s_len = 1;
     688          176851 :                                         pad_char = ' ';
     689          176851 :                                         break;
     690                 : 
     691                 : 
     692                 :                                 case '%':
     693               2 :                                         char_buf[0] = '%';
     694               2 :                                         s = &char_buf[0];
     695               2 :                                         s_len = 1;
     696               2 :                                         pad_char = ' ';
     697               2 :                                         break;
     698                 : 
     699                 : 
     700                 :                                 case 'n':
     701               0 :                                         *(va_arg(ap, int *)) = xbuf->len;
     702               0 :                                         goto skip_output;
     703                 : 
     704                 :                                         /*
     705                 :                                          * Always extract the argument as a "char *" pointer. We
     706                 :                                          * should be using "void *" but there are still machines
     707                 :                                          * that don't understand it.
     708                 :                                          * If the pointer size is equal to the size of an unsigned
     709                 :                                          * integer we convert the pointer to a hex number, otherwise
     710                 :                                          * we print "%p" to indicate that we don't handle "%p".
     711                 :                                          */
     712                 :                                 case 'p':
     713                 :                                         if (sizeof(char *) <= sizeof(u_wide_int)) {
     714             993 :                                                 ui_num = (u_wide_int)((size_t) va_arg(ap, char *));
     715             993 :                                                 s = ap_php_conv_p2(ui_num, 4, 'x',
     716                 :                                                                 &num_buf[NUM_BUF_SIZE], &s_len);
     717             993 :                                                 if (ui_num != 0) {
     718             993 :                                                         *--s = 'x';
     719             993 :                                                         *--s = '0';
     720             993 :                                                         s_len += 2;
     721                 :                                                 }
     722                 :                                         } else {
     723                 :                                                 s = "%p";
     724                 :                                                 s_len = 2;
     725                 :                                         }
     726             993 :                                         pad_char = ' ';
     727             993 :                                         break;
     728                 : 
     729                 : 
     730                 :                                 case NUL:
     731                 :                                         /*
     732                 :                                          * The last character of the format string was %.
     733                 :                                          * We ignore it.
     734                 :                                          */
     735               0 :                                         continue;
     736                 : 
     737                 : 
     738               0 : fmt_error:
     739               0 :                                 php_error(E_ERROR, "Illegal length modifier specified '%c' in s[np]printf call", *fmt);
     740                 :                                         /*
     741                 :                                          * The default case is for unrecognized %'s.
     742                 :                                          * We print %<char> to help the user identify what
     743                 :                                          * option is not understood.
     744                 :                                          * This is also useful in case the user wants to pass
     745                 :                                          * the output of format_converter to another function
     746                 :                                          * that understands some other %<char> (like syslog).
     747                 :                                          * Note that we can't point s inside fmt because the
     748                 :                                          * unknown <char> could be preceded by width etc.
     749                 :                                          */
     750                 :                                 default:
     751               0 :                                         char_buf[0] = '%';
     752               0 :                                         char_buf[1] = *fmt;
     753               0 :                                         s = char_buf;
     754               0 :                                         s_len = 2;
     755               0 :                                         pad_char = ' ';
     756                 :                                         break;
     757                 :                         }
     758                 : 
     759        18333594 :                         if (prefix_char != NUL) {
     760            8486 :                                 *--s = prefix_char;
     761            8486 :                                 s_len++;
     762                 :                         }
     763        18333594 :                         if (adjust_width && adjust == RIGHT && min_width > s_len) {
     764          152329 :                                 if (pad_char == '0' && prefix_char != NUL) {
     765               0 :                                         INS_CHAR(xbuf, *s);
     766               0 :                                         s++;
     767               0 :                                         s_len--;
     768               0 :                                         min_width--;
     769                 :                                 }
     770          152329 :                                 PAD(xbuf, min_width - s_len, pad_char);
     771                 :                         }
     772                 :                         /*
     773                 :                          * Print the string s.
     774                 :                          */
     775        18333594 :                         INS_STRING(xbuf, s, s_len);
     776                 : 
     777        18333594 :                         if (adjust_width && adjust == LEFT && min_width > s_len)
     778              20 :                                 PAD(xbuf, min_width - s_len, pad_char);
     779        18333594 :                         if (free_zcopy) {
     780               0 :                                 zval_dtor(&zcopy);
     781                 :                         }
     782                 :                 }
     783        89188304 : skip_output:
     784        89188304 :                 fmt++;
     785                 :         }
     786                 :         return;
     787                 : }
     788                 : /* }}} */
     789                 : 
     790                 : /*
     791                 :  * This is the general purpose conversion function.
     792                 :  */
     793                 : PHPAPI int vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) /* {{{ */
     794         7350884 : {
     795         7350884 :         smart_str xbuf = {0};
     796                 : 
     797         7350884 :         xbuf_format_converter(&xbuf, format, ap);
     798                 : 
     799         7350884 :         if (max_len && xbuf.len > max_len) {
     800               1 :                 xbuf.len = max_len;
     801                 :         }
     802         7350884 :         smart_str_0(&xbuf);
     803                 : 
     804         7350884 :         *pbuf = xbuf.c;
     805                 : 
     806         7350884 :         return xbuf.len;
     807                 : }
     808                 : /* }}} */
     809                 : 
     810                 : PHPAPI int spprintf(char **pbuf, size_t max_len, const char *format, ...) /* {{{ */
     811         1832145 : {
     812                 :         int cc;
     813                 :         va_list ap;
     814                 : 
     815         1832145 :         va_start(ap, format);
     816         1832145 :         cc = vspprintf(pbuf, max_len, format, ap);
     817         1832145 :         va_end(ap);
     818         1832145 :         return (cc);
     819                 : }
     820                 : /* }}} */
     821                 : 
     822                 : /*
     823                 :  * Local variables:
     824                 :  * tab-width: 4
     825                 :  * c-basic-offset: 4
     826                 :  * End:
     827                 :  * vim600: sw=4 ts=4 fdm=marker
     828                 :  * vim<600: sw=4 ts=4
     829                 :  */

Generated by: LTP GCOV extension version 1.5

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

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