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_2/main - spprintf.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 282
Code covered: 63.8 % Executed lines: 180
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 278043 2009-03-30 19:59:08Z iliaa $ */
      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                 : #if !HAVE_STRNLEN
     185                 : static size_t strnlen(const char *s, size_t maxlen) {
     186                 :         char *r = memchr(s, '\0', maxlen);
     187                 :         return r ? r-s : maxlen;
     188                 : }
     189                 : #endif
     190                 : 
     191                 : /*
     192                 :  * Do format conversion placing the output in buffer
     193                 :  */
     194                 : static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) /* {{{ */
     195         5999551 : {
     196         5999551 :         register char *s = NULL;
     197                 :         char *q;
     198                 :         int s_len;
     199                 : 
     200         5999551 :         register int min_width = 0;
     201         5999551 :         int precision = 0;
     202                 :         enum {
     203                 :                 LEFT, RIGHT
     204                 :         } adjust;
     205                 :         char pad_char;
     206                 :         char prefix_char;
     207                 : 
     208                 :         double fp_num;
     209         5999551 :         wide_int i_num = (wide_int) 0;
     210                 :         u_wide_int ui_num;
     211                 : 
     212                 :         char num_buf[NUM_BUF_SIZE];
     213                 :         char char_buf[2];                       /* for printing %% and %<unknown> */
     214                 : 
     215                 : #ifdef HAVE_LOCALE_H
     216         5999551 :         struct lconv *lconv = NULL;
     217                 : #endif
     218                 : 
     219                 :         /*
     220                 :          * Flag variables
     221                 :          */
     222                 :         length_modifier_e modifier;
     223                 :         boolean_e alternate_form;
     224                 :         boolean_e print_sign;
     225                 :         boolean_e print_blank;
     226                 :         boolean_e adjust_precision;
     227                 :         boolean_e adjust_width;
     228                 :         bool_int is_negative;
     229                 : 
     230        87964567 :         while (*fmt) {
     231        75965465 :                 if (*fmt != '%') {
     232        60694908 :                         INS_CHAR(xbuf, *fmt);
     233                 :                 } else {
     234                 :                         /*
     235                 :                          * Default variable settings
     236                 :                          */
     237        15270557 :                         adjust = RIGHT;
     238        15270557 :                         alternate_form = print_sign = print_blank = NO;
     239        15270557 :                         pad_char = ' ';
     240        15270557 :                         prefix_char = NUL;
     241                 : 
     242        15270557 :                         fmt++;
     243                 : 
     244                 :                         /*
     245                 :                          * Try to avoid checking for flags, width or precision
     246                 :                          */
     247        15444503 :                         if (isascii((int)*fmt) && !islower((int)*fmt)) {
     248                 :                                 /*
     249                 :                                  * Recognize flags: -, #, BLANK, +
     250                 :                                  */
     251           18570 :                                 for (;; fmt++) {
     252          192516 :                                         if (*fmt == '-')
     253              17 :                                                 adjust = LEFT;
     254          192499 :                                         else if (*fmt == '+')
     255               0 :                                                 print_sign = YES;
     256          192499 :                                         else if (*fmt == '#')
     257               0 :                                                 alternate_form = YES;
     258          192499 :                                         else if (*fmt == ' ')
     259               0 :                                                 print_blank = YES;
     260          192499 :                                         else if (*fmt == '0')
     261           18553 :                                                 pad_char = '0';
     262                 :                                         else
     263          173946 :                                                 break;
     264           18570 :                                 }
     265                 : 
     266                 :                                 /*
     267                 :                                  * Check if a width was specified
     268                 :                                  */
     269          173946 :                                 if (isdigit((int)*fmt)) {
     270           18336 :                                         STR_TO_DEC(fmt, min_width);
     271           18336 :                                         adjust_width = YES;
     272          155610 :                                 } else if (*fmt == '*') {
     273          130584 :                                         min_width = va_arg(ap, int);
     274          130584 :                                         fmt++;
     275          130584 :                                         adjust_width = YES;
     276          130584 :                                         if (min_width < 0) {
     277               0 :                                                 adjust = LEFT;
     278               0 :                                                 min_width = -min_width;
     279                 :                                         }
     280                 :                                 } else
     281           25026 :                                         adjust_width = NO;
     282                 : 
     283                 :                                 /*
     284                 :                                  * Check if a precision was specified
     285                 :                                  *
     286                 :                                  * XXX: an unreasonable amount of precision may be specified
     287                 :                                  * resulting in overflow of num_buf. Currently we
     288                 :                                  * ignore this possibility.
     289                 :                                  */
     290          173946 :                                 if (*fmt == '.') {
     291           25024 :                                         adjust_precision = YES;
     292           25024 :                                         fmt++;
     293           25024 :                                         if (isdigit((int)*fmt)) {
     294             492 :                                                 STR_TO_DEC(fmt, precision);
     295           24532 :                                         } else if (*fmt == '*') {
     296           24532 :                                                 precision = va_arg(ap, int);
     297           24532 :                                                 fmt++;
     298           24532 :                                                 if (precision < 0)
     299               0 :                                                         precision = 0;
     300                 :                                         } else
     301               0 :                                                 precision = 0;
     302                 :                                 } else
     303          148922 :                                         adjust_precision = NO;
     304                 :                         } else
     305        15096611 :                                 adjust_precision = adjust_width = NO;
     306                 : 
     307                 :                         /*
     308                 :                          * Modifier check
     309                 :                          */
     310        15270557 :                         switch (*fmt) {
     311                 :                                 case 'L':
     312               0 :                                         fmt++;
     313               0 :                                         modifier = LM_LONG_DOUBLE;
     314               0 :                                         break;
     315                 :                                 case 'I':
     316               0 :                                         fmt++;
     317                 : #if SIZEOF_LONG_LONG
     318               0 :                                         if (*fmt == '6' && *(fmt+1) == '4') {
     319               0 :                                                 fmt += 2;
     320               0 :                                                 modifier = LM_LONG_LONG;
     321                 :                                         } else
     322                 : #endif
     323               0 :                                                 if (*fmt == '3' && *(fmt+1) == '2') {
     324               0 :                                                         fmt += 2;
     325               0 :                                                         modifier = LM_LONG;
     326                 :                                                 } else {
     327                 : #ifdef _WIN64
     328                 :                                                         modifier = LM_LONG_LONG;
     329                 : #else
     330               0 :                                                         modifier = LM_LONG;
     331                 : #endif
     332                 :                                                 }
     333               0 :                                         break;
     334                 :                                 case 'l':
     335         2115663 :                                         fmt++;
     336                 : #if SIZEOF_LONG_LONG
     337         2115663 :                                         if (*fmt == 'l') {
     338               1 :                                                 fmt++;
     339               1 :                                                 modifier = LM_LONG_LONG;
     340                 :                                         } else
     341                 : #endif
     342         2115662 :                                                 modifier = LM_LONG;
     343         2115663 :                                         break;
     344                 :                                 case 'z':
     345               0 :                                         fmt++;
     346               0 :                                         modifier = LM_SIZE_T;
     347               0 :                                         break;
     348                 :                                 case 'j':
     349               0 :                                         fmt++;
     350                 : #if SIZEOF_INTMAX_T
     351               0 :                                         modifier = LM_INTMAX_T;
     352                 : #else
     353                 :                                         modifier = LM_SIZE_T;
     354                 : #endif
     355               0 :                                         break;
     356                 :                                 case 't':
     357               0 :                                         fmt++;
     358                 : #if SIZEOF_PTRDIFF_T
     359               0 :                                         modifier = LM_PTRDIFF_T;
     360                 : #else
     361                 :                                         modifier = LM_SIZE_T;
     362                 : #endif
     363               0 :                                         break;
     364                 :                                 case 'h':
     365               0 :                                         fmt++;
     366               0 :                                         if (*fmt == 'h') {
     367               0 :                                                 fmt++;
     368                 :                                         }
     369                 :                                         /* these are promoted to int, so no break */
     370                 :                                 default:                                
     371        13154894 :                                         modifier = LM_STD;
     372                 :                                         break;
     373                 :                         }
     374                 : 
     375                 :                         /*
     376                 :                          * Argument extraction and printing.
     377                 :                          * First we determine the argument type.
     378                 :                          * Then, we convert the argument to a string.
     379                 :                          * On exit from the switch, s points to the string that
     380                 :                          * must be printed, s_len has the length of the string
     381                 :                          * The precision requirements, if any, are reflected in s_len.
     382                 :                          *
     383                 :                          * NOTE: pad_char may be set to '0' because of the 0 flag.
     384                 :                          *   It is reset to ' ' by non-numeric formats
     385                 :                          */
     386        15270557 :                         switch (*fmt) {
     387                 :                                 case 'u':
     388             652 :                                         switch(modifier) {
     389                 :                                                 default:
     390             650 :                                                         i_num = (wide_int) va_arg(ap, unsigned int);
     391             650 :                                                         break;
     392                 :                                                 case LM_LONG_DOUBLE:
     393               0 :                                                         goto fmt_error;
     394                 :                                                 case LM_LONG:
     395               1 :                                                         i_num = (wide_int) va_arg(ap, unsigned long int);
     396               1 :                                                         break;
     397                 :                                                 case LM_SIZE_T:
     398               0 :                                                         i_num = (wide_int) va_arg(ap, size_t);
     399               0 :                                                         break;
     400                 : #if SIZEOF_LONG_LONG
     401                 :                                                 case LM_LONG_LONG:
     402               1 :                                                         i_num = (wide_int) va_arg(ap, u_wide_int);
     403               1 :                                                         break;
     404                 : #endif
     405                 : #if SIZEOF_INTMAX_T
     406                 :                                                 case LM_INTMAX_T:
     407               0 :                                                         i_num = (wide_int) va_arg(ap, uintmax_t);
     408               0 :                                                         break;
     409                 : #endif
     410                 : #if SIZEOF_PTRDIFF_T
     411                 :                                                 case LM_PTRDIFF_T:
     412               0 :                                                         i_num = (wide_int) va_arg(ap, ptrdiff_t);
     413                 :                                                         break;
     414                 : #endif
     415                 :                                         }
     416                 :                                         /*
     417                 :                                          * The rest also applies to other integer formats, so fall
     418                 :                                          * into that case.
     419                 :                                          */
     420                 :                                 case 'd':
     421                 :                                 case 'i':
     422                 :                                         /*
     423                 :                                          * Get the arg if we haven't already.
     424                 :                                          */
     425         4070091 :                                         if ((*fmt) != 'u') {
     426         4069439 :                                                 switch(modifier) {
     427                 :                                                         default:
     428         1953778 :                                                                 i_num = (wide_int) va_arg(ap, int);
     429         1953778 :                                                                 break;
     430                 :                                                         case LM_LONG_DOUBLE:
     431               0 :                                                                 goto fmt_error;
     432                 :                                                         case LM_LONG:
     433         2115661 :                                                                 i_num = (wide_int) va_arg(ap, long int);
     434         2115661 :                                                                 break;
     435                 :                                                         case LM_SIZE_T:
     436                 : #if SIZEOF_SSIZE_T
     437               0 :                                                                 i_num = (wide_int) va_arg(ap, ssize_t);
     438                 : #else
     439                 :                                                                 i_num = (wide_int) va_arg(ap, size_t);
     440                 : #endif
     441               0 :                                                                 break;
     442                 : #if SIZEOF_LONG_LONG
     443                 :                                                         case LM_LONG_LONG:
     444               0 :                                                                 i_num = (wide_int) va_arg(ap, wide_int);
     445               0 :                                                                 break;
     446                 : #endif
     447                 : #if SIZEOF_INTMAX_T
     448                 :                                                         case LM_INTMAX_T:
     449               0 :                                                                 i_num = (wide_int) va_arg(ap, intmax_t);
     450               0 :                                                                 break;
     451                 : #endif
     452                 : #if SIZEOF_PTRDIFF_T
     453                 :                                                         case LM_PTRDIFF_T:
     454               0 :                                                                 i_num = (wide_int) va_arg(ap, ptrdiff_t);
     455                 :                                                                 break;
     456                 : #endif
     457                 :                                                 }
     458                 :                                         }
     459         4070091 :                                         s = ap_php_conv_10(i_num, (*fmt) == 'u', &is_negative,
     460                 :                                                                 &num_buf[NUM_BUF_SIZE], &s_len);
     461         4070091 :                                         FIX_PRECISION(adjust_precision, precision, s, s_len);
     462                 : 
     463         4070091 :                                         if (*fmt != 'u') {
     464         4069439 :                                                 if (is_negative)
     465            4483 :                                                         prefix_char = '-';
     466         4064956 :                                                 else if (print_sign)
     467               0 :                                                         prefix_char = '+';
     468         4064956 :                                                 else if (print_blank)
     469               0 :                                                         prefix_char = ' ';
     470                 :                                         }
     471         4070091 :                                         break;
     472                 : 
     473                 : 
     474                 :                                 case 'o':
     475               2 :                                         switch(modifier) {
     476                 :                                                 default:
     477               2 :                                                         ui_num = (u_wide_int) va_arg(ap, unsigned int);
     478               2 :                                                         break;
     479                 :                                                 case LM_LONG_DOUBLE:
     480               0 :                                                         goto fmt_error;
     481                 :                                                 case LM_LONG:
     482               0 :                                                         ui_num = (u_wide_int) va_arg(ap, unsigned long int);
     483               0 :                                                         break;
     484                 :                                                 case LM_SIZE_T:
     485               0 :                                                         ui_num = (u_wide_int) va_arg(ap, size_t);
     486               0 :                                                         break;
     487                 : #if SIZEOF_LONG_LONG
     488                 :                                                 case LM_LONG_LONG:
     489               0 :                                                         ui_num = (u_wide_int) va_arg(ap, u_wide_int);
     490               0 :                                                         break;
     491                 : #endif
     492                 : #if SIZEOF_INTMAX_T
     493                 :                                                 case LM_INTMAX_T:
     494               0 :                                                         ui_num = (u_wide_int) va_arg(ap, uintmax_t);
     495               0 :                                                         break;
     496                 : #endif
     497                 : #if SIZEOF_PTRDIFF_T
     498                 :                                                 case LM_PTRDIFF_T:
     499               0 :                                                         ui_num = (u_wide_int) va_arg(ap, ptrdiff_t);
     500                 :                                                         break;
     501                 : #endif
     502                 :                                         }
     503               2 :                                         s = ap_php_conv_p2(ui_num, 3, *fmt,
     504                 :                                                                 &num_buf[NUM_BUF_SIZE], &s_len);
     505               2 :                                         FIX_PRECISION(adjust_precision, precision, s, s_len);
     506               2 :                                         if (alternate_form && *s != '0') {
     507               0 :                                                 *--s = '0';
     508               0 :                                                 s_len++;
     509                 :                                         }
     510               2 :                                         break;
     511                 : 
     512                 : 
     513                 :                                 case 'x':
     514                 :                                 case 'X':
     515           17975 :                                         switch(modifier) {
     516                 :                                                 default:
     517           17975 :                                                         ui_num = (u_wide_int) va_arg(ap, unsigned int);
     518           17975 :                                                         break;
     519                 :                                                 case LM_LONG_DOUBLE:
     520               0 :                                                         goto fmt_error;
     521                 :                                                 case LM_LONG:
     522               0 :                                                         ui_num = (u_wide_int) va_arg(ap, unsigned long int);
     523               0 :                                                         break;
     524                 :                                                 case LM_SIZE_T:
     525               0 :                                                         ui_num = (u_wide_int) va_arg(ap, size_t);
     526               0 :                                                         break;
     527                 : #if SIZEOF_LONG_LONG
     528                 :                                                 case LM_LONG_LONG:
     529               0 :                                                         ui_num = (u_wide_int) va_arg(ap, u_wide_int);
     530               0 :                                                         break;
     531                 : #endif
     532                 : #if SIZEOF_INTMAX_T
     533                 :                                                 case LM_INTMAX_T:
     534               0 :                                                         ui_num = (u_wide_int) va_arg(ap, uintmax_t);
     535               0 :                                                         break;
     536                 : #endif
     537                 : #if SIZEOF_PTRDIFF_T
     538                 :                                                 case LM_PTRDIFF_T:
     539               0 :                                                         ui_num = (u_wide_int) va_arg(ap, ptrdiff_t);
     540                 :                                                         break;
     541                 : #endif
     542                 :                                         }
     543           17975 :                                         s = ap_php_conv_p2(ui_num, 4, *fmt,
     544                 :                                                                 &num_buf[NUM_BUF_SIZE], &s_len);
     545           17975 :                                         FIX_PRECISION(adjust_precision, precision, s, s_len);
     546           17975 :                                         if (alternate_form && i_num != 0) {
     547               0 :                                                 *--s = *fmt;    /* 'x' or 'X' */
     548               0 :                                                 *--s = '0';
     549               0 :                                                 s_len += 2;
     550                 :                                         }
     551           17975 :                                         break;
     552                 : 
     553                 : 
     554                 :                                 case 's':
     555                 :                                 case 'v':
     556        11017023 :                                         s = va_arg(ap, char *);
     557        11017023 :                                         if (s != NULL) {
     558        11017015 :                                                 if (!adjust_precision) {
     559        11016775 :                                                         s_len = strlen(s);
     560                 :                                                 } else {
     561             240 :                                                         s_len = strnlen(s, precision);
     562                 :                                                 }
     563                 :                                         } else {
     564               8 :                                                 s = S_NULL;
     565               8 :                                                 s_len = S_NULL_LEN;
     566                 :                                         }
     567        11017023 :                                         pad_char = ' ';
     568        11017023 :                                         break;
     569                 : 
     570                 : 
     571                 :                                 case 'f':
     572                 :                                 case 'F':
     573                 :                                 case 'e':
     574                 :                                 case 'E':
     575             322 :                                         switch(modifier) {
     576                 :                                                 case LM_LONG_DOUBLE:
     577               0 :                                                         fp_num = (double) va_arg(ap, long double);
     578               0 :                                                         break;
     579                 :                                                 case LM_STD:
     580             322 :                                                         fp_num = va_arg(ap, double);
     581             322 :                                                         break;
     582                 :                                                 default:
     583               0 :                                                         goto fmt_error;
     584                 :                                         }
     585                 : 
     586             322 :                                         if (zend_isnan(fp_num)) {
     587               0 :                                                 s = "nan";
     588               0 :                                                 s_len = 3;
     589             322 :                                         } else if (zend_isinf(fp_num)) {
     590               2 :                                                 s = "inf";
     591               2 :                                                 s_len = 3;
     592                 :                                         } else {
     593                 : #ifdef HAVE_LOCALE_H
     594             320 :                                                 if (!lconv) {
     595             320 :                                                         lconv = localeconv();
     596                 :                                                 }
     597                 : #endif
     598             320 :                                                 s = php_conv_fp((*fmt == 'f')?'F':*fmt, fp_num, alternate_form,
     599                 :                                                  (adjust_precision == NO) ? FLOAT_DIGITS : precision,
     600                 :                                                  (*fmt == 'f')?LCONV_DECIMAL_POINT:'.',
     601                 :                                                                         &is_negative, &num_buf[1], &s_len);
     602             320 :                                                 if (is_negative)
     603               1 :                                                         prefix_char = '-';
     604             319 :                                                 else if (print_sign)
     605               0 :                                                         prefix_char = '+';
     606             319 :                                                 else if (print_blank)
     607               0 :                                                         prefix_char = ' ';
     608                 :                                         }
     609             322 :                                         break;
     610                 : 
     611                 : 
     612                 :                                 case 'g':
     613                 :                                 case 'k':
     614                 :                                 case 'G':
     615                 :                                 case 'H':
     616           24462 :                                         switch(modifier) {
     617                 :                                                 case LM_LONG_DOUBLE:
     618               0 :                                                         fp_num = (double) va_arg(ap, long double);
     619               0 :                                                         break;
     620                 :                                                 case LM_STD:
     621           24462 :                                                         fp_num = va_arg(ap, double);
     622           24462 :                                                         break;
     623                 :                                                 default:
     624               0 :                                                         goto fmt_error;
     625                 :                                         }
     626                 : 
     627           24462 :                                         if (zend_isnan(fp_num)) {
     628            1529 :                                                 s = "NAN";
     629            1529 :                                                 s_len = 3;
     630            1529 :                                                 break;
     631           22933 :                                         } else if (zend_isinf(fp_num)) {
     632            1545 :                                                 if (fp_num > 0) {
     633            1515 :                                                         s = "INF";
     634            1515 :                                                         s_len = 3;
     635                 :                                                 } else {
     636              30 :                                                         s = "-INF";
     637              30 :                                                         s_len = 4;
     638                 :                                                 }
     639            1545 :                                                 break;
     640                 :                                         }
     641                 : 
     642           21388 :                                         if (adjust_precision == NO)
     643               0 :                                                 precision = FLOAT_DIGITS;
     644           21388 :                                         else if (precision == 0)
     645               0 :                                                 precision = 1;
     646                 :                                         /*
     647                 :                                          * * We use &num_buf[ 1 ], so that we have room for the sign
     648                 :                                          */
     649                 : #ifdef HAVE_LOCALE_H
     650           21388 :                                         if (!lconv) {
     651           21388 :                                                 lconv = localeconv();
     652                 :                                         }
     653                 : #endif
     654           21388 :                                         s = php_gcvt(fp_num, precision, (*fmt=='H' || *fmt == 'k') ? '.' : LCONV_DECIMAL_POINT, (*fmt == 'G' || *fmt == 'H')?'E':'e', &num_buf[1]);
     655           21388 :                                         if (*s == '-')
     656            2331 :                                                 prefix_char = *s++;
     657           19057 :                                         else if (print_sign)
     658               0 :                                                 prefix_char = '+';
     659           19057 :                                         else if (print_blank)
     660               0 :                                                 prefix_char = ' ';
     661                 : 
     662           21388 :                                         s_len = strlen(s);
     663                 : 
     664           21388 :                                         if (alternate_form && (q = strchr(s, '.')) == NULL)
     665               0 :                                                 s[s_len++] = '.';
     666           21388 :                                         break;
     667                 : 
     668                 : 
     669                 :                                 case 'c':
     670          140679 :                                         char_buf[0] = (char) (va_arg(ap, int));
     671          140679 :                                         s = &char_buf[0];
     672          140679 :                                         s_len = 1;
     673          140679 :                                         pad_char = ' ';
     674          140679 :                                         break;
     675                 : 
     676                 : 
     677                 :                                 case '%':
     678               2 :                                         char_buf[0] = '%';
     679               2 :                                         s = &char_buf[0];
     680               2 :                                         s_len = 1;
     681               2 :                                         pad_char = ' ';
     682               2 :                                         break;
     683                 : 
     684                 : 
     685                 :                                 case 'n':
     686               0 :                                         *(va_arg(ap, int *)) = xbuf->len;
     687               0 :                                         goto skip_output;
     688                 : 
     689                 :                                         /*
     690                 :                                          * Always extract the argument as a "char *" pointer. We 
     691                 :                                          * should be using "void *" but there are still machines 
     692                 :                                          * that don't understand it.
     693                 :                                          * If the pointer size is equal to the size of an unsigned
     694                 :                                          * integer we convert the pointer to a hex number, otherwise 
     695                 :                                          * we print "%p" to indicate that we don't handle "%p".
     696                 :                                          */
     697                 :                                 case 'p':
     698                 :                                         if (sizeof(char *) <= sizeof(u_wide_int)) {
     699               1 :                                                 ui_num = (u_wide_int)((size_t) va_arg(ap, char *));
     700               1 :                                                 s = ap_php_conv_p2(ui_num, 4, 'x', 
     701                 :                                                                 &num_buf[NUM_BUF_SIZE], &s_len);
     702               1 :                                                 if (ui_num != 0) {
     703               1 :                                                         *--s = 'x';
     704               1 :                                                         *--s = '0';
     705               1 :                                                         s_len += 2;
     706                 :                                                 }
     707                 :                                         } else {
     708                 :                                                 s = "%p";
     709                 :                                                 s_len = 2;
     710                 :                                         }
     711               1 :                                         pad_char = ' ';
     712               1 :                                         break;
     713                 : 
     714                 : 
     715                 :                                 case NUL:
     716                 :                                         /*
     717                 :                                          * The last character of the format string was %.
     718                 :                                          * We ignore it.
     719                 :                                          */
     720               0 :                                         continue;
     721                 : 
     722                 : 
     723               0 : fmt_error:
     724               0 :                                 php_error(E_ERROR, "Illegal length modifier specified '%c' in s[np]printf call", *fmt);
     725                 :                                         /*
     726                 :                                          * The default case is for unrecognized %'s.
     727                 :                                          * We print %<char> to help the user identify what
     728                 :                                          * option is not understood.
     729                 :                                          * This is also useful in case the user wants to pass
     730                 :                                          * the output of format_converter to another function
     731                 :                                          * that understands some other %<char> (like syslog).
     732                 :                                          * Note that we can't point s inside fmt because the
     733                 :                                          * unknown <char> could be preceded by width etc.
     734                 :                                          */
     735                 :                                 default:
     736               0 :                                         char_buf[0] = '%';
     737               0 :                                         char_buf[1] = *fmt;
     738               0 :                                         s = char_buf;
     739               0 :                                         s_len = 2;
     740               0 :                                         pad_char = ' ';
     741                 :                                         break;
     742                 :                         }
     743                 : 
     744        15270557 :                         if (prefix_char != NUL) {
     745            6815 :                                 *--s = prefix_char;
     746            6815 :                                 s_len++;
     747                 :                         }
     748        15270557 :                         if (adjust_width && adjust == RIGHT && min_width > s_len) {
     749          131458 :                                 if (pad_char == '0' && prefix_char != NUL) {
     750               0 :                                         INS_CHAR(xbuf, *s);
     751               0 :                                         s++;
     752               0 :                                         s_len--;
     753               0 :                                         min_width--;
     754                 :                                 }
     755          131458 :                                 PAD(xbuf, min_width - s_len, pad_char);
     756                 :                         }
     757                 :                         /*
     758                 :                          * Print the string s. 
     759                 :                          */
     760        15270557 :                         INS_STRING(xbuf, s, s_len);
     761                 : 
     762        15270557 :                         if (adjust_width && adjust == LEFT && min_width > s_len)
     763              17 :                                 PAD(xbuf, min_width - s_len, pad_char);
     764                 :                 }
     765        75965465 : skip_output:
     766        75965465 :                 fmt++;
     767                 :         }
     768                 :         return;
     769                 : }
     770                 : /* }}} */
     771                 : 
     772                 : /*
     773                 :  * This is the general purpose conversion function.
     774                 :  */
     775                 : PHPAPI int vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) /* {{{ */
     776         5999551 : {
     777         5999551 :         smart_str xbuf = {0};
     778                 : 
     779         5999551 :         xbuf_format_converter(&xbuf, format, ap);
     780                 :         
     781         5999551 :         if (max_len && xbuf.len > max_len) {
     782               0 :                 xbuf.len = max_len;
     783                 :         }
     784         5999551 :         smart_str_0(&xbuf);
     785                 :                 
     786         5999551 :         *pbuf = xbuf.c;
     787                 :         
     788         5999551 :         return xbuf.len;
     789                 : }
     790                 : /* }}} */
     791                 : 
     792                 : PHPAPI int spprintf(char **pbuf, size_t max_len, const char *format, ...) /* {{{ */
     793         1406476 : {
     794                 :         int cc;
     795                 :         va_list ap;
     796                 : 
     797         1406476 :         va_start(ap, format);
     798         1406476 :         cc = vspprintf(pbuf, max_len, format, ap);
     799         1406476 :         va_end(ap);
     800         1406476 :         return (cc);
     801                 : }
     802                 : /* }}} */
     803                 : 
     804                 : /*
     805                 :  * Local variables:
     806                 :  * tab-width: 4
     807                 :  * c-basic-offset: 4
     808                 :  * End:
     809                 :  * vim600: sw=4 ts=4 fdm=marker
     810                 :  * vim<600: sw=4 ts=4
     811                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:28 +0000 (5 days ago)

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