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_HEAD/main - spprintf.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 356
Code covered: 69.1 % Executed lines: 246
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 6                                                        |
       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 277841 2009-03-26 20:02:53Z felipe $ */
      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                 : 
      80                 : #define _GNU_SOURCE
      81                 : #include "php.h"
      82                 : 
      83                 : #include <stddef.h>
      84                 : #include <stdio.h>
      85                 : #include <ctype.h>
      86                 : #include <sys/types.h>
      87                 : #include <stdarg.h>
      88                 : #include <string.h>
      89                 : #include <stdlib.h>
      90                 : #include <math.h>
      91                 : #ifdef HAVE_INTTYPES_H
      92                 : #include <inttypes.h>
      93                 : #endif
      94                 : 
      95                 : #ifdef HAVE_LOCALE_H
      96                 : #include <locale.h>
      97                 : #define LCONV_DECIMAL_POINT (*lconv->decimal_point)
      98                 : #else
      99                 : #define LCONV_DECIMAL_POINT '.'
     100                 : #endif
     101                 : 
     102                 : #include "snprintf.h"
     103                 : 
     104                 : #define FALSE           0
     105                 : #define TRUE            1
     106                 : #define NUL             '\0'
     107                 : #define INT_NULL        ((int *)0)
     108                 : 
     109                 : #define S_NULL          "(null)"
     110                 : #define S_NULL_LEN      6
     111                 : 
     112                 : #define FLOAT_DIGITS    6
     113                 : #define EXPONENT_LENGTH 10
     114                 : 
     115                 : #include "ext/standard/php_smart_str.h"
     116                 : 
     117                 : /* {{{ macros */
     118                 : 
     119                 : /*
     120                 :  * NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions
     121                 :  *
     122                 :  * XXX: this is a magic number; do not decrease it
     123                 :  */
     124                 : #define NUM_BUF_SIZE    512
     125                 : 
     126                 : /*
     127                 :  * The INS_CHAR macro inserts a character in the buffer.
     128                 :  *
     129                 :  * NOTE: Evaluation of the ch argument should not have any side-effects
     130                 :  */
     131                 : #define INS_CHAR_NR(unicode, xbuf, ch) do {                     \
     132                 :         if (unicode) {                                                                  \
     133                 :                 smart_str_append2c(xbuf, ch);                           \
     134                 :         } else {                                                                                \
     135                 :                 smart_str_appendc(xbuf, ch);                            \
     136                 :         }                                                                                               \
     137                 : } while (0)
     138                 : 
     139                 : #define INS_STRING(unicode, s_unicode, xbuf, s, s_len)  \
     140                 : do {                                                                                            \
     141                 :         if (unicode) {                                                                  \
     142                 :                 size_t newlen, p, sz = 2*(s_len);                       \
     143                 :                 smart_str_alloc(xbuf, (sz), 0);                         \
     144                 :                 if (s_unicode) {                                                        \
     145                 :                         memcpy(xbuf->c + xbuf->len, s, (sz));     \
     146                 :                         xbuf->len += sz;                                             \
     147                 :                 } else {                                                                        \
     148                 :                         p = (s_len);                                                    \
     149                 :                         while(p--) {                            \
     150                 :                                 smart_str_append2c(xbuf, *s);           \
     151                 :                                 *s++;                                                           \
     152                 :                         }                                                                               \
     153                 :                 }                                                                                       \
     154                 :         } else {                                                                                \
     155                 :                 smart_str_appendl(xbuf, s, s_len);                      \
     156                 :         }                                                                                               \
     157                 : } while (0)
     158                 : 
     159                 : #define INS_CHAR(unicode, xbuf, ch)                                     \
     160                 :         INS_CHAR_NR(unicode, xbuf, ch)
     161                 : 
     162                 : /*
     163                 :  * Macro that does padding. The padding is done by printing
     164                 :  * the character ch.
     165                 :  */
     166                 : #define PAD(unicode, xbuf, count, ch) do {                      \
     167                 :         if ((count) > 0) {                                   \
     168                 :                 size_t newlen, p, sz = (count);                         \
     169                 :                 if (unicode) {                                                          \
     170                 :                         p = sz;                                                                 \
     171                 :                         sz <<= 1;                                                         \
     172                 :                         smart_str_alloc(xbuf, sz, 0);                   \
     173                 :                         while(p--) smart_str_append2c(xbuf, ch);\
     174                 :                 } else {                                                                        \
     175                 :                         smart_str_alloc(xbuf, sz, 0);                   \
     176                 :                         memset(xbuf->c + xbuf->len, ch, sz);      \
     177                 :                         xbuf->len += sz;                                             \
     178                 :                 }                                                                                       \
     179                 :         }                                                                                               \
     180                 : } while (0)
     181                 : 
     182                 : #define NUM(c) (c - '0')
     183                 : 
     184                 : #define STR_TO_DEC(str, num) do {                                       \
     185                 :         num = NUM(*str++);                                      \
     186                 :         while (isdigit((int)*str)) {                            \
     187                 :                 num *= 10;                                              \
     188                 :                 num += NUM(*str++);                                     \
     189                 :                 if (num >= INT_MAX / 10) {                                   \
     190                 :                         while (isdigit((int)*str++));                   \
     191                 :                         break;                                                                  \
     192                 :                 }                                                                                       \
     193                 :     }                                                                                           \
     194                 : } while (0)
     195                 : 
     196                 : /*
     197                 :  * This macro does zero padding so that the precision
     198                 :  * requirement is satisfied. The padding is done by
     199                 :  * adding '0's to the left of the string that is going
     200                 :  * to be printed.
     201                 :  */
     202                 : #define FIX_PRECISION(adjust, precision, s, s_len)  \
     203                 :         do {                                                                                    \
     204                 :     if (adjust)                                                                         \
     205                 :                 while (s_len < precision) {                                  \
     206                 :                         *--s = '0';                                                             \
     207                 :                         s_len++;                                                                \
     208                 :                 }                                                                                       \
     209                 : } while (0)
     210                 : 
     211                 : /* }}} */
     212                 : 
     213                 : 
     214                 : #if !HAVE_STRNLEN
     215                 : static size_t strnlen(const char *s, size_t maxlen) {
     216                 :         char *r = memchr(s, '\0', maxlen);
     217                 :         return r ? r-s : maxlen;
     218                 : }
     219                 : #endif
     220                 : 
     221                 : /*
     222                 :  * Do format conversion placing the output in buffer
     223                 :  */
     224                 : static void xbuf_format_converter(int unicode, smart_str *xbuf, const char *fmt, va_list ap) /* {{{ */
     225         6377948 : {
     226         6377948 :         char *s = NULL;
     227         6377948 :         UChar *u = NULL;
     228                 :         char *q;
     229                 :         int s_len, s_unicode, u_len, free_zcopy;
     230                 :         zval *zvp, zcopy;
     231         6377948 :         int min_width = 0;
     232         6377948 :         int precision = 0;
     233                 :         enum {
     234                 :                 LEFT, RIGHT
     235                 :         } adjust;
     236                 :         char pad_char;
     237                 :         char prefix_char;
     238                 : 
     239                 :         double fp_num;
     240         6377948 :         wide_int i_num = (wide_int) 0;
     241                 :         u_wide_int ui_num;
     242                 : 
     243                 :         char num_buf[NUM_BUF_SIZE];
     244                 :         char char_buf[2]; /* for printing %% and %<unknown> */
     245                 :         zend_bool free_s; /* free string if allocated here */
     246                 : 
     247                 : #ifdef HAVE_LOCALE_H
     248         6377948 :         struct lconv *lconv = NULL;
     249                 : #endif
     250                 : 
     251                 :         /*
     252                 :          * Flag variables
     253                 :          */
     254                 :         length_modifier_e modifier;
     255                 :         boolean_e alternate_form;
     256                 :         boolean_e print_sign;
     257                 :         boolean_e print_blank;
     258                 :         boolean_e adjust_precision;
     259                 :         boolean_e adjust_width;
     260                 :         bool_int is_negative;
     261                 : 
     262                 :         TSRMLS_FETCH();
     263                 : 
     264       111952782 :         while (*fmt) {
     265        99196886 :                 if (*fmt != '%') {
     266        80643677 :                         INS_CHAR(unicode, xbuf, *fmt);
     267                 :                 } else {
     268                 :                         /*
     269                 :                          * Default variable settings
     270                 :                          */
     271        18553209 :                         adjust = RIGHT;
     272        18553209 :                         alternate_form = print_sign = print_blank = NO;
     273        18553209 :                         pad_char = ' ';
     274        18553209 :                         prefix_char = NUL;
     275        18553209 :                         free_s = 0;
     276        18553209 :                         free_zcopy = 0;
     277        18553209 :                         s_unicode = 0;
     278                 : 
     279        18553209 :                         fmt++;
     280                 : 
     281                 :                         /*
     282                 :                          * Try to avoid checking for flags, width or precision
     283                 :                          */
     284        18845722 :                         if (isascii((int)*fmt) && !islower((int)*fmt)) {
     285                 :                                 /*
     286                 :                                  * Recognize flags: -, #, BLANK, +
     287                 :                                  */
     288           19708 :                                 for (;; fmt++) {
     289          312221 :                                         if (*fmt == '-')
     290              20 :                                                 adjust = LEFT;
     291          312201 :                                         else if (*fmt == '+')
     292               0 :                                                 print_sign = YES;
     293          312201 :                                         else if (*fmt == '#')
     294               0 :                                                 alternate_form = YES;
     295          312201 :                                         else if (*fmt == ' ')
     296               0 :                                                 print_blank = YES;
     297          312201 :                                         else if (*fmt == '0')
     298           19688 :                                                 pad_char = '0';
     299                 :                                         else
     300          292513 :                                                 break;
     301           19708 :                                 }
     302                 : 
     303                 :                                 /*
     304                 :                                  * Check if a width was specified
     305                 :                                  */
     306          292513 :                                 if (isdigit((int)*fmt)) {
     307           19598 :                                         STR_TO_DEC(fmt, min_width);
     308           19598 :                                         adjust_width = YES;
     309          272915 :                                 } else if (*fmt == '*') {
     310          144339 :                                         min_width = va_arg(ap, int);
     311          144339 :                                         fmt++;
     312          144339 :                                         adjust_width = YES;
     313          144339 :                                         if (min_width < 0) {
     314               0 :                                                 adjust = LEFT;
     315               0 :                                                 min_width = -min_width;
     316                 :                                         }
     317                 :                                 } else
     318          128576 :                                         adjust_width = NO;
     319                 : 
     320                 :                                 /*
     321                 :                                  * Check if a precision was specified
     322                 :                                  *
     323                 :                                  * XXX: an unreasonable amount of precision may be specified
     324                 :                                  * resulting in overflow of num_buf. Currently we
     325                 :                                  * ignore this possibility.
     326                 :                                  */
     327          292513 :                                 if (*fmt == '.') {
     328            8761 :                                         adjust_precision = YES;
     329            8761 :                                         fmt++;
     330            8761 :                                         if (isdigit((int)*fmt)) {
     331             390 :                                                 STR_TO_DEC(fmt, precision);
     332            8371 :                                         } else if (*fmt == '*') {
     333            8371 :                                                 precision = va_arg(ap, int);
     334            8371 :                                                 fmt++;
     335            8371 :                                                 if (precision < 0)
     336               0 :                                                         precision = 0;
     337                 :                                         } else
     338               0 :                                                 precision = 0;
     339                 :                                 } else
     340          283752 :                                         adjust_precision = NO;
     341                 :                         } else
     342        18260696 :                                 adjust_precision = adjust_width = NO;
     343                 : 
     344                 :                         /*
     345                 :                          * Modifier check
     346                 :                          */
     347        18553209 :                         switch (*fmt) {
     348                 :                                 case 'L':
     349               0 :                                         fmt++;
     350               0 :                                         modifier = LM_LONG_DOUBLE;
     351               0 :                                         break;
     352                 :                                 case 'I':
     353               0 :                                         fmt++;
     354                 : #if SIZEOF_LONG_LONG
     355               0 :                                         if (*fmt == '6' && *(fmt+1) == '4') {
     356               0 :                                                 fmt += 2;
     357               0 :                                                 modifier = LM_LONG_LONG;
     358                 :                                         } else
     359                 : #endif
     360               0 :                                                 if (*fmt == '3' && *(fmt+1) == '2') {
     361               0 :                                                         fmt += 2;
     362               0 :                                                         modifier = LM_LONG;
     363                 :                                                 } else {
     364                 : #ifdef _WIN64
     365                 :                                                         modifier = LM_LONG_LONG;
     366                 : #else
     367               0 :                                                         modifier = LM_LONG;
     368                 : #endif
     369                 :                                                 }
     370               0 :                                         break;
     371                 :                                 case 'l':
     372         1297941 :                                         fmt++;
     373                 : #if SIZEOF_LONG_LONG
     374         1297941 :                                         if (*fmt == 'l') {
     375            2389 :                                                 fmt++;
     376            2389 :                                                 modifier = LM_LONG_LONG;
     377                 :                                         } else
     378                 : #endif
     379         1295552 :                                                 modifier = LM_LONG;
     380         1297941 :                                         break;
     381                 :                                 case 'z':
     382               3 :                                         fmt++;
     383               3 :                                         modifier = LM_SIZE_T;
     384               3 :                                         break;
     385                 :                                 case 'j':
     386               0 :                                         fmt++;
     387                 : #if SIZEOF_INTMAX_T
     388               0 :                                         modifier = LM_INTMAX_T;
     389                 : #else
     390                 :                                         modifier = LM_SIZE_T;
     391                 : #endif
     392               0 :                                         break;
     393                 :                                 case 't':
     394               0 :                                         fmt++;
     395                 : #if SIZEOF_PTRDIFF_T
     396               0 :                                         modifier = LM_PTRDIFF_T;
     397                 : #else
     398                 :                                         modifier = LM_SIZE_T;
     399                 : #endif
     400               0 :                                         break;
     401                 :                                 case 'h':
     402               0 :                                         fmt++;
     403               0 :                                         if (*fmt == 'h') {
     404               0 :                                                 fmt++;
     405                 :                                         }
     406                 :                                         /* these are promoted to int, so no break */
     407                 :                                 default:
     408        17255265 :                                         modifier = LM_STD;
     409                 :                                         break;
     410                 :                         }
     411                 : 
     412                 :                         /*
     413                 :                          * Argument extraction and printing.
     414                 :                          * First we determine the argument type.
     415                 :                          * Then, we convert the argument to a string.
     416                 :                          * On exit from the switch, s points to the string that
     417                 :                          * must be printed, s_len has the length of the string
     418                 :                          * The precision requirements, if any, are reflected in s_len.
     419                 :                          *
     420                 :                          * NOTE: pad_char may be set to '0' because of the 0 flag.
     421                 :                          *   It is reset to ' ' by non-numeric formats
     422                 :                          */
     423        18553209 :                         switch (*fmt) {
     424                 :                                 case 'Z':
     425             184 :                                         zvp = (zval*) va_arg(ap, zval*);
     426             184 :                                         if (unicode) {
     427               0 :                                                 zend_make_unicode_zval(zvp, &zcopy, &free_zcopy);
     428               0 :                                                 s_unicode = 1;
     429                 :                                         } else {
     430             184 :                                                 zend_make_string_zval(zvp, &zcopy, &free_zcopy);
     431                 :                                         }
     432             184 :                                         if (free_zcopy) {
     433             184 :                                                 zvp = &zcopy;
     434                 :                                         }
     435             184 :                                         s_len = Z_UNILEN_P(zvp);
     436             184 :                                         s = Z_STRVAL_P(zvp);
     437             184 :                                         if (adjust_precision && precision < s_len) {
     438               0 :                                                 s_len = precision;
     439                 :                                         }
     440             184 :                                         break;
     441                 :                                 case 'u':
     442            1027 :                                         switch(modifier) {
     443                 :                                                 default:
     444            1025 :                                                         i_num = (wide_int) va_arg(ap, unsigned int);
     445            1025 :                                                         break;
     446                 :                                                 case LM_LONG_DOUBLE:
     447               0 :                                                         goto fmt_error;
     448                 :                                                 case LM_LONG:
     449               1 :                                                         i_num = (wide_int) va_arg(ap, unsigned long int);
     450               1 :                                                         break;
     451                 :                                                 case LM_SIZE_T:
     452               0 :                                                         i_num = (wide_int) va_arg(ap, size_t);
     453               0 :                                                         break;
     454                 : #if SIZEOF_LONG_LONG
     455                 :                                                 case LM_LONG_LONG:
     456               1 :                                                         i_num = (wide_int) va_arg(ap, u_wide_int);
     457               1 :                                                         break;
     458                 : #endif
     459                 : #if SIZEOF_INTMAX_T
     460                 :                                                 case LM_INTMAX_T:
     461               0 :                                                         i_num = (wide_int) va_arg(ap, uintmax_t);
     462               0 :                                                         break;
     463                 : #endif
     464                 : #if SIZEOF_PTRDIFF_T
     465                 :                                                 case LM_PTRDIFF_T:
     466               0 :                                                         i_num = (wide_int) va_arg(ap, ptrdiff_t);
     467                 :                                                         break;
     468                 : #endif
     469                 :                                         }
     470                 :                                         /*
     471                 :                                          * The rest also applies to other integer formats, so fall
     472                 :                                          * into that case.
     473                 :                                          */
     474                 :                                 case 'd':
     475                 :                                 case 'i':
     476                 :                                         /*
     477                 :                                          * Get the arg if we haven't already.
     478                 :                                          */
     479         3910383 :                                         if ((*fmt) != 'u') {
     480         3909356 :                                                 switch(modifier) {
     481                 :                                                         default:
     482         2611414 :                                                                 i_num = (wide_int) va_arg(ap, int);
     483         2611414 :                                                                 break;
     484                 :                                                         case LM_LONG_DOUBLE:
     485               0 :                                                                 goto fmt_error;
     486                 :                                                         case LM_LONG:
     487         1295551 :                                                                 i_num = (wide_int) va_arg(ap, long int);
     488         1295551 :                                                                 break;
     489                 :                                                         case LM_SIZE_T:
     490                 : #if SIZEOF_SSIZE_T
     491               3 :                                                                 i_num = (wide_int) va_arg(ap, ssize_t);
     492                 : #else
     493                 :                                                                 i_num = (wide_int) va_arg(ap, size_t);
     494                 : #endif
     495               3 :                                                                 break;
     496                 : #if SIZEOF_LONG_LONG
     497                 :                                                         case LM_LONG_LONG:
     498            2388 :                                                                 i_num = (wide_int) va_arg(ap, wide_int);
     499            2388 :                                                                 break;
     500                 : #endif
     501                 : #if SIZEOF_INTMAX_T
     502                 :                                                         case LM_INTMAX_T:
     503               0 :                                                                 i_num = (wide_int) va_arg(ap, intmax_t);
     504               0 :                                                                 break;
     505                 : #endif
     506                 : #if SIZEOF_PTRDIFF_T
     507                 :                                                         case LM_PTRDIFF_T:
     508               0 :                                                                 i_num = (wide_int) va_arg(ap, ptrdiff_t);
     509                 :                                                                 break;
     510                 : #endif
     511                 :                                                 }
     512                 :                                         }
     513         3910383 :                                         s = ap_php_conv_10(i_num, (*fmt) == 'u', &is_negative,
     514                 :                                                                 &num_buf[NUM_BUF_SIZE], &s_len);
     515         3910383 :                                         FIX_PRECISION(adjust_precision, precision, s, s_len);
     516                 : 
     517         3910383 :                                         if (*fmt != 'u') {
     518         3909356 :                                                 if (is_negative)
     519            2731 :                                                         prefix_char = '-';
     520         3906625 :                                                 else if (print_sign)
     521               0 :                                                         prefix_char = '+';
     522         3906625 :                                                 else if (print_blank)
     523               0 :                                                         prefix_char = ' ';
     524                 :                                         }
     525         3910383 :                                         break;
     526                 : 
     527                 : 
     528                 :                                 case 'o':
     529               2 :                                         switch(modifier) {
     530                 :                                                 default:
     531               2 :                                                         ui_num = (u_wide_int) va_arg(ap, unsigned int);
     532               2 :                                                         break;
     533                 :                                                 case LM_LONG_DOUBLE:
     534               0 :                                                         goto fmt_error;
     535                 :                                                 case LM_LONG:
     536               0 :                                                         ui_num = (u_wide_int) va_arg(ap, unsigned long int);
     537               0 :                                                         break;
     538                 :                                                 case LM_SIZE_T:
     539               0 :                                                         ui_num = (u_wide_int) va_arg(ap, size_t);
     540               0 :                                                         break;
     541                 : #if SIZEOF_LONG_LONG
     542                 :                                                 case LM_LONG_LONG:
     543               0 :                                                         ui_num = (u_wide_int) va_arg(ap, u_wide_int);
     544               0 :                                                         break;
     545                 : #endif
     546                 : #if SIZEOF_INTMAX_T
     547                 :                                                 case LM_INTMAX_T:
     548               0 :                                                         ui_num = (u_wide_int) va_arg(ap, uintmax_t);
     549               0 :                                                         break;
     550                 : #endif
     551                 : #if SIZEOF_PTRDIFF_T
     552                 :                                                 case LM_PTRDIFF_T:
     553               0 :                                                         ui_num = (u_wide_int) va_arg(ap, ptrdiff_t);
     554                 :                                                         break;
     555                 : #endif
     556                 :                                         }
     557               2 :                                         s = ap_php_conv_p2(ui_num, 3, *fmt,
     558                 :                                                                 &num_buf[NUM_BUF_SIZE], &s_len);
     559               2 :                                         FIX_PRECISION(adjust_precision, precision, s, s_len);
     560               2 :                                         if (alternate_form && *s != '0') {
     561               0 :                                                 *--s = '0';
     562               0 :                                                 s_len++;
     563                 :                                         }
     564               2 :                                         break;
     565                 : 
     566                 : 
     567                 :                                 case 'x':
     568                 :                                 case 'X':
     569             854 :                                         switch(modifier) {
     570                 :                                                 default:
     571             854 :                                                         ui_num = (u_wide_int) va_arg(ap, unsigned int);
     572             854 :                                                         break;
     573                 :                                                 case LM_LONG_DOUBLE:
     574               0 :                                                         goto fmt_error;
     575                 :                                                 case LM_LONG:
     576               0 :                                                         ui_num = (u_wide_int) va_arg(ap, unsigned long int);
     577               0 :                                                         break;
     578                 :                                                 case LM_SIZE_T:
     579               0 :                                                         ui_num = (u_wide_int) va_arg(ap, size_t);
     580               0 :                                                         break;
     581                 : #if SIZEOF_LONG_LONG
     582                 :                                                 case LM_LONG_LONG:
     583               0 :                                                         ui_num = (u_wide_int) va_arg(ap, u_wide_int);
     584               0 :                                                         break;
     585                 : #endif
     586                 : #if SIZEOF_INTMAX_T
     587                 :                                                 case LM_INTMAX_T:
     588               0 :                                                         ui_num = (u_wide_int) va_arg(ap, uintmax_t);
     589               0 :                                                         break;
     590                 : #endif
     591                 : #if SIZEOF_PTRDIFF_T
     592                 :                                                 case LM_PTRDIFF_T:
     593               0 :                                                         ui_num = (u_wide_int) va_arg(ap, ptrdiff_t);
     594                 :                                                         break;
     595                 : #endif
     596                 :                                         }
     597             854 :                                         s = ap_php_conv_p2(ui_num, 4, *fmt,
     598                 :                                                                 &num_buf[NUM_BUF_SIZE], &s_len);
     599             854 :                                         FIX_PRECISION(adjust_precision, precision, s, s_len);
     600             854 :                                         if (alternate_form && i_num != 0) {
     601               0 :                                                 *--s = *fmt;    /* 'x' or 'X' */
     602               0 :                                                 *--s = '0';
     603               0 :                                                 s_len += 2;
     604                 :                                         }
     605             854 :                                         break;
     606                 : 
     607                 :                                 case 'v':
     608         5423182 :                                         goto fmt_unicode;
     609                 :                                         break;
     610                 : 
     611                 :                                 case 'R':
     612                 :                                 {
     613          119626 :                                         int type = va_arg(ap, int);
     614          119626 :                                         if (type != IS_UNICODE) {
     615           12962 :                                                 if (alternate_form) {
     616               0 :                                                         va_arg(ap, UConverter *);
     617                 :                                                 }
     618           12962 :                                                 goto fmt_string;
     619                 :                                         }
     620                 :                                 }
     621                 :                                 /* break omitted */
     622                 : 
     623                 :                                 case 'r':
     624         5529902 : fmt_unicode:
     625                 :                                 {
     626         5529902 :                                         UConverter *conv = ZEND_U_CONVERTER(UG(output_encoding_conv));
     627         5529902 :                                         UErrorCode status = U_ZERO_ERROR;
     628         5529902 :                                         char *res = NULL;
     629                 : 
     630         5529902 :                                         if (alternate_form) {
     631               0 :                                                 conv = va_arg(ap, UConverter *);
     632                 :                                         }
     633                 : 
     634         5529902 :                                         u = va_arg(ap, UChar *);
     635         5529902 :                                         if (u == NULL) {
     636               0 :                                                 s = S_NULL;
     637               0 :                                                 s_len = S_NULL_LEN;
     638               0 :                                                 break;
     639                 :                                         }
     640                 : 
     641         5529902 :                                         u_len = u_strlen(u);
     642         5529902 :                                         if (unicode) {
     643            3894 :                                                 s_len = u_len; /* UTODO actually we think of 2bytes each atm */
     644            3894 :                                                 s = (char*)u;
     645            3894 :                                                 s_unicode = 1;
     646                 :                                         } else {
     647         5526008 :                                                 zend_unicode_to_string_ex(conv, &res, &s_len, u, u_len, &status);
     648         5526008 :                                                 if (U_FAILURE(status)) {
     649               0 :                                                         php_error(E_WARNING, "Could not convert Unicode to printable form in s[np]printf call");
     650               0 :                                                         return;
     651                 :                                                 }
     652         5526008 :                                                 s = res;
     653         5526008 :                                                 free_s = 1;
     654                 :                                         }
     655                 : 
     656         5529902 :                                         pad_char = ' ';
     657         5529902 :                                         break;
     658                 :                                 }
     659                 : 
     660                 :                                 case 's':
     661         8937174 : fmt_string:
     662         8937174 :                                         s = va_arg(ap, char *);
     663         8937174 :                                         if (s != NULL) {
     664         8937166 :                                                 if (!adjust_precision) {
     665         8936970 :                                                         s_len = strlen(s);
     666                 :                                                 } else {
     667             196 :                                                         s_len = strnlen(s, precision);
     668                 :                                                 }
     669                 :                                         } else {
     670               8 :                                                 s = S_NULL;
     671               8 :                                                 s_len = S_NULL_LEN;
     672                 :                                         }
     673         8937174 :                                         pad_char = ' ';
     674         8937174 :                                         break;
     675                 : 
     676                 :                                 case 'f':
     677                 :                                 case 'F':
     678                 :                                 case 'e':
     679                 :                                 case 'E':
     680            1513 :                                         switch(modifier) {
     681                 :                                                 case LM_LONG_DOUBLE:
     682               0 :                                                         fp_num = (double) va_arg(ap, long double);
     683               0 :                                                         break;
     684                 :                                                 case LM_STD:
     685            1513 :                                                         fp_num = va_arg(ap, double);
     686            1513 :                                                         break;
     687                 :                                                 default:
     688               0 :                                                         goto fmt_error;
     689                 :                                         }
     690                 : 
     691            1513 :                                         if (zend_isnan(fp_num)) {
     692               0 :                                                 s = "nan";
     693               0 :                                                 s_len = 3;
     694            1513 :                                         } else if (zend_isinf(fp_num)) {
     695               2 :                                                 s = "inf";
     696               2 :                                                 s_len = 3;
     697                 :                                         } else {
     698                 : #ifdef HAVE_LOCALE_H
     699            1511 :                                                 if (!lconv) {
     700            1511 :                                                         lconv = localeconv();
     701                 :                                                 }
     702                 : #endif
     703            1511 :                                                 s = php_conv_fp((*fmt == 'f')?'F':*fmt, fp_num, alternate_form,
     704                 :                                                  (adjust_precision == NO) ? FLOAT_DIGITS : precision,
     705                 :                                                  (*fmt == 'f')?LCONV_DECIMAL_POINT:'.',
     706                 :                                                                         &is_negative, &num_buf[1], &s_len);
     707            1511 :                                                 if (is_negative)
     708               4 :                                                         prefix_char = '-';
     709            1507 :                                                 else if (print_sign)
     710               0 :                                                         prefix_char = '+';
     711            1507 :                                                 else if (print_blank)
     712               0 :                                                         prefix_char = ' ';
     713                 :                                         }
     714            1513 :                                         break;
     715                 : 
     716                 : 
     717                 :                                 case 'g':
     718                 :                                 case 'k':
     719                 :                                 case 'G':
     720                 :                                 case 'H':
     721            7052 :                                         switch(modifier) {
     722                 :                                                 case LM_LONG_DOUBLE:
     723               0 :                                                         fp_num = (double) va_arg(ap, long double);
     724               0 :                                                         break;
     725                 :                                                 case LM_STD:
     726            7052 :                                                         fp_num = va_arg(ap, double);
     727            7052 :                                                         break;
     728                 :                                                 default:
     729               0 :                                                         goto fmt_error;
     730                 :                                         }
     731                 : 
     732            7052 :                                         if (zend_isnan(fp_num)) {
     733              99 :                                                 s = "NAN";
     734              99 :                                                 s_len = 3;
     735              99 :                                                 break;
     736            6953 :                                         } else if (zend_isinf(fp_num)) {
     737              99 :                                                 if (fp_num > 0) {
     738              76 :                                                         s = "INF";
     739              76 :                                                         s_len = 3;
     740                 :                                                 } else {
     741              23 :                                                         s = "-INF";
     742              23 :                                                         s_len = 4;
     743                 :                                                 }
     744              99 :                                                 break;
     745                 :                                         }
     746                 : 
     747            6854 :                                         if (adjust_precision == NO)
     748               0 :                                                 precision = FLOAT_DIGITS;
     749            6854 :                                         else if (precision == 0)
     750               0 :                                                 precision = 1;
     751                 :                                         /*
     752                 :                                          * * We use &num_buf[ 1 ], so that we have room for the sign
     753                 :                                          */
     754                 : #ifdef HAVE_LOCALE_H
     755            6854 :                                         if (!lconv) {
     756            6854 :                                                 lconv = localeconv();
     757                 :                                         }
     758                 : #endif
     759            6854 :                                         s = php_gcvt(fp_num, precision, (*fmt=='H' || *fmt == 'k') ? '.' : LCONV_DECIMAL_POINT, (*fmt == 'G' || *fmt == 'H')?'E':'e', &num_buf[1]);
     760            6854 :                                         if (*s == '-')
     761            1632 :                                                 prefix_char = *s++;
     762            5222 :                                         else if (print_sign)
     763               0 :                                                 prefix_char = '+';
     764            5222 :                                         else if (print_blank)
     765               0 :                                                 prefix_char = ' ';
     766                 : 
     767            6854 :                                         s_len = strlen(s);
     768                 : 
     769            6854 :                                         if (alternate_form && (q = strchr(s, '.')) == NULL)
     770               0 :                                                 s[s_len++] = '.';
     771            6854 :                                         break;
     772                 : 
     773                 : 
     774                 :                                 case 'c':
     775          165167 :                                         char_buf[0] = (char) (va_arg(ap, int));
     776          165167 :                                         s = &char_buf[0];
     777          165167 :                                         s_len = 1;
     778          165167 :                                         pad_char = ' ';
     779          165167 :                                         break;
     780                 : 
     781                 : 
     782                 :                                 case '%':
     783               4 :                                         char_buf[0] = '%';
     784               4 :                                         s = &char_buf[0];
     785               4 :                                         s_len = 1;
     786               4 :                                         pad_char = ' ';
     787               4 :                                         break;
     788                 : 
     789                 : 
     790                 :                                 case 'n':
     791               0 :                                         *(va_arg(ap, int *)) = xbuf->len;
     792               0 :                                         goto skip_output;
     793                 : 
     794                 :                                         /*
     795                 :                                          * Always extract the argument as a "char *" pointer. We
     796                 :                                          * should be using "void *" but there are still machines
     797                 :                                          * that don't understand it.
     798                 :                                          * If the pointer size is equal to the size of an unsigned
     799                 :                                          * integer we convert the pointer to a hex number, otherwise
     800                 :                                          * we print "%p" to indicate that we don't handle "%p".
     801                 :                                          */
     802                 :                                 case 'p':
     803                 :                                         if (sizeof(char *) <= sizeof(u_wide_int)) {
     804             974 :                                                 ui_num = (u_wide_int)((size_t) va_arg(ap, char *));
     805             974 :                                                 s = ap_php_conv_p2(ui_num, 4, 'x',
     806                 :                                                                 &num_buf[NUM_BUF_SIZE], &s_len);
     807             974 :                                                 if (ui_num != 0) {
     808             974 :                                                         *--s = 'x';
     809             974 :                                                         *--s = '0';
     810             974 :                                                         s_len += 2;
     811                 :                                                 }
     812                 :                                         } else {
     813                 :                                                 s = "%p";
     814                 :                                                 s_len = 2;
     815                 :                                         }
     816             974 :                                         pad_char = ' ';
     817             974 :                                         break;
     818                 : 
     819                 : 
     820                 :                                 case NUL:
     821                 :                                         /*
     822                 :                                          * The last character of the format string was %.
     823                 :                                          * We ignore it.
     824                 :                                          */
     825               0 :                                         continue;
     826                 : 
     827                 : 
     828               0 : fmt_error:
     829               0 :                                 php_error(E_ERROR, "Illegal length modifier specified '%c' in s[np]printf call", *fmt);
     830                 :                                         /*
     831                 :                                          * The default case is for unrecognized %'s.
     832                 :                                          * We print %<char> to help the user identify what
     833                 :                                          * option is not understood.
     834                 :                                          * This is also useful in case the user wants to pass
     835                 :                                          * the output of format_converter to another function
     836                 :                                          * that understands some other %<char> (like syslog).
     837                 :                                          * Note that we can't point s inside fmt because the
     838                 :                                          * unknown <char> could be preceded by width etc.
     839                 :                                          */
     840                 :                                 default:
     841               0 :                                         char_buf[0] = '%';
     842               0 :                                         char_buf[1] = *fmt;
     843               0 :                                         s = char_buf;
     844               0 :                                         s_len = 2;
     845               0 :                                         pad_char = ' ';
     846                 :                                         break;
     847                 :                         }
     848                 : 
     849        18553209 :                         if (prefix_char != NUL) {
     850            4367 :                                 *--s = prefix_char;
     851            4367 :                                 s_len++;
     852                 :                         }
     853        18553209 :                         if (adjust_width && adjust == RIGHT && min_width > s_len) {
     854          155932 :                                 if (pad_char == '0' && prefix_char != NUL) {
     855               0 :                                         INS_CHAR(unicode, xbuf, *s);
     856               0 :                                         s++;
     857               0 :                                         s_len--;
     858               0 :                                         min_width--;
     859                 :                                 }
     860          155932 :                                 PAD(unicode, xbuf, min_width - s_len, pad_char);
     861                 :                         }
     862                 :                         /*
     863                 :                          * Print the string s.
     864                 :                          */
     865        18553209 :                         INS_STRING(unicode, s_unicode, xbuf, s, s_len);
     866        18553209 :                         if (free_s) {
     867         5526008 :                                 efree(s);
     868                 :                         }
     869        18553209 :                         if (free_zcopy) {
     870             184 :                                 zval_dtor(&zcopy);
     871                 :                         }
     872                 : 
     873        18553209 :                         if (adjust_width && adjust == LEFT && min_width > s_len) {
     874              20 :                                 PAD(unicode, xbuf, min_width - s_len, pad_char);
     875                 :                         }
     876                 :                 }
     877        99196886 : skip_output:
     878        99196886 :                 fmt++;
     879                 :         }
     880         6377948 :         return;
     881                 : }
     882                 : /* }}} */
     883                 : 
     884                 : /*
     885                 :  * This is the general purpose conversion function.
     886                 :  */
     887                 : PHPAPI int vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) /* {{{ */
     888         6341474 : {
     889         6341474 :         smart_str xbuf = {0};
     890                 : 
     891         6341474 :         xbuf_format_converter(0, &xbuf, format, ap);
     892                 : 
     893         6341474 :         if (max_len && xbuf.len > max_len) {
     894               1 :                 xbuf.len = max_len;
     895                 :         }
     896         6341474 :         smart_str_0(&xbuf);
     897                 : 
     898         6341474 :         *pbuf = xbuf.c;
     899                 : 
     900         6341474 :         return xbuf.len;
     901                 : }
     902                 : /* }}} */
     903                 : 
     904                 : PHPAPI int spprintf(char **pbuf, size_t max_len, const char *format, ...) /* {{{ */
     905         1810174 : {
     906                 :         int cc;
     907                 :         va_list ap;
     908                 : 
     909         1810174 :         va_start(ap, format);
     910         1810174 :         cc = vspprintf(pbuf, max_len, format, ap);
     911         1810174 :         va_end(ap);
     912         1810174 :         return (cc);
     913                 : }
     914                 : /* }}} */
     915                 : 
     916                 : PHPAPI int vuspprintf(UChar **pbuf, size_t max_len, const char *format, va_list ap) /* {{{ */
     917           36474 : {
     918           36474 :         smart_str xbuf = {0};
     919                 : 
     920           36474 :         xbuf_format_converter(1, &xbuf, format, ap);
     921                 : 
     922           36474 :         if (max_len && xbuf.len > max_len) {
     923               0 :                 xbuf.len = max_len;
     924                 :         }
     925           36474 :         smart_str_0(&xbuf);
     926                 : 
     927           36474 :         *pbuf = (UChar*)xbuf.c;
     928                 : 
     929           36474 :         return xbuf.len / sizeof(UChar);
     930                 : }
     931                 : /* }}} */
     932                 : 
     933                 : PHPAPI int uspprintf(UChar **pbuf, size_t max_len, const char *format, ...) /* {{{ */
     934               0 : {
     935                 :         int cc;
     936                 :         va_list ap;
     937                 : 
     938               0 :         va_start(ap, format);
     939               0 :         cc = vuspprintf(pbuf, max_len, format, ap);
     940               0 :         va_end(ap);
     941               0 :         return (cc);
     942                 : }
     943                 : /* }}} */
     944                 : 
     945                 : PHPAPI int vzspprintf(zend_uchar type, zstr *pbuf, size_t max_len, const char *format, va_list ap) /* {{{ */
     946            4926 : {
     947            4926 :         if (type == IS_UNICODE) {
     948            3894 :                 return vuspprintf(&pbuf->u, max_len, format, ap);
     949                 :         } else {
     950            1032 :                 return vspprintf(&pbuf->s, max_len, format, ap);
     951                 :         }
     952                 : }
     953                 : /* }}} */
     954                 : 
     955                 : PHPAPI int zspprintf( zend_uchar type, zstr *pbuf, size_t max_len, const char *format, ...) /* {{{ */
     956            4926 : {
     957                 :         int cc;
     958                 :         va_list ap;
     959                 : 
     960            4926 :         va_start(ap, format);
     961            4926 :         cc = vzspprintf(type, pbuf, max_len, format, ap);
     962            4926 :         va_end(ap);
     963            4926 :         return (cc);
     964                 : }
     965                 : /* }}} */
     966                 : 
     967                 : /*
     968                 :  * Local variables:
     969                 :  * tab-width: 4
     970                 :  * c-basic-offset: 4
     971                 :  * End:
     972                 :  * vim600: sw=4 ts=4 fdm=marker
     973                 :  * vim<600: sw=4 ts=4
     974                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:46 +0000 (35 hours ago)

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