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.151 2003/02/26 12:31:57 mast Exp $ + || $Id: stralloc.c,v 1.152 2003/02/26 22:42:29 mast 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"
pike.git/src/stralloc.c:17:   #include "bignum.h"   #include "interpret.h"   #include "block_alloc.h"   #include "operators.h"      #include <errno.h>   #include <float.h>   #include <ctype.h>   #include <math.h>    - #ifndef HUGE - #define HUGE HUGE_VAL - #endif /*!HUGE*/ + RCSID("$Id: stralloc.c,v 1.152 2003/02/26 22:42:29 mast Exp $");    - RCSID("$Id: stralloc.c,v 1.151 2003/02/26 12:31:57 mast Exp $"); -  +    /* #define STRALLOC_USE_PRIMES */      #ifdef STRALLOC_USE_PRIMES      #define SET_HSIZE(X) htable_size=hashprimes[(X)]   #define HMODULO(X) ((X) % htable_size)      #else      #define SET_HSIZE(X) htable_mask=(htable_size=(1<<(X)))-1
pike.git/src/stralloc.c:2176:    Pike_fatal("Illegal shift in MEMCHR_PCHARP.\n");    return MKPCHARP(0,0); /* make wcc happy */   }      #define DIGIT(x) (WIDE_ISDIGIT(x) ? (x) - '0' : \    WIDE_ISLOWER(x) ? (x) + 10 - 'a' : (x) + 10 - 'A')   #define MBASE ('z' - 'a' + 1 + 10)      PMOD_EXPORT long STRTOL_PCHARP(PCHARP str, PCHARP *ptr, int base)   { -  register long val; -  register int c; -  int xx, neg = 0; +  /* Note: Code duplication in STRTOL and pcharp_to_svalue_inumber. */    -  +  unsigned long val, mul_limit; +  int c; +  int xx, neg = 0, add_limit, overflow = 0; +     if (ptr) *ptr = str;    if (base < 0 || base > MBASE) return 0;    if (!WIDE_ISALNUM(c = EXTRACT_PCHARP(str)))    { -  while (ISSPACE(c)) +  while (WIDE_ISSPACE(c))    {    INC_PCHARP(str,1);    c=EXTRACT_PCHARP(str);    }    switch (c)    {    case '-':    neg++;    case '+': /* fall-through */    INC_PCHARP(str,1);
pike.git/src/stralloc.c:2217:    }       if (!WIDE_ISALNUM(c) || (xx = DIGIT(c)) >= base)    return 0; /* no number formed */    if (base == 16 && c == '0' && isxdigit(INDEX_PCHARP(str,2)) &&    (INDEX_PCHARP(str,1) == 'x' || INDEX_PCHARP(str,1) == 'X'))    {    INC_PCHARP(str,2);    c = EXTRACT_PCHARP(str); /* skip over leading "0x" or "0X" */    } -  val=-DIGIT(c); +  +  if (neg) { +  mul_limit = (unsigned long) LONG_MIN / base; +  add_limit = (int) ((unsigned long) LONG_MIN % base); +  } +  else { +  mul_limit = LONG_MAX / base; +  add_limit = (int) (LONG_MAX % base); +  } +  +  val=DIGIT(c);    while(1)    {    INC_PCHARP(str,1);    c=EXTRACT_PCHARP(str);    if(!(WIDE_ISALNUM(c) && (xx=DIGIT(c)) < base)) break; -  val = base * val - xx; +  if (val > mul_limit || (val == mul_limit && xx > add_limit)) +  overflow = 1; +  else +  val = base * val + xx;    } -  +     if (ptr) *ptr = str; -  return (neg ? val : -val); +  if (overflow) { +  errno = ERANGE; +  return neg ? LONG_MIN : LONG_MAX;    } -  +  else { +  if (neg) +  return val > (unsigned long) LONG_MAX ? +  -(long) (val - (unsigned long) LONG_MAX) - LONG_MAX : +  -(long) val; +  else +  return (long) val; +  } + }      PMOD_EXPORT int string_to_svalue_inumber(struct svalue *r,    char * str,    char **ptr,    int base,    int maxlength)   {    PCHARP tmp;    int ret=pcharp_to_svalue_inumber(r,    MKPCHARP(str,0),
pike.git/src/stralloc.c:2268:    if(ptr) *ptr=(char *)tmp.ptr;    return ret;   }      PMOD_EXPORT int pcharp_to_svalue_inumber(struct svalue *r,    PCHARP str,    PCHARP *ptr,    int base,    ptrdiff_t maxlength)   { +  /* Note: Code duplication in STRTOL and STRTOL_PCHARP. */ +     PCHARP str_start;    -  INT_TYPE xx, neg = 0, is_bignum = 0, implicit_base = 0; -  INT_TYPE val; -  INT_TYPE c; +  unsigned INT_TYPE val, mul_limit; +  int c; +  int xx, neg = 0, add_limit, overflow = 0;       maxlength--; /* max_length <= 0 means no max length. */    str_start = str;       /* In case no number is formed. */    r->type = T_INT;    r->subtype = NUMBER_NUMBER;    r->u.integer = 0;    if(ptr != 0)    *ptr = str;
pike.git/src/stralloc.c:2308:    neg++;    /* Fall-through. */    case '+':    INC_PCHARP(str,1);    c = EXTRACT_PCHARP(str);    }    }       if(base == 0)    { -  implicit_base = 1; -  +     if(c != '0')    base = 10;    else if(INDEX_PCHARP(str,1) == 'x' || INDEX_PCHARP(str,1) == 'X')    base = 16;    else if(INDEX_PCHARP(str,1) == 'b' || INDEX_PCHARP(str,1) == 'B')    base = 2;    else    base = 8;    }   
pike.git/src/stralloc.c:2339:    isxdigit(INDEX_PCHARP(str,2)) &&    ((base==16 && (INDEX_PCHARP(str,1)=='x' || INDEX_PCHARP(str,1)=='X')) ||    (base==2 && (INDEX_PCHARP(str,1)=='b' || INDEX_PCHARP(str,1)=='B'))))    {    /* Skip over leading "0x", "0X", "0b" or "0B". */    INC_PCHARP(str,2);    c=EXTRACT_PCHARP(str);    }    str_start=str;    -  for(val = -DIGIT(c); +  if (neg) { +  mul_limit = (unsigned INT_TYPE) MIN_INT_TYPE / base; +  add_limit = (int) ((unsigned INT_TYPE) MIN_INT_TYPE % base); +  } +  else { +  mul_limit = MAX_INT_TYPE / base; +  add_limit = (int) (MAX_INT_TYPE % base); +  } +  +  for(val = DIGIT(c);    (INC_PCHARP(str,1), WIDE_ISALNUM(c = EXTRACT_PCHARP(str) )) &&    (xx = DIGIT(c)) < base &&    0 != maxlength--; )    { - #ifdef AUTO_BIGNUM -  if(INT_TYPE_MUL_OVERFLOW(val, base)) -  is_bignum = 1; - #endif /* AUTO_BIGNUM */ -  val = base * val; -  /* Accumulating a negative value avoids surprises near MIN_TYPE_INT. */ - #ifdef AUTO_BIGNUM -  if(INT_TYPE_SUB_OVERFLOW(val, xx)) -  is_bignum = 1; - #endif /* AUTO_BIGNUM */ -  val -= xx; +  if (val > mul_limit || (val == mul_limit && xx > add_limit)) +  overflow = 1; +  else +  val = base * val + xx;    }       if(ptr != 0)    *ptr = str;    -  if(neg) -  r->u.integer = val; -  else -  { +  if (overflow) {   #ifdef AUTO_BIGNUM -  if(INT_TYPE_NEG_OVERFLOW(val)) -  is_bignum = 1; - #endif /* AUTO_BIGNUM */ -  r->u.integer = -val; -  } -  - #ifdef AUTO_BIGNUM -  if(is_bignum) -  { +     push_string(make_shared_binary_pcharp(str_start,    SUBTRACT_PCHARP(str,str_start))); -  /* Note that this can concievably throw errors() +  /* Note that this can conceivably throw errors()    * in some situations that might not be desirable...    * take care.    * /Hubbe    *    * It could probably also be faster...    */    push_int(base);    convert_stack_top_with_base_to_bignum();    if(neg) o_negate();       *r = *--Pike_sp; -  +  dmalloc_touch_svalue (r); + #else /* !AUTO_BIGNUM */ +  r->u.integer = neg ? MIN_INT_TYPE : MAX_INT_TYPE; + #endif    } - #endif /* AUTO_BIGNUM */ +  else { +  if (neg) +  r->u.integer = val > (unsigned INT_TYPE) MAX_INT_TYPE ? +  -(INT_TYPE) (val - (unsigned INT_TYPE) MAX_INT_TYPE) - MAX_INT_TYPE : +  -(INT_TYPE) val; +  else +  r->u.integer = (INT_TYPE) val; +  }       return 1;   }      PMOD_EXPORT int convert_stack_top_string_to_inumber(int base)   {    struct svalue r;    int i;       if(Pike_sp[-1].type != T_STRING)
pike.git/src/stralloc.c:2545:    if(exponent < 0 && exponent >-100) /* make sure we don't underflow */    num /= pow(10.0, (double) -exponent);    else    num *= pow(10.0, (double) exponent);       return num * sign;       overflow:    /* Return an overflow error. */    errno = ERANGE; -  return HUGE * sign; +  return HUGE_VAL * sign;       underflow:    /* Return an underflow error. */   #if 0    if (endptr != NULL)    *endptr = nptr;   #endif    errno = ERANGE;    return 0.0;