⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snprintf.c

📁 radius服务器
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   Unix snprintf implementation.   Version 1.4   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU Library General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU Library General Public License for more details.   You should have received a copy of the GNU Library General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   Revision History:   1.4:      *  integrate in FreeRADIUS's libradius:	  *  Fetched from: http://savannah.gnu.org/cgi-bin/viewcvs/mailutils/mailutils/lib/snprintf.c?rev=1.4	  *  Fetched from: http://savannah.gnu.org/cgi-bin/viewcvs/mailutils/mailutils/lib/snprintf.h?rev=1.4	  *  Replace config.h with autoconf.h	  *  Protect with HAVE_LOCAL_SNPRINTF     1.3:      *  add #include <config.h> ifdef HAVE_CONFIG_H      *  cosmetic change, when exponent is 0 print xxxE+00         instead of xxxE-00   1.2:      *  put the program under LGPL.   1.1:      *  added changes from Miles Bader      *  corrected a bug with %f      *  added support for %#g      *  added more comments :-)   1.0:      *  supporting must ANSI syntaxic_sugars   0.0:      *  suppot %s %c %d THANKS(for the patches and ideas):     Miles Bader     Cyrille Rustom     Jacek Slabocewiz     Mike Parker(mouse)*/#include "autoconf.h"#ifdef HAVE_LOCAL_SNPRINTF#include "snprintf.h"/* * Find the nth power of 10 */PRIVATE double#ifdef __STDC__pow_10(int n)#elsepow_10(n)int n;#endif{  int i;  double P;  if (n < 0)    for (i = 1, P = 1., n = -n ; i <= n ; i++) {P *= .1;}  else    for (i = 1, P = 1. ; i <= n ; i++) {P *= 10.0;}  return P;}/* * Find the integral part of the log in base 10 * Note: this not a real log10()         I just need and approximation(integerpart) of x in:          10^x ~= r * log_10(200) = 2; * log_10(250) = 2; */PRIVATE int#ifdef __STDC__log_10(double r)#elselog_10(r)double r;#endif{  int i = 0;  double result = 1.;  if (r < 0.)    r = -r;  if (r < 1.) {    while (result >= r) {result *= .1; i++;}    return (-i);  } else {    while (result <= r) {result *= 10.; i++;}    return (i - 1);  }}/* * This function return the fraction part of a double * and set in ip the integral part. * In many ways it resemble the modf() found on most Un*x */PRIVATE double#ifdef __STDC__integral(double real, double * ip)#elseintegral(real, ip)double real;double * ip;#endif{  int j;  double i, s, p;  double real_integral = 0.;/* take care of the obvious *//* equal to zero ? */  if (real == 0.) {    *ip = 0.;    return (0.);  }/* negative number ? */  if (real < 0.)    real = -real;/* a fraction ? */  if ( real < 1.) {    *ip = 0.;    return real;  }/* the real work :-) */  for (j = log_10(real); j >= 0; j--) {    p = pow_10(j);    s = (real - real_integral)/p;    i = 0.;    while (i + 1. <= s) {i++;}    real_integral += i*p;  }  *ip = real_integral;  return (real - real_integral);}#define PRECISION 1.e-6/* * return an ascii representation of the integral part of the number * and set fract to be an ascii representation of the fraction part * the container for the fraction and the integral part or staticly * declare with fix size */PRIVATE char *#ifdef __STDC__numtoa(double number, int base, int precision, char ** fract)#elsenumtoa(number, base, precision, fract)double number;int base;int precision;char ** fract;#endif{  register int i, j;  double ip, fp; /* integer and fraction part */  double fraction;  int digits = MAX_INT - 1;  static char integral_part[MAX_INT];  static char fraction_part[MAX_FRACT];  double sign;  int ch;/* taking care of the obvious case: 0.0 */  if (number == 0.) {    integral_part[0] = '0';    integral_part[1] = '\0';    fraction_part[0] = '0';    fraction_part[1] = '\0';    return integral_part;  }/* for negative numbers */  if ((sign = number) < 0.) {    number = -number;    digits--; /* sign consume one digit */  }  fraction = integral(number, &ip);  number = ip;/* do the integral part */  if ( ip == 0.) {    integral_part[0] = '0';    i = 1;  } else {    for ( i = 0; i < digits && number != 0.; ++i) {      number /= base;      fp = integral(number, &ip);      ch = (int)((fp + PRECISION)*base); /* force to round */      integral_part[i] = (ch <= 9) ? ch + '0' : ch + 'a' - 10;      if (! isxdigit(integral_part[i])) /* bail out overflow !! */        break;      number = ip;     }  }/* Oh No !! out of bound, ho well fill it up ! */  if (number != 0.)    for (i = 0; i < digits; ++i)      integral_part[i] = '9';/* put the sign ? */  if (sign < 0.)    integral_part[i++] = '-';  integral_part[i] = '\0';/* reverse every thing */  for ( i--, j = 0; j < i; j++, i--)    SWAP_INT(integral_part[i], integral_part[j]);/* the fractionnal part */  for (i=0, fp=fraction; precision > 0 && i < MAX_FRACT ; i++, precision--	) {    fraction_part[i] = (int)((fp + PRECISION)*10. + '0');    if (! isdigit(fraction_part[i])) /* underflow ? */      break;    fp = (fp*10.0) - (double)(long)((fp + PRECISION)*10.);  }  fraction_part[i] = '\0';  if (fract != (char **)0)    *fract = fraction_part;  return integral_part;}/* for %d and friends, it puts in holder * the representation with the right padding */PRIVATE void#ifdef __STDC__decimal(struct DATA *p, double d)#elsedecimal(p, d)struct DATA *p;double d;#endif{  char *tmp;  tmp = itoa(d);  p->width -= strlen(tmp);  PAD_RIGHT(p);  PUT_PLUS(d, p);  PUT_SPACE(d, p);  while (*tmp) { /* the integral */    PUT_CHAR(*tmp, p);    tmp++;  }  PAD_LEFT(p);}/* for %o octal representation */PRIVATE void#ifdef __STDC__octal(struct DATA *p, double d)#elseoctal(p, d)struct DATA *p;double d;#endif{  char *tmp;  tmp = otoa(d);  p->width -= strlen(tmp);  PAD_RIGHT(p);  if (p->square == FOUND) /* had prefix '0' for octal */    PUT_CHAR('0', p);  while (*tmp) { /* octal */    PUT_CHAR(*tmp, p);    tmp++;  }  PAD_LEFT(p);}/* for %x %X hexadecimal representation */PRIVATE void#ifdef __STDC__hexa(struct DATA *p, double d)#elsehexa(p, d)struct DATA *p;double d;#endif{  char *tmp;  tmp = htoa(d);  p->width -= strlen(tmp);  PAD_RIGHT(p);  if (p->square == FOUND) { /* prefix '0x' for hexa */    PUT_CHAR('0', p); PUT_CHAR(*p->pf, p);  }  while (*tmp) { /* hexa */    PUT_CHAR((*p->pf == 'X' ? toupper(*tmp) : *tmp), p);    tmp++;  }  PAD_LEFT(p);}/* %s strings */PRIVATE void#ifdef __STDC__strings(struct DATA *p, char *tmp)#elsestrings(p, tmp)struct DATA *p;char *tmp;#endif{  int i;  i = strlen(tmp);  if (p->precision != NOT_FOUND) /* the smallest number */    i = (i < p->precision ? i : p->precision);  p->width -= i;  PAD_RIGHT(p);  while (i-- > 0) { /* put the sting */    PUT_CHAR(*tmp, p);    tmp++;  }  PAD_LEFT(p);}/* %f or %g  floating point representation */PRIVATE void#ifdef __STDC__floating(struct DATA *p, double d)#elsefloating(p, d)struct DATA *p;double d;#endif{  char *tmp, *tmp2;  int i;  DEF_PREC(p);  d = ROUND(d, p);  tmp = dtoa(d, p->precision, &tmp2);  /* calculate the padding. 1 for the dot */  p->width = p->width -            ((d > 0. && p->justify == RIGHT) ? 1:0) -            ((p->space == FOUND) ? 1:0) -            strlen(tmp) - p->precision - 1;  PAD_RIGHT(p);  PUT_PLUS(d, p);  PUT_SPACE(d, p);  while (*tmp) { /* the integral */    PUT_CHAR(*tmp, p);    tmp++;  }  if (p->precision != 0 || p->square == FOUND)    PUT_CHAR('.', p);  /* put the '.' */  if (*p->pf == 'g' || *p->pf == 'G') /* smash the trailing zeros */    for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)       tmp2[i] = '\0';  for (; *tmp2; tmp2++)    PUT_CHAR(*tmp2, p); /* the fraction */  PAD_LEFT(p);}/* %e %E %g exponent representation */PRIVATE void#ifdef __STDC__exponent(struct DATA *p, double d)#elseexponent(p, d)struct DATA *p;double d;#endif{  char *tmp, *tmp2;  int j, i;  DEF_PREC(p);  j = log_10(d);  d = d / pow_10(j);  /* get the Mantissa */  d = ROUND(d, p);  tmp = dtoa(d, p->precision, &tmp2);  /* 1 for unit, 1 for the '.', 1 for 'e|E',   * 1 for '+|-', 3 for 'exp' */  /* calculate how much padding need */  p->width = p->width -             ((d > 0. && p->justify == RIGHT) ? 1:0) -             ((p->space == FOUND) ? 1:0) - p->precision - 7;  PAD_RIGHT(p);  PUT_PLUS(d, p);  PUT_SPACE(d, p);  while (*tmp) {/* the integral */    PUT_CHAR(*tmp, p);    tmp++;  }  if (p->precision != 0 || p->square == FOUND)    PUT_CHAR('.', p);  /* the '.' */  if (*p->pf == 'g' || *p->pf == 'G') /* smash the trailing zeros */    for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)       tmp2[i] = '\0';  for (; *tmp2; tmp2++)    PUT_CHAR(*tmp2, p); /* the fraction */  if (*p->pf == 'g' || *p->pf == 'e') { /* the exponent put the 'e|E' */    PUT_CHAR('e', p);  } else    PUT_CHAR('E', p);  if (j >= 0) {  /* the sign of the exp */    PUT_CHAR('+', p);  } else {    PUT_CHAR('-', p);    j = -j;  }  tmp = itoa((double)j);  if (j < 9) {  /* need to pad the exponent with 0 '000' */    PUT_CHAR('0', p); PUT_CHAR('0', p);  } else if (j < 99)    PUT_CHAR('0', p);  while (*tmp) { /* the exponent */    PUT_CHAR(*tmp, p);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -