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

📄 snprintf.c

📁 网站压力测试的工具
💻 C
📖 第 1 页 / 共 3 页
字号:
#  define breakeven_point   2	/* AXP (DEC Alpha)     - gcc or cc or egcs */#endif#if defined(__i386__)  || defined(__i386)#  define breakeven_point  12	/* Intel Pentium/Linux - gcc 2.96 */#endif#if defined(__hppa)#  define breakeven_point  10	/* HP-PA               - gcc */#endif#if defined(__sparc__) || defined(__sparc)#  define breakeven_point  33	/* Sun Sparc 5         - gcc 2.8.1 */#endif/* some other values of possible interest: *//* #define breakeven_point  8 */  /* VAX 4000          - vaxc *//* #define breakeven_point 19 */  /* VAX 4000          - gcc 2.7.0 */#ifndef breakeven_point#  define breakeven_point   6	/* some reasonable one-size-fits-all value */#endif#define fast_memcpy(d,s,n) \  { register size_t nn = (size_t)(n); \    if (nn >= breakeven_point) memcpy((d), (s), nn); \    else if (nn > 0) { /* proc call overhead is worth only for large strings*/\      register char *dd; register const char *ss; \      for (ss=(s), dd=(d); nn>0; nn--) *dd++ = *ss++; } }#define fast_memset(d,c,n) \  { register size_t nn = (size_t)(n); \    if (nn >= breakeven_point) memset((d), (int)(c), nn); \    else if (nn > 0) { /* proc call overhead is worth only for large strings*/\      register char *dd; register const int cc=(int)(c); \      for (dd=(d); nn>0; nn--) *dd++ = cc; } }/* prototypes */#if defined(NEED_ASPRINTF)int asprintf   (char **ptr, const char *fmt, /*args*/ ...);#endif#if defined(NEED_VASPRINTF)int vasprintf  (char **ptr, const char *fmt, va_list ap);#endif#if defined(NEED_ASNPRINTF)int asnprintf  (char **ptr, size_t str_m, const char *fmt, /*args*/ ...);#endif#if defined(NEED_VASNPRINTF)int vasnprintf (char **ptr, size_t str_m, const char *fmt, va_list ap);#endif#if defined(HAVE_SNPRINTF)/* declare our portable snprintf  routine under name portable_snprintf  *//* declare our portable vsnprintf routine under name portable_vsnprintf */#else/* declare our portable routines under names snprintf and vsnprintf */#define portable_snprintf snprintf#if !defined(NEED_SNPRINTF_ONLY)#define portable_vsnprintf vsnprintf#endif#endif#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...);#if !defined(NEED_SNPRINTF_ONLY)int portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap);#endif#endif/* declarations */#if 0static char credits[] = "\n\@(#)snprintf.c, v2.2: Mark Martinec, <mark.martinec@ijs.si>\n\@(#)snprintf.c, v2.2: Copyright 1999, Mark Martinec. Frontier Artistic License applies.\n\@(#)snprintf.c, v2.2: http://www.ijs.si/software/snprintf/\n";#endif /* silence the compiler */#if defined(NEED_ASPRINTF)int asprintf(char **ptr, const char *fmt, /*args*/ ...) {  va_list ap;  size_t str_m;  int str_l;  *ptr = NULL;  va_start(ap, fmt);                            /* measure the required size */  str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap);  va_end(ap);  assert(str_l >= 0);        /* possible integer overflow if str_m > INT_MAX */  *ptr = (char *) malloc(str_m = (size_t)str_l + 1);  if (*ptr == NULL) { errno = ENOMEM; str_l = -1; }  else {    int str_l2;    va_start(ap, fmt);    str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);    va_end(ap);    assert(str_l2 == str_l);  }  return str_l;}#endif#if defined(NEED_VASPRINTF)int vasprintf(char **ptr, const char *fmt, va_list ap) {  size_t str_m;  int str_l;  *ptr = NULL;  { va_list ap2;    va_copy(ap2, ap);  /* don't consume the original ap, we'll need it again */    str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/    va_end(ap2);  }  assert(str_l >= 0);        /* possible integer overflow if str_m > INT_MAX */  *ptr = (char *) malloc(str_m = (size_t)str_l + 1);  if (*ptr == NULL) { errno = ENOMEM; str_l = -1; }  else {    int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);    assert(str_l2 == str_l);  }  return str_l;}#endif#if defined(NEED_ASNPRINTF)int asnprintf (char **ptr, size_t str_m, const char *fmt, /*args*/ ...) {  va_list ap;  int str_l;  *ptr = NULL;  va_start(ap, fmt);                            /* measure the required size */  str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap);  va_end(ap);  assert(str_l >= 0);        /* possible integer overflow if str_m > INT_MAX */  if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1;      /* truncate */  /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */  if (str_m == 0) {  /* not interested in resulting string, just return size */  } else {    *ptr = (char *) malloc(str_m);    if (*ptr == NULL) { errno = ENOMEM; str_l = -1; }    else {      int str_l2;      va_start(ap, fmt);      str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);      va_end(ap);      assert(str_l2 == str_l);    }  }  return str_l;}#endif#if defined(NEED_VASNPRINTF)int vasnprintf (char **ptr, size_t str_m, const char *fmt, va_list ap) {  int str_l;  *ptr = NULL;  { va_list ap2;    va_copy(ap2, ap);  /* don't consume the original ap, we'll need it again */    str_l = portable_vsnprintf(NULL, (size_t)0, fmt, ap2);/*get required size*/    va_end(ap2);  }  assert(str_l >= 0);        /* possible integer overflow if str_m > INT_MAX */  if ((size_t)str_l + 1 < str_m) str_m = (size_t)str_l + 1;      /* truncate */  /* if str_m is 0, no buffer is allocated, just set *ptr to NULL */  if (str_m == 0) {  /* not interested in resulting string, just return size */  } else {    *ptr = (char *) malloc(str_m);    if (*ptr == NULL) { errno = ENOMEM; str_l = -1; }    else {      int str_l2 = portable_vsnprintf(*ptr, str_m, fmt, ap);      assert(str_l2 == str_l);    }  }  return str_l;}#endif/* * If the system does have snprintf and the portable routine is not * specifically required, this module produces no code for snprintf/vsnprintf. */#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)#if !defined(NEED_SNPRINTF_ONLY)int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) {  va_list ap;  int str_l;  va_start(ap, fmt);  str_l = portable_vsnprintf(str, str_m, fmt, ap);  va_end(ap);  return str_l;}#endif#if defined(NEED_SNPRINTF_ONLY)int portable_snprintf(char *str, size_t str_m, const char *fmt, /*args*/ ...) {#elseint portable_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap) {#endif#if defined(NEED_SNPRINTF_ONLY)  va_list ap;#endif  size_t str_l = 0;  const char *p = fmt;/* In contrast with POSIX, the ISO C99 now says * that str can be NULL and str_m can be 0. * This is more useful than the old:  if (str_m < 1) return -1; */#if defined(NEED_SNPRINTF_ONLY)  va_start(ap, fmt);#endif  if (!p) p = "";  while (*p) {    if (*p != '%') {   /* if (str_l < str_m) str[str_l++] = *p++;    -- this would be sufficient */   /* but the following code achieves better performance for cases    * where format string is long and contains few conversions */      const char *q = strchr(p+1,'%');      size_t n = !q ? strlen(p) : (q-p);      if (str_l < str_m) {        size_t avail = str_m-str_l;        fast_memcpy(str+str_l, p, (n>avail?avail:n));      }      p += n; str_l += n;    } else {      const char *starting_p;      size_t min_field_width = 0, precision = 0;      int zero_padding = 0, precision_specified = 0, justify_left = 0;      int alternate_form = 0, force_sign = 0;      int space_for_positive = 1; /* If both the ' ' and '+' flags appear,                                     the ' ' flag should be ignored. */      char length_modifier = '\0';            /* allowed values: \0, h, l, L */      char tmp[32];/* temporary buffer for simple numeric->string conversion */      const char *str_arg;      /* string address in case of string argument */      size_t str_arg_l;         /* natural field width of arg without padding                                   and sign */      unsigned char uchar_arg;        /* unsigned char argument value - only defined for c conversion.           N.B. standard explicitly states the char argument for           the c conversion is unsigned */      size_t number_of_zeros_to_pad = 0;        /* number of zeros to be inserted for numeric conversions           as required by the precision or minimal field width */      size_t zero_padding_insertion_ind = 0;        /* index into tmp where zero padding is to be inserted */      char fmt_spec = '\0';        /* current conversion specifier character */      /* str_arg = credits; just to make compiler happy (defined but not used)*/      str_arg = NULL;      starting_p = p; p++;  /* skip '%' */   /* parse flags */      while (*p == '0' || *p == '-' || *p == '+' ||             *p == ' ' || *p == '#' || *p == '\'') {        switch (*p) {        case '0': zero_padding = 1; break;        case '-': justify_left = 1; break;        case '+': force_sign = 1; space_for_positive = 0; break;        case ' ': force_sign = 1;     /* If both the ' ' and '+' flags appear, the ' ' flag should be ignored */#ifdef PERL_COMPATIBLE     /* ... but in Perl the last of ' ' and '+' applies */                  space_for_positive = 1;#endif                  break;        case '#': alternate_form = 1; break;        case '\'': break;        }        p++;      }   /* If the '0' and '-' flags both appear, the '0' flag should be ignored. */   /* parse field width */      if (*p == '*') {        int j;        p++; j = va_arg(ap, int);        if (j >= 0) min_field_width = j;        else { min_field_width = -j; justify_left = 1; }      } else if (isdigit((int)(*p))) {        /* size_t could be wider than unsigned int;           make sure we treat argument like common implementations do */        unsigned int uj = *p++ - '0';        while (isdigit((int)(*p))) uj = 10*uj + (unsigned int)(*p++ - '0');        min_field_width = uj;      }   /* parse precision */      if (*p == '.') {        p++; precision_specified = 1;        if (*p == '*') {          int j = va_arg(ap, int);          p++;          if (j >= 0) precision = j;          else {            precision_specified = 0; precision = 0;         /* NOTE:          *   Solaris 2.6 man page claims that in this case the precision          *   should be set to 0.  Digital Unix 4.0, HPUX 10 and BSD man page          *   claim that this case should be treated as unspecified precision,          *   which is what we do here.          */          }        } else if (isdigit((int)(*p))) {          /* size_t could be wider than unsigned int;             make sure we treat argument like common implementations do */          unsigned int uj = *p++ - '0';          while (isdigit((int)(*p))) uj = 10*uj + (unsigned int)(*p++ - '0');          precision = uj;        }      }   /* parse 'h', 'l' and 'll' length modifiers */      if (*p == 'h' || *p == 'l') {        length_modifier = *p; p++;        if (length_modifier == 'l' && *p == 'l') {   /* double l = long long */#ifdef SNPRINTF_LONGLONG_SUPPORT          length_modifier = '2';                  /* double l encoded as '2' */#else          length_modifier = 'l';                 /* treat it as a single 'l' */#endif          p++;        }      }      fmt_spec = *p;   /* common synonyms: */      switch (fmt_spec) {      case 'i': fmt_spec = 'd'; break;      case 'D': fmt_spec = 'd'; length_modifier = 'l'; break;      case 'U': fmt_spec = 'u'; length_modifier = 'l'; break;      case 'O': fmt_spec = 'o'; length_modifier = 'l'; break;      default: break;      }   /* get parameter value, do initial processing */      switch (fmt_spec) {      case '%': /* % behaves similar to 's' regarding flags and field widths */      case 'c': /* c behaves similar to 's' regarding flags and field widths */      case 's':        length_modifier = '\0';          /* wint_t and wchar_t not supported */     /* the result of zero padding flag with non-numeric conversion specifier*/     /* is undefined. Solaris and HPUX 10 does zero padding in this case,    */

⌨️ 快捷键说明

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