pike.git / src / stralloc.c

version» Context lines:

pike.git/src/stralloc.c:1:   /*   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: stralloc.c,v 1.188 2004/11/09 12:27:53 grubba Exp $ + || $Id: stralloc.c,v 1.189 2004/11/11 14:57:11 grubba Exp $   */      #include "global.h"   #include "stralloc.h"   #include "pike_macros.h"   #include "dynamic_buffer.h"   #include "pike_macros.h"   #include "pike_memory.h"   #include "pike_error.h"   #include "gc.h"   #include "stuff.h"   #include "bignum.h"   #include "interpret.h"   #include "block_alloc.h"   #include "operators.h" -  + #include "pike_float.h"      #include <errno.h>   #include <float.h>   #include <ctype.h>   #include <math.h>      /* #define STRALLOC_USE_PRIMES */      #ifdef STRALLOC_USE_PRIMES   
pike.git/src/stralloc.c:2295:    * Note that APPEND_ZERO_PAD can not be active here, since    * len is at least min_width in that case.    * Note that APPEND_LEFT is always active here, since    * min_width isn't zero.    */    string_builder_fill(s, min_width - len, MKPCHARP(" ", 0),    4, 0);    }   }    - /* Values used internally in string_builder_vsprintf() */ - #define STATE_MIN_WIDTH 1 - #define STATE_PRECISION 2 -  +    /* Kludge around brokeness of gcc/x86_64 */   #ifdef VA_LIST_IS_STATE_PTR   #define VA_LIST_PTR va_list   #define VA_LIST_ADDR(X) (X)   #define VA_LIST_DEREF(X) (X)   #else   #define VA_LIST_PTR va_list *   #define VA_LIST_ADDR(X) (&(X))   #define VA_LIST_DEREF(X) (*(X))   #endif
pike.git/src/stralloc.c:2337: Inside #if defined(INT64)
   return va_arg(VA_LIST_DEREF(args), unsigned INT64);    case APPEND_WIDTH_LONG_LONG|APPEND_SIGNED:    return va_arg(VA_LIST_DEREF(args), INT64);   #endif /* INT64 */    }    Pike_fatal("string_builder_append_integerv(): Unsupported flags: 0x%04x\n",    flags);    return 0;   }    + /* Values used internally in string_builder_vsprintf() */ + #define STATE_MIN_WIDTH 1 + #define STATE_PRECISION 2 +    PMOD_EXPORT void string_builder_vsprintf(struct string_builder *s,    const char *fmt,    va_list args)   {    while (*fmt) {    if (*fmt == '%') {    int flags = 0;    size_t min_width = 0;    size_t precision = 0;    int state = 0;
pike.git/src/stralloc.c:2506:    case 'u':    string_builder_append_integer(s, pike_va_int(VA_LIST_ADDR(args), flags), 10,    flags, min_width, precision);    break;    case 'd':    string_builder_append_integer(s, pike_va_int(VA_LIST_ADDR(args), flags), 10,    flags | APPEND_SIGNED,    min_width, precision);    break;    -  /* FIMXE: TODO: Doubles (ie 'a', 'e', 'E', 'f', 'g', 'G'). */ +  /* FIMXE: TODO: Doubles (ie 'a', 'e', 'E', 'g', 'G'). */    -  +  /* %f used in modules/Image/colors.c. */ +  case 'f': +  { +  double val = va_arg(args, double); +  size_t bytes; +  +  if (PIKE_ISNAN(val)) { +  /* NaN */ +  string_builder_strcat(s, "nan"); +  break; +  } +  if (val < 0.0) { +  string_builder_putchar(s, '-'); +  val = -val; +  } else if (flags & APPEND_SIGNED) { +  string_builder_putchar(s, '+'); +  } +  if (val+val == val) { +  if (val > 0.0) { +  /* Infinity */ +  string_builder_strcat(s, "inf"); +  } else { +  string_builder_strcat(s, "0.0"); +  } +  break; +  } +  /* FIXME: Field lengths and precision. */ +  if ((bytes = snprintf(NULL, 0, "%f", val))) { +  p_wchar0 *p = string_builder_allocate(s, bytes, 0); +  size_t check = snprintf(p, bytes+1, "%f", val); +  if (check != bytes) { +  Pike_fatal("string_builder_vsprintf(): snprintf(%f) is not " +  "trustworthy: %"PRINTSIZET"u != %"PRINTSIZET"u\n", +  val, bytes, check); +  } +  if (s->s->size_shift) { +  /* We need to widen the string we just wrote. */ +  if (s->s->size_shift == 1) { +  p_wchar1 *p1 = (p_wchar1 *)p; +  while (bytes--) { +  p1[bytes] = p[bytes]; +  } +  } else { +  p_wchar2 *p2 = (p_wchar2 *)p; +  while (bytes--) { +  p2[bytes] = p[bytes]; +  } +  } +  } +  } +  } +  break; +     default:    Pike_fatal("string_builder_vsprintf(): Invalid formatting method: "    "'%c' 0x%x.\n", fmt[-1], fmt[-1]);    }    break;    }    } else {    const char *start = fmt;    while (*fmt && (*fmt != '%'))    fmt++;