📄 formatted_print.c
字号:
/* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Stig S鎡her Bakken <ssb@fast.no> | +----------------------------------------------------------------------+ *//* $Id: formatted_print.c,v 1.59.2.15.2.4 2007/01/13 16:31:36 iliaa Exp $ */#include <math.h> /* modf() */#include "php.h"#include "ext/standard/head.h"#include "php_string.h"#include "zend_execute.h"#include <stdio.h>#ifdef HAVE_LOCALE_H#include <locale.h>#endif#define ALIGN_LEFT 0#define ALIGN_RIGHT 1#define ADJ_WIDTH 1#define ADJ_PRECISION 2#define NUM_BUF_SIZE 500#define NDIG 80#define FLOAT_DIGITS 6#define FLOAT_PRECISION 6#define MAX_FLOAT_DIGITS 38#define MAX_FLOAT_PRECISION 40#if 0/* trick to control varargs functions through cpp */# define PRINTF_DEBUG(arg) php_printf arg#else# define PRINTF_DEBUG(arg)#endifstatic char hexchars[] = "0123456789abcdef";static char HEXCHARS[] = "0123456789ABCDEF";/* * cvt.c - IEEE floating point formatting routines for FreeBSD * from GNU libc-4.6.27 *//* * php_convert_to_decimal converts to decimal * the number of digits is specified by ndigit * decpt is set to the position of the decimal point * sign is set to 0 for positive, 1 for negative */static char *php_convert_to_decimal(double arg, int ndigits, int *decpt, int *sign, int eflag){ register int r2; int mvl; double fi, fj; register char *p, *p1; /*THREADX*/#ifndef THREAD_SAFE static char cvt_buf[NDIG];#endif if (ndigits >= NDIG - 1) ndigits = NDIG - 2; r2 = 0; *sign = 0; p = &cvt_buf[0]; if (arg < 0) { *sign = 1; arg = -arg; } arg = modf(arg, &fi); p1 = &cvt_buf[NDIG]; /* * Do integer part */ if (fi != 0) { p1 = &cvt_buf[NDIG]; while (fi != 0) { fj = modf(fi / 10, &fi); if (p1 <= &cvt_buf[0]) { mvl = NDIG - ndigits; memmove(&cvt_buf[mvl], &cvt_buf[0], NDIG-mvl-1); p1 += mvl; } *--p1 = (int) ((fj + .03) * 10) + '0'; r2++; } while (p1 < &cvt_buf[NDIG]) *p++ = *p1++; } else if (arg > 0) { while ((fj = arg * 10) < 1) { if (!eflag && (r2 * -1) < ndigits) { break; } arg = fj; r2--; } } p1 = &cvt_buf[ndigits]; if (eflag == 0) p1 += r2; *decpt = r2; if (p1 < &cvt_buf[0]) { cvt_buf[0] = '\0'; return (cvt_buf); } if (p <= p1 && p < &cvt_buf[NDIG]) { arg = modf(arg * 10, &fj); if ((int)fj==10) { *p++ = '1'; fj = 0; *decpt = ++r2; } while (p <= p1 && p < &cvt_buf[NDIG]) { *p++ = (int) fj + '0'; arg = modf(arg * 10, &fj); } } if (p1 >= &cvt_buf[NDIG]) { cvt_buf[NDIG - 1] = '\0'; return (cvt_buf); } p = p1; *p1 += 5; while (*p1 > '9') { *p1 = '0'; if (p1 > cvt_buf) ++ * --p1; else { *p1 = '1'; (*decpt)++; if (eflag == 0) { if (p > cvt_buf) *p = '0'; p++; } } } *p = '\0'; return (cvt_buf);}inline static voidphp_sprintf_appendchar(char **buffer, int *pos, int *size, char add TSRMLS_DC){ if ((*pos + 1) >= *size) { *size <<= 1; PRINTF_DEBUG(("%s(): ereallocing buffer to %d bytes\n", get_active_function_name(TSRMLS_C), *size)); *buffer = erealloc(*buffer, *size); } PRINTF_DEBUG(("sprintf: appending '%c', pos=\n", add, *pos)); (*buffer)[(*pos)++] = add;}inline static voidphp_sprintf_appendstring(char **buffer, int *pos, int *size, char *add, int min_width, int max_width, char padding, int alignment, int len, int neg, int expprec, int always_sign){ register int npad; int req_size; int copy_len; copy_len = (expprec ? MIN(max_width, len) : len); npad = min_width - copy_len; if (npad < 0) { npad = 0; } PRINTF_DEBUG(("sprintf: appendstring(%x, %d, %d, \"%s\", %d, '%c', %d)\n", *buffer, *pos, *size, add, min_width, padding, alignment)); req_size = *pos + MAX(min_width, copy_len) + 1; if (req_size > *size) { while (req_size > *size) { *size <<= 1; } PRINTF_DEBUG(("sprintf ereallocing buffer to %d bytes\n", *size)); *buffer = erealloc(*buffer, *size); } if (alignment == ALIGN_RIGHT) { if ((neg || always_sign) && padding=='0') { (*buffer)[(*pos)++] = (neg) ? '-' : '+'; add++; len--; copy_len--; } while (npad-- > 0) { (*buffer)[(*pos)++] = padding; } } PRINTF_DEBUG(("sprintf: appending \"%s\"\n", add)); memcpy(&(*buffer)[*pos], add, copy_len + 1); *pos += copy_len; if (alignment == ALIGN_LEFT) { while (npad--) { (*buffer)[(*pos)++] = padding; } }}inline static voidphp_sprintf_appendint(char **buffer, int *pos, int *size, long number, int width, char padding, int alignment, int always_sign){ char numbuf[NUM_BUF_SIZE]; register unsigned long magn, nmagn; register unsigned int i = NUM_BUF_SIZE - 1, neg = 0; PRINTF_DEBUG(("sprintf: appendint(%x, %x, %x, %d, %d, '%c', %d)\n", *buffer, pos, size, number, width, padding, alignment)); if (number < 0) { neg = 1; magn = ((unsigned long) -(number + 1)) + 1; } else { magn = (unsigned long) number; } /* Can't right-pad 0's on integers */ if(alignment==0 && padding=='0') padding=' '; numbuf[i] = '\0'; do { nmagn = magn / 10; numbuf[--i] = (unsigned char)(magn - (nmagn * 10)) + '0'; magn = nmagn; } while (magn > 0 && i > 0); if (neg) { numbuf[--i] = '-'; } else if (always_sign) { numbuf[--i] = '+'; } PRINTF_DEBUG(("sprintf: appending %d as \"%s\", i=%d\n", number, &numbuf[i], i)); php_sprintf_appendstring(buffer, pos, size, &numbuf[i], width, 0, padding, alignment, (NUM_BUF_SIZE - 1) - i, neg, 0, always_sign);}inline static voidphp_sprintf_appenduint(char **buffer, int *pos, int *size, unsigned long number, int width, char padding, int alignment){ char numbuf[NUM_BUF_SIZE]; register unsigned long magn, nmagn; register unsigned int i = NUM_BUF_SIZE - 1; PRINTF_DEBUG(("sprintf: appenduint(%x, %x, %x, %d, %d, '%c', %d)\n", *buffer, pos, size, number, width, padding, alignment)); magn = (unsigned int) number; /* Can't right-pad 0's on integers */ if (alignment == 0 && padding == '0') padding = ' '; numbuf[i] = '\0'; do { nmagn = magn / 10; numbuf[--i] = (unsigned char)(magn - (nmagn * 10)) + '0'; magn = nmagn; } while (magn > 0 && i > 0); PRINTF_DEBUG(("sprintf: appending %d as \"%s\", i=%d\n", number, &numbuf[i], i)); php_sprintf_appendstring(buffer, pos, size, &numbuf[i], width, 0, padding, alignment, (NUM_BUF_SIZE - 1) - i, 0, 0, 0);}inline static voidphp_sprintf_appenddouble(char **buffer, int *pos, int *size, double number, int width, char padding, int alignment, int precision, int adjust, char fmt, int always_sign TSRMLS_DC){ char numbuf[NUM_BUF_SIZE]; char *cvt; register int i = 0, j = 0; int sign, decpt, cvt_len; char decimal_point = '.';#ifdef HAVE_LOCALE_H struct lconv lc; char locale_decimal_point; localeconv_r(&lc); locale_decimal_point = (lc.decimal_point)[0];#else char locale_decimal_point = '.';#endif PRINTF_DEBUG(("sprintf: appenddouble(%x, %x, %x, %f, %d, '%c', %d, %c)\n", *buffer, pos, size, number, width, padding, alignment, fmt)); if ((adjust & ADJ_PRECISION) == 0) { precision = FLOAT_PRECISION; } else if (precision > MAX_FLOAT_PRECISION) { precision = MAX_FLOAT_PRECISION; } if (zend_isnan(number)) { sign = (number<0); php_sprintf_appendstring(buffer, pos, size, "NaN", 3, 0, padding, alignment, precision, sign, 0, always_sign); return; } if (zend_isinf(number)) { sign = (number<0); php_sprintf_appendstring(buffer, pos, size, "INF", 3, 0, padding, alignment, precision, sign, 0, always_sign); return; } cvt = php_convert_to_decimal(number, precision, &decpt, &sign, (fmt == 'e')); cvt_len = strlen(cvt); if (sign) { numbuf[i++] = '-'; } else if (always_sign) { numbuf[i++] = '+'; } if (fmt == 'f' || fmt == 'F') { if (decpt <= 0) { numbuf[i++] = '0'; if (precision > 0) { int k = precision; numbuf[i++] = fmt == 'F' ? decimal_point : locale_decimal_point; while ((decpt++ < 0) && k--) { numbuf[i++] = '0'; } } } else { while (decpt-- > 0) { numbuf[i++] = j < cvt_len ? cvt[j++] : '0'; } if (precision > 0) { numbuf[i++] = fmt == 'F' ? decimal_point : locale_decimal_point; while (precision-- > 0) { numbuf[i++] = j < cvt_len ? cvt[j++] : '0'; } } } } else if (fmt == 'e' || fmt == 'E') { char *exp_p; int dec2; decpt--; numbuf[i++] = cvt[j++]; numbuf[i++] = decimal_point; if (precision > 0) { int k = precision; while (k-- && cvt[j]) { numbuf[i++] = cvt[j++]; } } else { numbuf[i++] = '0'; } numbuf[i++] = fmt; exp_p = php_convert_to_decimal(decpt, 0, &dec2, &sign, 0); numbuf[i++] = sign ? '-' : '+'; if (*exp_p) { while (*exp_p) { numbuf[i++] = *(exp_p++); } } else { numbuf[i++] = '0'; } } else { numbuf[i++] = cvt[j++]; if (precision > 0) numbuf[i++] = decimal_point; } while (cvt[j]) { numbuf[i++] = cvt[j++]; } numbuf[i] = '\0'; php_sprintf_appendstring(buffer, pos, size, numbuf, width, 0, padding, alignment, i, sign, 0, always_sign);}inline static voidphp_sprintf_append2n(char **buffer, int *pos, int *size, long number,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -