Branch: Tag:

2004-11-06

2004-11-06 13:41:38 by Henrik Grubbström (Grubba) <grubba@grubba.org>

Added string_builder_append_integer().

Rev: src/stralloc.c:1.174
Rev: src/stralloc.h:1.84

2:   || 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.173 2004/11/05 16:09:35 grubba Exp $ + || $Id: stralloc.c,v 1.174 2004/11/06 13:41:38 grubba Exp $   */      #include "global.h"
1098: Inside #if defined(PIKE_DEBUG)
   }       if(do_hash(s) != s->hval) +  { +  locate_problem(wrong_hash);    Pike_fatal("Shared string hashed to other number.\n"); -  +  }       if(HMODULO(s->hval) != e)    {
2174:    s->s->str[s->s->len << s->s->size_shift] = 0;   }    + PMOD_EXPORT void string_builder_append_integer(struct string_builder *s, +  LONGEST val, +  unsigned int base, +  int flags) + { +  unsigned LONGEST tmp; +  const char *numbers = "0123456789abcdef"; +  if ((base < 2) || (base > 16)) { +  Pike_fatal("string_builder_append_int(): Unsupported base %u.\n", base); +  } +  if (flags & APPEND_UPPER_CASE) { +  numbers = "0123456789ABCDEF"; +  } +  if ((flags & APPEND_SIGNED) && (val < 0)) { +  string_builder_putchar(s, '-'); +  val = -val; +  } else if (flags & APPEND_POSITIVE) { +  string_builder_putchar(s, '+'); +  } +  tmp = val; +  if (base & (base - 1)) { +  int len = 0; +  +  /* Calculate the output length. +  * Use do-while to ensure that zero isn't output as an empty string. +  */ +  do { +  len++; +  tmp /= base; +  } while (tmp); +  +  tmp = val; +  switch(s->s->size_shift) { +  case 0: +  { +  p_wchar0 *p = string_builder_allocate(s, len, 0); +  do { +  p[--len] = numbers[tmp%base]; +  tmp /= base; +  } while (tmp); +  } +  break; +  case 1: +  { +  p_wchar1 *p = string_builder_allocate(s, len, 0); +  do { +  p[--len] = numbers[tmp%base]; +  tmp /= base; +  } while (tmp); +  } +  break; +  case 2: +  { +  p_wchar2 *p = string_builder_allocate(s, len, 0); +  do { +  p[--len] = numbers[tmp%base]; +  tmp /= base; +  } while (tmp); +  } +  break; +  } +  } else { +  /* base is a power of two, so we can do without +  * the division and modulo operations. +  */ +  int delta; +  int shift; +  unsigned int mask; +  +  for(delta = 1; (base>>delta) > 1; delta++) +  ; +  +  mask = (1<<delta)-1; /* Usually base-1. */ +  +  /* Start at delta, so that zero isn't output as an empty string. */ +  for (shift = delta; tmp >> shift; shift += delta) +  ; +  shift -= delta; +  while(shift >= 0) { +  string_builder_putchar(s, numbers[(tmp>>shift) & mask]); +  shift -= delta; +  } +  } + } +    PMOD_EXPORT void string_builder_vsprintf(struct string_builder *s,    const char *fmt,    va_list args)
2209:    string_builder_putchar(s, va_arg(args, INT32));    break;    case 'b': -  case 'o': -  case 'x': -  case 'X': -  { -  int delta; -  unsigned int val = va_arg(args, unsigned int); -  char *numbers = "0123456789abcdef"; -  int shift; -  unsigned int mask; -  -  switch (*fmt) { -  case 'b': -  delta = 1; +  string_builder_append_integer(s, va_arg(args, unsigned int), 2, 0);    break;    case 'o': -  delta = 3; +  string_builder_append_integer(s, va_arg(args, unsigned int), 8, 0);    break; -  case 'X': -  numbers = "0123456789ABCDEF"; -  /* FALL_THROUGH */ +     case 'x': -  delta = 4; +  string_builder_append_integer(s, va_arg(args, unsigned int), 16, 0);    break; -  default: -  fatal("Unsupported binary integer formatting directive '%c'\n", -  *fmt); +  case 'X': +  string_builder_append_integer(s, va_arg(args, unsigned int), 16, +  APPEND_UPPER_CASE);    break; -  } -  mask = (1<<delta)-1; -  -  for (shift = delta; val >> shift; shift += delta) -  ; -  shift -= delta; -  while(shift >= 0) { -  string_builder_putchar(s, numbers[(val>>shift) & mask]); -  shift -= delta; -  } -  } +  case 'u': +  string_builder_append_integer(s, va_arg(args, unsigned int), 10, 0);    break;    case 'd': -  case 'u': -  { -  unsigned int val = va_arg(args, unsigned int); -  unsigned int tmp; -  int len; -  if ((*fmt == 'd') && ((int)val < 0)) { -  string_builder_putchar(s, '-'); -  val = -val; -  } -  tmp = val; -  len = 0; -  do { -  len++; -  tmp /= 10; -  } while (tmp); -  -  switch(s->s->size_shift) { -  case 0: -  { -  p_wchar0 *p = string_builder_allocate(s, len, 0); -  do { -  p[--len] = '0' + val%10; -  val /= 10; -  } while (val); -  } +  string_builder_append_integer(s, va_arg(args, int), 10, APPEND_SIGNED);    break; -  case 1: -  { -  p_wchar1 *p = string_builder_allocate(s, len, 0); -  do { -  p[--len] = '0' + val%10; -  val /= 10; -  } while (val); -  } -  break; -  case 2: -  { -  p_wchar2 *p = string_builder_allocate(s, len, 0); -  do { -  p[--len] = '0' + val%10; -  val /= 10; -  } while (val); -  } -  break; -  } -  } -  break; -  +     default:    Pike_fatal("string_builder_vsprintf(): Invalid formatting method: "    "'%c' 0x%x.\n", *fmt, *fmt);