cb2256 | 1995-10-11 | Fredrik Hübinette (Hubbe) | | |
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | ||| This file a part of Pike, and is copyright by Fredrik Hubinette
||| Pike is distributed as GPL (General Public License)
|
cb2256 | 1995-10-11 | Fredrik Hübinette (Hubbe) | | ||| See the files COPYING and DISCLAIMER for more information.
\*/
|
82b1ff | 1999-02-27 | Henrik Grubbström (Grubba) | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #include "global.h"
#include "stralloc.h"
|
bb55f8 | 1997-03-16 | Fredrik Hübinette (Hubbe) | | #include "pike_macros.h"
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #include "dynamic_buffer.h"
|
bb55f8 | 1997-03-16 | Fredrik Hübinette (Hubbe) | | #include "pike_macros.h"
|
9aa6fa | 1997-05-19 | Fredrik Hübinette (Hubbe) | | #include "pike_memory.h"
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #include "error.h"
|
9c6f7d | 1997-04-15 | Fredrik Hübinette (Hubbe) | | #include "gc.h"
|
75920f | 1997-12-28 | Fredrik Hübinette (Hubbe) | | #include "stuff.h"
|
31ea27 | 1999-10-22 | Fredrik Noring | | #include "bignum.h"
#include "interpret.h"
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
f3ece8 | 1999-02-28 | Fredrik Hübinette (Hubbe) | | #include <errno.h>
|
4c3904 | 1999-03-23 | Marcus Comstedt | | #include <float.h>
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | #include <ctype.h>
|
f3ece8 | 1999-02-28 | Fredrik Hübinette (Hubbe) | | #include <math.h>
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | |
|
4c3904 | 1999-03-23 | Marcus Comstedt | | #ifndef HUGE
#define HUGE HUGE_VAL
#endif /*!HUGE*/
|
c3dbe5 | 2000-08-09 | Henrik Grubbström (Grubba) | | RCSID("$Id: stralloc.c,v 1.91 2000/08/09 18:46:10 grubba Exp $");
|
24ddc7 | 1998-03-28 | Henrik Grubbström (Grubba) | |
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | #define BEGIN_HASH_SIZE 997
#define MAX_AVG_LINK_LENGTH 3
|
2cbf7c | 1999-09-01 | Fredrik Hübinette (Hubbe) | |
#ifndef HASH_PREFIX
|
8f4f38 | 1999-09-16 | Fredrik Hübinette (Hubbe) | | static unsigned int HASH_PREFIX=64;
|
fe3c9f | 1999-09-06 | Henrik Grubbström (Grubba) | | static unsigned int need_more_hash_prefix=0;
|
2cbf7c | 1999-09-01 | Fredrik Hübinette (Hubbe) | | #endif
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
unsigned INT32 htable_size=0;
|
75920f | 1997-12-28 | Fredrik Hübinette (Hubbe) | | static unsigned int hashprimes_entry=0;
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | static struct pike_string **base_table=0;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | static unsigned INT32 full_hash_value;
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | unsigned INT32 num_strings=0;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
#define StrHash(s,len) low_do_hash(s,len,0)
static unsigned int low_do_hash(const void *s, int len, int size_shift)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | full_hash_value=hashmem(s,len<<size_shift,HASH_PREFIX<<size_shift);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | return full_hash_value % htable_size;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | static INLINE unsigned int do_hash(struct pike_string *s)
{
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | return low_do_hash(s->str, s->len, s->size_shift);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | }
static INLINE int find_magnitude1(const unsigned INT16 *s, int len)
{
while(--len>=0)
if(s[len]>=256)
return 1;
return 0;
}
static INLINE int find_magnitude2(const unsigned INT32 *s, int len)
{
while(--len>=0)
{
if(s[len]>=256)
{
do
{
if(s[len]>=65536)
return 2;
}while(--len>=0);
return 1;
}
}
return 0;
}
static INLINE int min_magnitude(const unsigned INT32 c)
{
if(c<256) return 0;
if(c<65536) return 1;
return 2;
}
|
e52673 | 2000-08-04 | Henrik Grubbström (Grubba) | | static INLINE unsigned INT32 generic_extract (const void *str, int size, ptrdiff_t pos)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
switch(size)
{
case 0: return ((unsigned char *)str)[pos];
case 1: return ((unsigned INT16 *)str)[pos];
case 2: return ((unsigned INT32 *)str)[pos];
}
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | fatal("Illegal shift size!\n");
return 0;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | }
|
e52673 | 2000-08-04 | Henrik Grubbström (Grubba) | | PMOD_EXPORT INLINE unsigned INT32 index_shared_string(struct pike_string *s, ptrdiff_t pos)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
a8f9bd | 1998-10-15 | Henrik Grubbström (Grubba) | | if(pos > s->len || pos<0) {
|
49ed18 | 1998-10-15 | Henrik Grubbström (Grubba) | | if (s->len) {
fatal("String index %d is out of range [0 - %d]!\n", pos, s->len-1);
} else {
fatal("Attempt to index the empty string with %d!\n", pos);
}
}
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | #endif
return generic_extract(s->str,s->size_shift,pos);
}
|
c3dbe5 | 2000-08-09 | Henrik Grubbström (Grubba) | | PMOD_EXPORT INLINE void low_set_index(struct pike_string *s, ptrdiff_t pos,
int value)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | if(pos > s->len || pos<0)
fatal("string index out of range!\n");
if(pos == s->len && value)
fatal("string zero termination foul!\n");
#endif
switch(s->size_shift)
{
case 0: STR0(s)[pos]=value; break;
case 1: STR1(s)[pos]=value; break;
case 2: STR2(s)[pos]=value; break;
default:
fatal("Illegal shift size!\n");
}
}
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT INLINE struct pike_string *debug_check_size_shift(struct pike_string *a,int shift)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
if(a->size_shift != shift)
fatal("Wrong STRX macro used!\n");
return a;
}
#endif
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | #define CONVERT(FROM,TO) \
|
e4b225 | 2000-08-09 | Henrik Grubbström (Grubba) | | INLINE void PIKE_CONCAT4(convert_,FROM,_to_,TO)(PIKE_CONCAT(p_wchar,TO) *to, const PIKE_CONCAT(p_wchar,FROM) *from, ptrdiff_t len) \
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | { while(--len>=0) *(to++)=*(from++); } \
|
e4b225 | 2000-08-09 | Henrik Grubbström (Grubba) | | INLINE INT32 PIKE_CONCAT4(compare_,FROM,_to_,TO)(const PIKE_CONCAT(p_wchar,TO) *to, const PIKE_CONCAT(p_wchar,FROM) *from, ptrdiff_t len) \
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | { int tmp; while(--len>=0) if((tmp=*(to++)-*(from++))) return tmp; return 0; }
CONVERT(0,1)
CONVERT(0,2)
CONVERT(1,0)
CONVERT(1,2)
CONVERT(2,0)
CONVERT(2,1)
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int generic_compare_strings(const void *a,int alen, int asize,
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | const void *b,int blen, int bsize)
{
#define TWO_SIZES(X,Y) (((X)<<2)+(Y))
if(alen != blen) return 0;
if(asize==bsize)
{
|
19b73a | 1999-08-14 | Per Hedbor | | return !MEMCMP(a,b,alen<<asize);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | }else{
INT32 pos;
for(pos=0;pos< alen ;pos++)
if(generic_extract(a,asize,pos) != generic_extract(b,bsize,pos))
return 0;
return 1;
}
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void generic_memcpy(PCHARP to,
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | PCHARP from,
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | int len)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
|
68d913 | 1999-04-01 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
if(len<0)
fatal("Cannot copy %d bytes!\n",len);
#endif
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | switch(TWO_SIZES(from.shift,to.shift))
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
case TWO_SIZES(0,0):
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | convert_0_to_0((p_wchar0 *)to.ptr,(p_wchar0 *)from.ptr,len);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | break;
case TWO_SIZES(0,1):
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | convert_0_to_1((p_wchar1 *)to.ptr,(p_wchar0 *)from.ptr,len);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | break;
case TWO_SIZES(0,2):
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | convert_0_to_2((p_wchar2 *)to.ptr,(p_wchar0 *)from.ptr,len);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | break;
case TWO_SIZES(1,0):
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | convert_1_to_0((p_wchar0 *)to.ptr,(p_wchar1 *)from.ptr,len);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | break;
case TWO_SIZES(1,1):
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | convert_1_to_1((p_wchar1 *)to.ptr,(p_wchar1 *)from.ptr,len);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | break;
case TWO_SIZES(1,2):
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | convert_1_to_2((p_wchar2 *)to.ptr,(p_wchar1 *)from.ptr,len);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | break;
case TWO_SIZES(2,0):
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | convert_2_to_0((p_wchar0 *)to.ptr,(p_wchar2 *)from.ptr,len);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | break;
case TWO_SIZES(2,1):
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | convert_2_to_1((p_wchar1 *)to.ptr,(p_wchar2 *)from.ptr,len);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | break;
case TWO_SIZES(2,2):
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | convert_2_to_2((p_wchar2 *)to.ptr,(p_wchar2 *)from.ptr,len);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | break;
}
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT INLINE void pike_string_cpy(PCHARP to,
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | struct pike_string *from)
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | {
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | generic_memcpy(to,MKPCHARP_STR(from),from->len);
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | }
|
501421 | 1998-10-14 | Fredrik Hübinette (Hubbe) | |
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
501421 | 1998-10-14 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG_MALLOC
#define DM(X) X
#else
#define DM(X)
#endif
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | static void locate_problem(int (*isproblem)(struct pike_string *))
{
unsigned INT32 e;
struct pike_string *s;
|
9e5238 | 1998-03-01 | Fredrik Hübinette (Hubbe) | | DM(struct memhdr *yes=alloc_memhdr());
DM(struct memhdr *no=alloc_memhdr());
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | |
for(e=0;e<htable_size;e++)
|
9e5238 | 1998-03-01 | Fredrik Hübinette (Hubbe) | | {
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | for(s=base_table[e];s;s=s->next)
|
9e5238 | 1998-03-01 | Fredrik Hübinette (Hubbe) | | {
if(isproblem(s))
{
fprintf(stderr,"***Guilty string:\n");
debug_dump_pike_string(s, 70);
DM(add_marks_to_memhdr(yes,s));
}else{
DM(add_marks_to_memhdr(no,s));
}
}
}
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | |
|
9e5238 | 1998-03-01 | Fredrik Hübinette (Hubbe) | | DM(fprintf(stderr,"Plausible problem location(s):\n"));
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | DM(dump_memhdr_locations(yes,0,0));
|
9e5238 | 1998-03-01 | Fredrik Hübinette (Hubbe) | |
DM(fprintf(stderr,"More Plausible problem location(s):\n"));
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | DM(dump_memhdr_locations(yes,no,0));
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | }
static int has_zero_refs(struct pike_string *s)
{
return s->refs<=0;
}
static int wrong_hash(struct pike_string *s)
{
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | return (s->hval % htable_size) != do_hash(s);
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | }
static int improper_zero_termination(struct pike_string *s)
{
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | return index_shared_string(s,s->len);
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | }
#else
#define locate_problem(X)
#endif
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
fe3c9f | 1999-09-06 | Henrik Grubbström (Grubba) | |
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | static struct pike_string *internal_findstring(const char *s,
int len,
int size_shift,
int h)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *curr,**prev, **base;
|
2cbf7c | 1999-09-01 | Fredrik Hübinette (Hubbe) | | #ifndef HASH_PREFIX
unsigned int depth=0;
#endif
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
for(base = prev = base_table + h;( curr=*prev ); prev=&curr->next)
{
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | if(curr->refs<1)
|
38d608 | 1998-02-07 | Fredrik Hübinette (Hubbe) | | {
debug_dump_pike_string(curr, 70);
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | locate_problem(has_zero_refs);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | fatal("String with no references.\n");
|
38d608 | 1998-02-07 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #endif
|
f43e42 | 1999-10-21 | Fredrik Hübinette (Hubbe) | | debug_malloc_touch(curr);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
if (full_hash_value == curr->hval &&
len==curr->len &&
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | size_shift==curr->size_shift &&
|
66769e | 1999-11-04 | Fredrik Hübinette (Hubbe) | | ( curr->str == s ||
!MEMCMP(curr->str, s,len<<size_shift)))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
*prev = curr->next;
curr->next = *base;
*base = curr;
return curr;
}
|
2cbf7c | 1999-09-01 | Fredrik Hübinette (Hubbe) | | #ifndef HASH_PREFIX
depth++;
#endif
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
2cbf7c | 1999-09-01 | Fredrik Hübinette (Hubbe) | | #ifndef HASH_PREFIX
|
fe3c9f | 1999-09-06 | Henrik Grubbström (Grubba) | | if((depth > HASH_PREFIX) && (HASH_PREFIX < (unsigned int)len))
|
2cbf7c | 1999-09-01 | Fredrik Hübinette (Hubbe) | | {
need_more_hash_prefix++;
}else{
if(need_more_hash_prefix)
need_more_hash_prefix--;
}
#endif
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return 0;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct pike_string *binary_findstring(const char *foo, INT32 l)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | return internal_findstring(foo, l, 0, StrHash(foo,l));
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct pike_string *findstring(const char *foo)
|
ca74dd | 1996-10-08 | Fredrik Hübinette (Hubbe) | | {
return binary_findstring(foo, strlen(foo));
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | static struct pike_string *propagate_shared_string(const struct pike_string *s,
int h)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *curr, **prev, **base;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
for(base = prev = base_table + h;( curr=*prev ); prev=&curr->next)
{
if (curr == s)
{
*prev=curr->next;
curr->next=*base;
*base=curr;
return curr;
}
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | if(curr->refs<1)
|
38d608 | 1998-02-07 | Fredrik Hübinette (Hubbe) | | {
debug_dump_pike_string(curr, 70);
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | locate_problem(has_zero_refs);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | fatal("String with no references.\n");
|
38d608 | 1998-02-07 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #endif
}
return 0;
}
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
static void rehash_string_backwards(struct pike_string *s)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | int h;
if(!s) return;
rehash_string_backwards(s->next);
h=s->hval % htable_size;
s->next=base_table[h];
base_table[h]=s;
}
|
aef30b | 1996-10-11 | Fredrik Hübinette (Hubbe) | |
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | static void rehash(void)
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | {
int h,old;
struct pike_string **old_base;
|
aef30b | 1996-10-11 | Fredrik Hübinette (Hubbe) | |
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | old=htable_size;
old_base=base_table;
|
75920f | 1997-12-28 | Fredrik Hübinette (Hubbe) | | htable_size=hashprimes[++hashprimes_entry];
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | base_table=(struct pike_string **)xalloc(sizeof(struct pike_string *)*htable_size);
MEMSET((char *)base_table,0,sizeof(struct pike_string *)*htable_size);
|
2cbf7c | 1999-09-01 | Fredrik Hübinette (Hubbe) | | for(h=0;h<old;h++)
rehash_string_backwards(old_base[h]);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
if(old_base)
free((char *)old_base);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
c8318b | 2000-08-03 | Henrik Grubbström (Grubba) | | PMOD_EXPORT struct pike_string *debug_begin_shared_string(size_t len)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *t;
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
6a1371 | 1998-04-17 | Fredrik Hübinette (Hubbe) | | extern int d_flag;
|
7abf49 | 1998-04-17 | Fredrik Hübinette (Hubbe) | | if(d_flag>10)
verify_shared_strings_tables();
#endif
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | t=(struct pike_string *)xalloc(len + sizeof(struct pike_string));
|
ca74dd | 1996-10-08 | Fredrik Hübinette (Hubbe) | | t->str[len]=0;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | t->len=len;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | t->size_shift=0;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return t;
}
|
fe3c9f | 1999-09-06 | Henrik Grubbström (Grubba) | | static void link_pike_string(struct pike_string *s, unsigned int h)
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | {
s->refs = 0;
s->next = base_table[h];
base_table[h] = s;
s->hval=full_hash_value;
num_strings++;
if(num_strings > MAX_AVG_LINK_LENGTH * htable_size)
rehash();
|
2cbf7c | 1999-09-01 | Fredrik Hübinette (Hubbe) | |
#ifndef HASH_PREFIX
if(need_more_hash_prefix > ( htable_size >> 4))
{
unsigned INT32 save_full_hash_value=full_hash_value;
need_more_hash_prefix=0;
HASH_PREFIX=HASH_PREFIX*2;
for(h=0;h<htable_size;h++)
{
struct pike_string *tmp=base_table[h];
base_table[h]=0;
while(tmp)
{
|
fe3c9f | 1999-09-06 | Henrik Grubbström (Grubba) | | unsigned int h2;
|
2cbf7c | 1999-09-01 | Fredrik Hübinette (Hubbe) | | struct pike_string *tmp2=tmp;
tmp=tmp2->next;
h2=do_hash(tmp2);
tmp2->hval=full_hash_value;
tmp2->next=base_table[h2];
base_table[h2]=tmp2;
}
}
full_hash_value=save_full_hash_value;
}
#endif
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | }
|
c8318b | 2000-08-03 | Henrik Grubbström (Grubba) | | PMOD_EXPORT struct pike_string *debug_begin_wide_shared_string(size_t len, int shift)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
struct pike_string *t;
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | extern int d_flag;
if(d_flag>10)
verify_shared_strings_tables();
#endif
t=(struct pike_string *)xalloc((len<<shift) + sizeof(struct pike_string));
t->len=len;
t->size_shift=shift;
low_set_index(t,len,0);
return t;
}
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | |
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct pike_string *low_end_shared_string(struct pike_string *s)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
int len,h;
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *s2;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | len=s->len;
h=do_hash(s);
s2=internal_findstring(s->str,len,s->size_shift,h);
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | if(s2==s)
fatal("end_shared_string called twice! (or something like that)\n");
#endif
if(s2)
{
free((char *)s);
s=s2;
}else{
link_pike_string(s, h);
}
add_ref(s);
return s;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct pike_string *end_shared_string(struct pike_string *s)
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | {
struct pike_string *s2;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | switch(s->size_shift)
{
default:
|
1231a4 | 1998-10-29 | Henrik Grubbström (Grubba) | | fatal("ARGHEL! size_shift:%d\n", s->size_shift);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
case 2:
switch(find_magnitude2(STR2(s),s->len))
{
case 0:
s2=begin_shared_string(s->len);
convert_2_to_0(STR0(s2),STR2(s),s->len);
free((char *)s);
s=s2;
break;
case 1:
|
82b1ff | 1999-02-27 | Henrik Grubbström (Grubba) | | s2=begin_wide_shared_string(s->len,1);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | convert_2_to_1(STR1(s2),STR2(s),s->len);
free((char *)s);
s=s2;
}
break;
case 1:
if(!find_magnitude1(STR1(s),s->len))
{
s2=begin_shared_string(s->len);
convert_1_to_0(STR0(s2),STR1(s),s->len);
free((char *)s);
s=s2;
}
break;
case 0: break;
}
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | return low_end_shared_string(s);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
|
c8318b | 2000-08-03 | Henrik Grubbström (Grubba) | | PMOD_EXPORT struct pike_string * debug_make_shared_binary_string(const char *str,size_t len)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *s;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | int h=StrHash(str,len);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | s = internal_findstring(str,len,0,h);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | if (!s)
{
s=begin_shared_string(len);
MEMCPY(s->str, str, len);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | link_pike_string(s, h);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
d6ac73 | 1998-04-20 | Henrik Grubbström (Grubba) | | add_ref(s);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
return s;
}
|
c8318b | 2000-08-03 | Henrik Grubbström (Grubba) | | PMOD_EXPORT struct pike_string * debug_make_shared_binary_pcharp(const PCHARP str,size_t len)
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | {
switch(str.shift)
{
case 0:
|
01a957 | 2000-02-03 | Henrik Grubbström (Grubba) | | return make_shared_binary_string((char *)(str.ptr), len);
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | case 1:
return make_shared_binary_string1((p_wchar1 *)(str.ptr), len);
case 2:
return make_shared_binary_string2((p_wchar2 *)(str.ptr), len);
default:
fatal("Unknown string width!\n");
}
|
2a515a | 2000-06-27 | Henrik Grubbström (Grubba) | |
return NULL;
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | }
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct pike_string * debug_make_shared_pcharp(const PCHARP str)
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | {
return debug_make_shared_binary_pcharp(str, pcharp_strlen(str));
}
|
c8318b | 2000-08-03 | Henrik Grubbström (Grubba) | | PMOD_EXPORT struct pike_string * debug_make_shared_binary_string0(const p_wchar0 *str,size_t len)
|
50d6d3 | 1999-10-31 | Henrik Grubbström (Grubba) | | {
|
a0d5ae | 1999-10-31 | Henrik Grubbström (Grubba) | | return debug_make_shared_binary_string((const char *)str, len);
|
50d6d3 | 1999-10-31 | Henrik Grubbström (Grubba) | | }
|
c8318b | 2000-08-03 | Henrik Grubbström (Grubba) | | PMOD_EXPORT struct pike_string * debug_make_shared_binary_string1(const p_wchar1 *str,size_t len)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
struct pike_string *s;
int h;
if(!find_magnitude1(str,len))
{
s=begin_shared_string(len);
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | convert_1_to_0(STR0(s),str,len);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | return end_shared_string(s);
}
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | h=low_do_hash(str, len, 1);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
s = internal_findstring((char *)str,len,1,h);
if (!s)
{
s=begin_wide_shared_string(len,1);
MEMCPY(s->str, str, len<<1);
link_pike_string(s, h);
}
add_ref(s);
return s;
}
|
c8318b | 2000-08-03 | Henrik Grubbström (Grubba) | | PMOD_EXPORT struct pike_string * debug_make_shared_binary_string2(const p_wchar2 *str,size_t len)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
struct pike_string *s;
int h;
switch(find_magnitude2(str,len))
{
case 0:
s=begin_shared_string(len);
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | convert_2_to_0(STR0(s),str,len);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | return end_shared_string(s);
case 1:
s=begin_wide_shared_string(len,1);
convert_2_to_1(STR1(s),str,len);
return end_shared_string(s);
}
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | h=low_do_hash(str, len, 2);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
s = internal_findstring((char *)str,len,2,h);
if (!s)
{
s=begin_wide_shared_string(len,2);
MEMCPY(s->str, str, len<<2);
link_pike_string(s, h);
}
add_ref(s);
return s;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct pike_string *debug_make_shared_string(const char *str)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
return make_shared_binary_string(str, strlen(str));
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct pike_string *debug_make_shared_string0(const p_wchar0 *str)
|
50d6d3 | 1999-10-31 | Henrik Grubbström (Grubba) | | {
|
a0d5ae | 1999-10-31 | Henrik Grubbström (Grubba) | | return debug_make_shared_string((const char *)str);
|
50d6d3 | 1999-10-31 | Henrik Grubbström (Grubba) | | }
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct pike_string *debug_make_shared_string1(const p_wchar1 *str)
|
4d1ed1 | 1998-09-18 | Fredrik Hübinette (Hubbe) | | {
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | INT32 len;
|
4d1ed1 | 1998-09-18 | Fredrik Hübinette (Hubbe) | | for(len=0;str[len];len++);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | return debug_make_shared_binary_string1(str,len);
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct pike_string *debug_make_shared_string2(const p_wchar2 *str)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
INT32 len;
for(len=0;str[len];len++);
return debug_make_shared_binary_string2(str,len);
|
4d1ed1 | 1998-09-18 | Fredrik Hübinette (Hubbe) | | }
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void unlink_pike_string(struct pike_string *s)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
c9e5eb | 1999-10-19 | Henrik Grubbström (Grubba) | | unsigned int h=s->hval % htable_size;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | propagate_shared_string(s,h);
base_table[h]=s->next;
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
230223 | 1998-04-23 | Fredrik Hübinette (Hubbe) | | s->next=(struct pike_string *)-1;
#endif
|
760b26 | 1996-12-03 | Fredrik Hübinette (Hubbe) | | num_strings--;
|
0a3d60 | 1996-10-09 | Fredrik Hübinette (Hubbe) | | }
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void do_free_string(struct pike_string *s)
|
04965a | 1998-12-06 | Fredrik Hübinette (Hubbe) | | {
|
65b673 | 2000-07-07 | Martin Stjernholm | | if (s)
free_string(s);
|
04965a | 1998-12-06 | Fredrik Hübinette (Hubbe) | | }
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void really_free_string(struct pike_string *s)
|
0a3d60 | 1996-10-09 | Fredrik Hübinette (Hubbe) | | {
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
936735 | 1997-01-27 | Fredrik Hübinette (Hubbe) | | extern int d_flag;
|
2a515a | 2000-06-27 | Henrik Grubbström (Grubba) | | if (d_flag) {
if (s->refs) {
fatal("Freeing string with references!\n");
}
if(d_flag > 2)
{
if(s->next == (struct pike_string *)-1)
fatal("Freeing shared string again!\n");
|
7abf49 | 1998-04-17 | Fredrik Hübinette (Hubbe) | |
|
2a515a | 2000-06-27 | Henrik Grubbström (Grubba) | | if(((long)s->next) & 1)
fatal("Freeing shared string again, memory corrupt or other bug!\n");
}
|
936735 | 1997-01-27 | Fredrik Hübinette (Hubbe) | | }
#endif
|
0a3d60 | 1996-10-09 | Fredrik Hübinette (Hubbe) | | unlink_pike_string(s);
|
20f7a0 | 2000-03-20 | Fredrik Hübinette (Hubbe) | | debug_free((char *)s,DMALLOC_LOCATION(),1);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void debug_free_string(struct pike_string *s)
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | {
if(--s->refs<=0)
really_free_string(s);
}
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | |
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | * String table status
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | */
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *add_string_status(int verbose)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
char b[200];
init_buf();
if (verbose)
{
int allocd_strings=0;
int allocd_bytes=0;
int num_distinct_strings=0;
int bytes_distinct_strings=0;
int overhead_bytes=0;
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | unsigned INT32 e;
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *p;
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | for(e=0;e<htable_size;e++)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
for(p=base_table[e];p;p=p->next)
{
num_distinct_strings++;
|
90e978 | 1999-01-31 | Fredrik Hübinette (Hubbe) | | bytes_distinct_strings+=DO_ALIGN(p->len,sizeof(void *));
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | allocd_strings+=p->refs;
|
90e978 | 1999-01-31 | Fredrik Hübinette (Hubbe) | | allocd_bytes+=p->refs*DO_ALIGN(p->len+3,sizeof(void *));
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | overhead_bytes=(sizeof(struct pike_string)-1)*num_distinct_strings;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | my_strcat("\nShared string hash table:\n");
my_strcat("-------------------------\t Strings Bytes\n");
sprintf(b,"Total asked for\t\t\t%8ld %8ld\n",
(long)allocd_strings, (long)allocd_bytes);
my_strcat(b);
sprintf(b,"Strings malloced\t\t%8ld %8ld + %ld overhead\n",
(long)num_distinct_strings,
(long)bytes_distinct_strings,
(long)overhead_bytes);
my_strcat(b);
sprintf(b,"Space actually required/total string bytes %d%%\n",
(bytes_distinct_strings + overhead_bytes)*100 / allocd_bytes);
my_strcat(b);
}
return free_buf();
}
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | |
#ifdef PIKE_DEBUG
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void check_string(struct pike_string *s)
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | {
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | do_hash(s);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | if(full_hash_value != s->hval)
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | {
locate_problem(wrong_hash);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | fatal("Hash value changed?\n");
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | }
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
if(debug_findstring(s) !=s)
fatal("Shared string not shared.\n");
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | if(index_shared_string(s,s->len))
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | {
locate_problem(improper_zero_termination);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | fatal("Shared string is not zero terminated properly.\n");
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | }
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | }
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void verify_shared_strings_tables(void)
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | {
|
beac72 | 1998-04-16 | Fredrik Hübinette (Hubbe) | | unsigned INT32 e, h, num=0;
|
95fd02 | 1998-05-25 | Henrik Grubbström (Grubba) | | unsigned INT32 orig_full_hash = full_hash_value;
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | struct pike_string *s;
for(e=0;e<htable_size;e++)
{
h=0;
for(s=base_table[e];s;s=s->next)
{
|
beac72 | 1998-04-16 | Fredrik Hübinette (Hubbe) | | num++;
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | h++;
if(s->len < 0)
fatal("Shared string shorter than zero bytes.\n");
if(s->refs <= 0)
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | {
locate_problem(has_zero_refs);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | fatal("Shared string had too few references.\n");
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | }
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
|
f4e1ec | 1998-10-22 | Fredrik Hübinette (Hubbe) | | if(index_shared_string(s,s->len))
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | {
locate_problem(improper_zero_termination);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | fatal("Shared string didn't end with a zero.\n");
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | }
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | if(do_hash(s) != e)
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | {
locate_problem(wrong_hash);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | fatal("Shared string hashed to wrong place.\n");
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | }
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
if(s->hval != full_hash_value)
fatal("Shared string hashed to other number.\n");
if(h>10000)
{
struct pike_string *s2;
for(s2=s;s2;s2=s2->next)
if(s2 == s)
fatal("Shared string table is cyclic.\n");
h=0;
}
}
}
|
beac72 | 1998-04-16 | Fredrik Hübinette (Hubbe) | | if(num != num_strings)
fatal("Num strings is wrong %d!=%d\n",num,num_strings);
|
95fd02 | 1998-05-25 | Henrik Grubbström (Grubba) | | full_hash_value = orig_full_hash;
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | }
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int safe_debug_findstring(struct pike_string *foo)
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | | {
unsigned INT32 e;
if(!base_table) return 0;
for(e=0;e<htable_size;e++)
{
struct pike_string *p;
for(p=base_table[e];p;p=p->next)
if(p==foo) return 1;
}
return 0;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct pike_string *debug_findstring(const struct pike_string *foo)
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | {
struct pike_string *tmp;
tmp=propagate_shared_string(foo, foo->hval % htable_size);
#if 0
if(!tmp)
{
unsigned INT32 e;
struct pike_string *tmp2;
fprintf(stderr,"String %p %ld %ld %s\n",
foo,
(long)foo->hval,
(long)foo->len,
foo->str);
StrHash(foo->str,foo->len);
fprintf(stderr,"------ %p %ld\n",
base_table[foo->hval %htable_size],
(long)full_hash_value);
for(tmp2=base_table[foo->hval % htable_size];tmp2;tmp2=tmp2->next)
{
if(tmp2 == tmp)
fprintf(stderr,"!!%p!!->",tmp2);
else
fprintf(stderr,"%p->",tmp2);
}
fprintf(stderr,"0\n");
for(e=0;e<htable_size;e++)
{
for(tmp2=base_table[e];tmp2;tmp2=tmp2->next)
{
if(tmp2 == tmp)
fprintf(stderr,"String found in hashbin %ld (not %ld)\n",
(long)e,
(long)(foo->hval % htable_size));
}
}
}
#endif
return tmp;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void debug_dump_pike_string(struct pike_string *s, INT32 max)
|
38d608 | 1998-02-07 | Fredrik Hübinette (Hubbe) | | {
INT32 e;
|
a73744 | 1998-10-11 | Henrik Grubbström (Grubba) | | fprintf(stderr,"0x%p: %ld refs, len=%ld, size_shift=%d, hval=%lux (%lx)\n",
|
38d608 | 1998-02-07 | Fredrik Hübinette (Hubbe) | | s,
(long)s->refs,
(long)s->len,
|
a73744 | 1998-10-11 | Henrik Grubbström (Grubba) | | s->size_shift,
|
38d608 | 1998-02-07 | Fredrik Hübinette (Hubbe) | | (unsigned long)s->hval,
(unsigned long)StrHash(s->str, s->len));
fprintf(stderr," \"");
for(e=0;e<s->len && max>0;e++)
{
int c=EXTRACT_UCHAR(s->str+e);
switch(c)
{
case '\t': fprintf(stderr,"\\t"); max-=2; break;
case '\n': fprintf(stderr,"\\n"); max-=2; break;
case '\r': fprintf(stderr,"\\r"); max-=2; break;
case '\b': fprintf(stderr,"\\b"); max-=2; break;
default:
if(is8bitalnum(c) || c==' ' || isgraph(c))
{
putc(c,stderr);
max--;
}else{
fprintf(stderr,"\\%03o",c);
max-=4;
}
}
}
if(!max)
fprintf(stderr,"...\n");
else
fprintf(stderr,"\"\n");
}
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | void dump_stralloc_strings(void)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | unsigned INT32 e;
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *p;
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | for(e=0;e<htable_size;e++)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | for(p=base_table[e];p;p=p->next)
|
38d608 | 1998-02-07 | Fredrik Hübinette (Hubbe) | | debug_dump_pike_string(p, 70);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | #endif
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int low_quick_binary_strcmp(char *a,INT32 alen,
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | char *b,INT32 blen)
{
int tmp;
if(alen > blen)
{
tmp=MEMCMP(a, b, blen);
if(tmp) return tmp;
return 1;
}else if(alen < blen){
tmp=MEMCMP(a, b, alen);
if(tmp) return tmp;
return -1;
}else{
return MEMCMP(a, b, alen);
}
}
|
a5787d | 1999-03-03 | Fredrik Hübinette (Hubbe) | |
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | |
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int generic_quick_binary_strcmp(const char *a,INT32 alen, int asize,
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | const char *b,INT32 blen, int bsize)
{
if(!asize && !bsize)
{
int tmp;
if(alen > blen)
{
tmp=MEMCMP(a, b, blen);
if(tmp) return tmp;
return 1;
}else if(alen < blen){
tmp=MEMCMP(a, b, alen);
if(tmp) return tmp;
return -1;
}else{
return MEMCMP(a, b, alen);
}
}else{
INT32 pos;
for(pos=0;pos< MINIMUM(alen,blen) ;pos++)
{
INT32 ac=generic_extract(a,asize,pos);
INT32 bc=generic_extract(b,bsize,pos);
if(ac-bc) return ac-bc;
}
return alen-blen;
}
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int c_compare_string(struct pike_string *s, char *foo, int len)
|
a5787d | 1999-03-03 | Fredrik Hübinette (Hubbe) | | {
return s->len == len && s->size_shift == 0 && !MEMCMP(s->str,foo,len);
}
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | #ifndef HAVE_STRCOLL
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | int low_binary_strcmp(char *a,INT32 alen,
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | char *b,INT32 blen)
{
low_quick_binary_strcmp(a,alen,b,blen);
}
#else
static int low_binary_strcmp(char *a,INT32 alen,
char *b,INT32 blen)
{
INT32 tmp;
while(alen>0 && blen>0)
{
tmp=strcoll(a,b);
if(tmp) return (int)tmp;
tmp=strlen(a)+1;
a+=tmp;
b+=tmp;
alen-=tmp;
blen-=tmp;
}
if(alen==blen) return 0;
if(alen > blen) return 1;
return -1;
}
#endif
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | |
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int my_quick_strcmp(struct pike_string *a,struct pike_string *b)
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | {
if(a==b) return 0;
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | return generic_quick_binary_strcmp(a->str, a->len, a->size_shift,
b->str, b->len, b->size_shift);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | }
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int my_strcmp(struct pike_string *a,struct pike_string *b)
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | {
if(a==b) return 0;
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | switch(TWO_SIZES(a->size_shift,b->size_shift))
{
case TWO_SIZES(0,0):
return low_binary_strcmp(a->str,a->len,b->str,b->len);
default:
{
INT32 e,l=MINIMUM(a->len,b->len);
for(e=0;e<l;e++)
{
INT32 ac=index_shared_string(a,e);
INT32 bc=index_shared_string(b,e);
#ifdef HAVE_STRCOLL
if(ac < 256 && bc < 256)
{
char atmp[2],btmp[2];
int tmp;
atmp[0]=ac;
btmp[0]=bc;
atmp[1]=0;
btmp[1]=0;
if((tmp=strcoll(atmp,btmp)))
return tmp;
}else
#endif
if(ac-bc) return ac-bc;
}
return a->len - b->len;
}
}
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | }
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct pike_string *realloc_unlinked_string(struct pike_string *a, INT32 size)
|
8d28be | 1997-02-10 | Fredrik Hübinette (Hubbe) | | {
struct pike_string *r;
r=(struct pike_string *)realloc((char *)a,
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | sizeof(struct pike_string)+
((size+1)<<a->size_shift));
|
8d28be | 1997-02-10 | Fredrik Hübinette (Hubbe) | |
if(!r)
{
r=begin_shared_string(size);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | MEMCPY(r->str, a->str, a->len<<a->size_shift);
|
8d28be | 1997-02-10 | Fredrik Hübinette (Hubbe) | | free((char *)a);
}
r->len=size;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | low_set_index(r,size,0);
|
8d28be | 1997-02-10 | Fredrik Hübinette (Hubbe) | | return r;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct pike_string *realloc_shared_string(struct pike_string *a, INT32 size)
|
8d28be | 1997-02-10 | Fredrik Hübinette (Hubbe) | | {
struct pike_string *r;
if(a->refs==1)
{
unlink_pike_string(a);
return realloc_unlinked_string(a, size);
}else{
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | r=begin_wide_shared_string(size,a->size_shift);
MEMCPY(r->str, a->str, a->len<<a->size_shift);
|
709463 | 1997-02-24 | Fredrik Hübinette (Hubbe) | | free_string(a);
|
8d28be | 1997-02-10 | Fredrik Hübinette (Hubbe) | | return r;
}
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct pike_string *new_realloc_shared_string(struct pike_string *a, INT32 size, int shift)
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | {
struct pike_string *r;
if(shift == a->size_shift) return realloc_shared_string(a,size);
r=begin_wide_shared_string(size,shift);
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | pike_string_cpy(MKPCHARP_STR(r),a);
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | free_string(a);
return r;
}
|
0d3ea5 | 1998-01-19 | Fredrik Hübinette (Hubbe) | | |
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | *
* Phew, this function become complicated when I inserted magic for wide
* characters...
|
0d3ea5 | 1998-01-19 | Fredrik Hübinette (Hubbe) | | */
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct pike_string *modify_shared_string(struct pike_string *a,
|
0d3ea5 | 1998-01-19 | Fredrik Hübinette (Hubbe) | | INT32 index,
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | INT32 c)
|
0d3ea5 | 1998-01-19 | Fredrik Hübinette (Hubbe) | | {
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | INT32 old_value;
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
0d3ea5 | 1998-01-19 | Fredrik Hübinette (Hubbe) | | if(index<0 || index>=a->len)
fatal("Index out of range in modify_shared_string()\n");
#endif
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | old_value=index_shared_string(a,index);
if(old_value==c) return a;
if(min_magnitude(c) > a->size_shift)
{
struct pike_string *b;
switch(TWO_SIZES(min_magnitude(c),a->size_shift))
{
case TWO_SIZES(1,0):
b=begin_wide_shared_string(a->len,1);
|
01a957 | 2000-02-03 | Henrik Grubbström (Grubba) | | convert_0_to_1(STR1(b),(p_wchar0 *)a->str,a->len);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | STR1(b)[index]=c;
|
723806 | 1998-10-11 | Fredrik Hübinette (Hubbe) | | free_string(a);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | return end_shared_string(b);
case TWO_SIZES(2,0):
b=begin_wide_shared_string(a->len,2);
|
01a957 | 2000-02-03 | Henrik Grubbström (Grubba) | | convert_0_to_2(STR2(b),(p_wchar0 *)a->str,a->len);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | STR2(b)[index]=c;
|
723806 | 1998-10-11 | Fredrik Hübinette (Hubbe) | | free_string(a);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | return end_shared_string(b);
case TWO_SIZES(2,1):
b=begin_wide_shared_string(a->len,2);
convert_1_to_2(STR2(b),STR1(a),a->len);
STR2(b)[index]=c;
|
723806 | 1998-10-11 | Fredrik Hübinette (Hubbe) | | free_string(a);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | return end_shared_string(b);
default:
fatal("Odd wide string conversion!\n");
}
}
if(min_magnitude(old_value) == a->size_shift &&
min_magnitude(c) < min_magnitude(old_value))
{
struct pike_string *b;
int size,tmp;
switch(a->size_shift)
{
case 0:
fatal("Unshrinkable!\n");
case 1:
if(find_magnitude1(STR1(a),index)) break;
if(find_magnitude1(STR1(a)+index+1,a->len-index-1))
break;
b=begin_shared_string(a->len);
|
01a957 | 2000-02-03 | Henrik Grubbström (Grubba) | | convert_1_to_0((p_wchar0 *)b->str,STR1(a),a->len);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | b->str[index]=c;
free_string(a);
return end_shared_string(b);
case 2:
size=find_magnitude2(STR2(a),index);
if(size==2) break;
tmp=find_magnitude2(STR2(a)+index+1,a->len-index-1);
if(tmp==2) break;
size=MAXIMUM(MAXIMUM(size,tmp),min_magnitude(c));
switch(size)
{
case 0:
b=begin_shared_string(a->len);
|
01a957 | 2000-02-03 | Henrik Grubbström (Grubba) | | convert_2_to_0((p_wchar0 *)b->str,STR2(a),a->len);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | b->str[index]=c;
free_string(a);
return end_shared_string(b);
case 1:
b=begin_wide_shared_string(a->len,1);
|
01a957 | 2000-02-03 | Henrik Grubbström (Grubba) | | convert_2_to_1((p_wchar1 *)b->str,STR2(a),a->len);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | STR1(b)[index]=c;
free_string(a);
return end_shared_string(b);
}
}
}
|
0d3ea5 | 1998-01-19 | Fredrik Hübinette (Hubbe) | | if(a->refs==1)
{
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
|
fe3c9f | 1999-09-06 | Henrik Grubbström (Grubba) | | if((((unsigned int)index) >= HASH_PREFIX) && (index < a->len-8))
|
0d3ea5 | 1998-01-19 | Fredrik Hübinette (Hubbe) | | {
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
low_set_index(a,index,c);
|
0d3ea5 | 1998-01-19 | Fredrik Hübinette (Hubbe) | | return a;
}else{
unlink_pike_string(a);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | low_set_index(a,index,c);
|
0d3ea5 | 1998-01-19 | Fredrik Hübinette (Hubbe) | | return end_shared_string(a);
}
}else{
struct pike_string *r;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | r=begin_wide_shared_string(a->len,a->size_shift);
MEMCPY(r->str, a->str, a->len << a->size_shift);
low_set_index(r,index,c);
|
0d3ea5 | 1998-01-19 | Fredrik Hübinette (Hubbe) | | free_string(a);
return end_shared_string(r);
}
}
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct pike_string *add_shared_strings(struct pike_string *a,
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *b)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *ret;
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | PCHARP tmp;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | int target_size=MAXIMUM(a->size_shift,b->size_shift);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | ret=begin_wide_shared_string(a->len+b->len,target_size);
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | tmp=MKPCHARP_STR(ret);
pike_string_cpy(tmp,a);
INC_PCHARP(tmp,a->len);
pike_string_cpy(tmp,b);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | return end_shared_string(ret);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct pike_string *add_and_free_shared_strings(struct pike_string *a,
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | struct pike_string *b)
{
INT32 alen=a->len;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | if(a->size_shift == b->size_shift)
{
a=realloc_shared_string(a,alen + b->len);
MEMCPY(a->str+(alen<<a->size_shift),b->str,b->len<<b->size_shift);
free_string(b);
return end_shared_string(a);
}else{
struct pike_string *ret=add_shared_strings(a,b);
free_string(a);
free_string(b);
return ret;
}
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int string_search(struct pike_string *haystack,
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | struct pike_string *needle,
int start)
{
struct generic_mem_searcher s;
char *r;
if(needle->size_shift > haystack->size_shift)
return -1;
init_generic_memsearcher(&s,
needle->str,
needle->len,
needle->size_shift,
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | haystack->len-start,
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | haystack->size_shift);
r=(char *)generic_memory_search(&s,
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | haystack->str+(start<<haystack->size_shift),
haystack->len-start,
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | haystack->size_shift);
if(!r) return -1;
return (r-haystack->str)>>haystack->size_shift;
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | }
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct pike_string *string_slice(struct pike_string *s,
|
ab8572 | 2000-08-04 | Henrik Grubbström (Grubba) | | ptrdiff_t start,
ptrdiff_t len)
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | {
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | if(start < 0 || len<0 || start+len>s->len )
{
fatal("string_slice, start = %d, len = %d, s->len = %d\n",start,len,s->len);
}
#endif
if(start==0 && len==s->len)
{
add_ref(s);
return s;
}
switch(s->size_shift)
{
case 0:
|
01a957 | 2000-02-03 | Henrik Grubbström (Grubba) | | return make_shared_binary_string((char *)STR0(s)+start,len);
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | |
case 1:
return make_shared_binary_string1(STR1(s)+start,len);
case 2:
return make_shared_binary_string2(STR2(s)+start,len);
}
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | fatal("Illegal shift size!\n");
return 0;
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | }
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct pike_string *string_replace(struct pike_string *str,
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | struct pike_string *del,
struct pike_string *to)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *ret;
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | char *s,*tmp,*end;
PCHARP r;
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | int shift;
struct generic_mem_searcher searcher;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
a99145 | 1997-07-08 | Fredrik Hübinette (Hubbe) | | if(!str->len)
{
|
d6ac73 | 1998-04-20 | Henrik Grubbström (Grubba) | | add_ref(str);
|
a99145 | 1997-07-08 | Fredrik Hübinette (Hubbe) | | return str;
}
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | shift=MAXIMUM(str->size_shift,to->size_shift);
|
a99145 | 1997-07-08 | Fredrik Hübinette (Hubbe) | | if(!del->len)
{
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | int e,pos;
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | ret=begin_wide_shared_string(str->len + to->len * (str->len -1),shift);
low_set_index(ret,0,index_shared_string(str,0));
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | for(pos=e=1;e<str->len;e++)
|
a99145 | 1997-07-08 | Fredrik Hübinette (Hubbe) | | {
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | pike_string_cpy(MKPCHARP_STR_OFF(ret,pos),to);
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | pos+=to->len;
low_set_index(ret,pos++,index_shared_string(str,e));
|
a99145 | 1997-07-08 | Fredrik Hübinette (Hubbe) | | }
return end_shared_string(ret);
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | s=str->str;
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | end=s+(str->len<<str->size_shift);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
1f515a | 1997-02-15 | Fredrik Hübinette (Hubbe) | | if(del->len == to->len)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | init_generic_memsearcher(&searcher,
del->str,
del->len,
del->size_shift,
str->len,
str->size_shift);
ret=begin_wide_shared_string(str->len,shift);
|
1f515a | 1997-02-15 | Fredrik Hübinette (Hubbe) | | }else{
INT32 delimeters=0;
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | init_generic_memsearcher(&searcher,
del->str,
del->len,
del->size_shift,
str->len*2,
str->size_shift);
while((s=generic_memory_search(&searcher,
s,
(end-s)>>str->size_shift,
str->size_shift)))
|
1f515a | 1997-02-15 | Fredrik Hübinette (Hubbe) | | {
delimeters++;
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | s+=del->len << str->size_shift;
|
1f515a | 1997-02-15 | Fredrik Hübinette (Hubbe) | | }
if(!delimeters)
{
|
d6ac73 | 1998-04-20 | Henrik Grubbström (Grubba) | | add_ref(str);
|
1f515a | 1997-02-15 | Fredrik Hübinette (Hubbe) | | return str;
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | ret=begin_wide_shared_string(str->len + (to->len-del->len)*delimeters, shift);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
s=str->str;
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | r=MKPCHARP_STR(ret);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | while((tmp=(char *)generic_memory_search(&searcher,
s,
(end-s)>>str->size_shift,
str->size_shift)))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
68d913 | 1999-04-01 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
if(tmp + (del->len << str->size_shift) > end)
fatal("generic_memory_search found a match beyond end of string!!!\n");
#endif
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | generic_memcpy(r,MKPCHARP(s,str->size_shift),(tmp-s)>>str->size_shift);
INC_PCHARP(r,(tmp-s)>>str->size_shift);
pike_string_cpy(r,to);
INC_PCHARP(r,to->len);
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | s=tmp+(del->len << str->size_shift);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | generic_memcpy(r,MKPCHARP(s,str->size_shift),(end-s)>>str->size_shift);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
return end_shared_string(ret);
}
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | void init_shared_string_table(void)
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | {
|
85f59e | 1998-01-08 | Fredrik Hübinette (Hubbe) | | for(hashprimes_entry=0;hashprimes[hashprimes_entry]<BEGIN_HASH_SIZE;hashprimes_entry++);
|
75920f | 1997-12-28 | Fredrik Hübinette (Hubbe) | | htable_size=hashprimes[hashprimes_entry];
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | base_table=(struct pike_string **)xalloc(sizeof(struct pike_string *)*htable_size);
MEMSET((char *)base_table,0,sizeof(struct pike_string *)*htable_size);
}
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG_MALLOC
struct shared_string_location *all_shared_string_locations;
#endif
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | void cleanup_shared_string_table(void)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | unsigned INT32 e;
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *s,*next;
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | |
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #if defined(PIKE_DEBUG) && defined(DEBUG_MALLOC)
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | while(all_shared_string_locations)
{
struct shared_string_location *x=all_shared_string_locations;
all_shared_string_locations=x->next;
free_string(x->s);
x->s=0;
}
if(verbose_debug_exit)
{
|
3c0c28 | 1998-01-26 | Fredrik Hübinette (Hubbe) | | INT32 num,size;
count_memory_in_strings(&num,&size);
if(num)
{
fprintf(stderr,"Strings left: %d (%d bytes) (zapped)\n",num,size);
dump_stralloc_strings();
}
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | }
#endif
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | for(e=0;e<htable_size;e++)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
for(s=base_table[e];s;s=next)
{
next=s->next;
#ifdef REALLY_FREE
free((char *)s);
#else
s->next=0;
#endif
}
base_table[e]=0;
}
|
b906cf | 1996-11-27 | Fredrik Hübinette (Hubbe) | | free((char *)base_table);
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | base_table=0;
num_strings=0;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
c3c703 | 1996-12-04 | Fredrik Hübinette (Hubbe) | |
void count_memory_in_strings(INT32 *num, INT32 *size)
{
unsigned INT32 e, num_=0, size_=0;
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | if(!base_table)
{
*num=*size=0;
return;
}
|
c3c703 | 1996-12-04 | Fredrik Hübinette (Hubbe) | | size_+=htable_size * sizeof(struct pike_string *);
for(e=0;e<htable_size;e++)
{
struct pike_string *p;
for(p=base_table[e];p;p=p->next)
{
num_++;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | size_+=sizeof(struct pike_string)+(p->len<<p->size_shift);
|
c3c703 | 1996-12-04 | Fredrik Hübinette (Hubbe) | | }
}
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
c3c703 | 1996-12-04 | Fredrik Hübinette (Hubbe) | | if(num_strings != num_)
|
beac72 | 1998-04-16 | Fredrik Hübinette (Hubbe) | | fatal("Num strings is wrong! %d!=%d.\n",num_strings, num_);
|
c3c703 | 1996-12-04 | Fredrik Hübinette (Hubbe) | | #endif
num[0]=num_;
size[0]=size_;
}
|
936735 | 1997-01-27 | Fredrik Hübinette (Hubbe) | |
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | void gc_mark_all_strings(void)
|
936735 | 1997-01-27 | Fredrik Hübinette (Hubbe) | | {
unsigned INT32 e;
if(!base_table) return;
for(e=0;e<htable_size;e++)
{
struct pike_string *p;
for(p=base_table[e];p;p=p->next) gc_is_referenced(p);
}
}
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void init_string_builder(struct string_builder *s, int mag)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
s->malloced=256;
s->s=begin_wide_shared_string(256,mag);
s->s->len=0;
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | s->known_shift=0;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | }
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | static void string_build_mkspace(struct string_builder *s, int chars, int mag)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
if(mag > s->s->size_shift)
{
struct pike_string *n;
int l=s->s->len+chars+s->malloced;
n=begin_wide_shared_string(l,mag);
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | pike_string_cpy(MKPCHARP_STR(n),s->s);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | n->len=s->s->len;
s->malloced=l;
free((char *)s->s);
s->s=n;
}
else if(s->s->len+chars > s->malloced)
{
int newlen=MAXIMUM(s->malloced*2,s->s->len+chars);
s->s=(struct pike_string *)realloc((char *)s->s,
sizeof(struct pike_string)+
((newlen+1)<<s->s->size_shift));
if(!s->s)
fatal("Out of memory.\n");
s->malloced=newlen;
}
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void *string_builder_allocate(struct string_builder *s, int chars, int mag)
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | {
void *ret;
string_build_mkspace(s,chars,mag);
if(chars<0) s->known_shift=0;
ret=s->s->str + (s->s->len<<s->s->size_shift);
s->s->len+=chars;
return ret;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void string_builder_putchar(struct string_builder *s, int ch)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
INT32 i;
string_build_mkspace(s,1,min_magnitude(ch));
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | s->known_shift=MAXIMUM(min_magnitude(ch),s->known_shift);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | i=s->s->len++;
low_set_index(s->s,i,ch);
}
|
c3dbe5 | 2000-08-09 | Henrik Grubbström (Grubba) | | PMOD_EXPORT void string_builder_binary_strcat(struct string_builder *s, char *str, ptrdiff_t len)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | string_build_mkspace(s,len,0);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | switch(s->s->size_shift)
{
|
01a957 | 2000-02-03 | Henrik Grubbström (Grubba) | | case 0: convert_0_to_0(STR0(s->s)+s->s->len,(p_wchar0 *)str,len); break;
case 1: convert_0_to_1(STR1(s->s)+s->s->len,(p_wchar0 *)str,len); break;
case 2: convert_0_to_2(STR2(s->s)+s->s->len,(p_wchar0 *)str,len); break;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | default:
fatal("Illegal magnitude!\n");
}
s->s->len+=len;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void string_builder_append(struct string_builder *s,
|
c3dbe5 | 2000-08-09 | Henrik Grubbström (Grubba) | | PCHARP from,
ptrdiff_t len)
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | {
string_build_mkspace(s,len,from.shift);
generic_memcpy(MKPCHARP_STR_OFF(s->s,s->s->len), from, len);
s->s->len+=len;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void string_builder_fill(struct string_builder *s,
|
c3dbe5 | 2000-08-09 | Henrik Grubbström (Grubba) | | ptrdiff_t howmany,
PCHARP from,
ptrdiff_t len,
ptrdiff_t offset)
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | {
|
c3dbe5 | 2000-08-09 | Henrik Grubbström (Grubba) | | ptrdiff_t tmp;
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | if(len<=0)
fatal("Cannot fill with zero length strings!\n");
#endif
if(howmany<=0) return;
if(!s->s->size_shift &&
len == 1 &&
(!from.shift || !min_magnitude(EXTRACT_PCHARP(from))))
{
MEMSET(string_builder_allocate(s,howmany,0),
EXTRACT_PCHARP(from),
howmany);
return;
}
string_build_mkspace(s,howmany,from.shift);
|
c3dbe5 | 2000-08-09 | Henrik Grubbström (Grubba) | | tmp = MINIMUM(howmany, len - offset);
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | |
generic_memcpy(MKPCHARP_STR_OFF(s->s,s->s->len),
ADD_PCHARP(from,offset),
tmp);
s->s->len+=tmp;
howmany-=tmp;
if(howmany > 0)
{
void *new_from;
PCHARP to;
tmp=MINIMUM(howmany, len);
to=MKPCHARP_STR_OFF(s->s,s->s->len);
generic_memcpy(to,from, tmp);
s->s->len+=tmp;
howmany-=tmp;
while(howmany > 0)
{
|
c3dbe5 | 2000-08-09 | Henrik Grubbström (Grubba) | | tmp = MINIMUM(len, howmany);
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | MEMCPY(s->s->str + (s->s->len << s->s->size_shift),
to.ptr,
tmp << s->s->size_shift);
len+=tmp;
howmany-=tmp;
s->s->len+=tmp;
}
}
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void string_builder_strcat(struct string_builder *s, char *str)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
string_builder_binary_strcat(s,str,strlen(str));
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void string_builder_shared_strcat(struct string_builder *s, struct pike_string *str)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
|
964179 | 1999-06-30 | Fredrik Hübinette (Hubbe) | | string_build_mkspace(s,str->len,str->size_shift);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | pike_string_cpy(MKPCHARP_STR_OFF(s->s,s->s->len), str);
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | s->known_shift=MAXIMUM(s->known_shift,str->size_shift);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | s->s->len+=str->len;
}
|
723806 | 1998-10-11 | Fredrik Hübinette (Hubbe) | |
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void reset_string_builder(struct string_builder *s)
|
723806 | 1998-10-11 | Fredrik Hübinette (Hubbe) | | {
s->known_shift=0;
s->s->len=0;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void free_string_builder(struct string_builder *s)
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | {
free((char *)s->s);
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct pike_string *finish_string_builder(struct string_builder *s)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
low_set_index(s->s,s->s->len,0);
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | if(s->known_shift == s->s->size_shift)
return low_end_shared_string(s->s);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | return end_shared_string(s->s);
}
|
98f9a9 | 2000-08-08 | Henrik Grubbström (Grubba) | | PMOD_EXPORT PCHARP MEMCHR_PCHARP(PCHARP ptr, int chr, ptrdiff_t len)
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | {
switch(ptr.shift)
{
case 0: return MKPCHARP(MEMCHR0(ptr.ptr,chr,len),0);
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | case 1: return MKPCHARP(MEMCHR1((p_wchar1 *)ptr.ptr,chr,len),1);
case 2: return MKPCHARP(MEMCHR2((p_wchar2 *)ptr.ptr,chr,len),2);
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | }
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | fatal("Illegal shift in MEMCHR_PCHARP.\n");
return MKPCHARP(0,0);
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | }
|
bbee34 | 2000-03-31 | Fredrik Hübinette (Hubbe) | | #define DIGIT(x) (WIDE_ISDIGIT(x) ? (x) - '0' : \
WIDE_ISLOWER(x) ? (x) + 10 - 'a' : (x) + 10 - 'A')
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | #define MBASE ('z' - 'a' + 1 + 10)
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT long STRTOL_PCHARP(PCHARP str, PCHARP *ptr, int base)
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | {
register long val;
register int c;
int xx, neg = 0;
if (ptr) *ptr = str;
if (base < 0 || base > MBASE) return 0;
|
bbee34 | 2000-03-31 | Fredrik Hübinette (Hubbe) | | if (!WIDE_ISALNUM(c = EXTRACT_PCHARP(str)))
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | {
while (ISSPACE(c))
{
INC_PCHARP(str,1);
c=EXTRACT_PCHARP(str);
}
switch (c)
{
case '-':
neg++;
case '+':
INC_PCHARP(str,1);
c=EXTRACT_PCHARP(str);
}
}
if (!base)
{
if (c != '0')
base = 10;
else if (INDEX_PCHARP(str,1) == 'x' || INDEX_PCHARP(str,1) == 'X')
base = 16;
else
base = 8;
}
|
bbee34 | 2000-03-31 | Fredrik Hübinette (Hubbe) | | if (!WIDE_ISALNUM(c) || (xx = DIGIT(c)) >= base)
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | return 0;
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);
}
val=-DIGIT(c);
while(1)
{
INC_PCHARP(str,1);
c=EXTRACT_PCHARP(str);
|
bbee34 | 2000-03-31 | Fredrik Hübinette (Hubbe) | | if(!(WIDE_ISALNUM(c) && (xx=DIGIT(c)) < base)) break;
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | val = base * val - xx;
}
if (ptr) *ptr = str;
return (neg ? val : -val);
}
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | |
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int string_to_svalue_inumber(struct svalue *r,
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | char * str,
char **ptr,
int base,
int maxlength)
{
PCHARP tmp;
int ret=pcharp_to_svalue_inumber(r,
MKPCHARP(str,0),
&tmp,
base,
maxlength);
if(ptr) *ptr=(char *)tmp.ptr;
return ret;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int wide_string_to_svalue_inumber(struct svalue *r,
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | void * str,
void **ptr,
int base,
int maxlength,
int shift)
{
PCHARP tmp;
int ret=pcharp_to_svalue_inumber(r,
MKPCHARP(str,shift),
&tmp,
base,
maxlength);
if(ptr) *ptr=(char *)tmp.ptr;
return ret;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int pcharp_to_svalue_inumber(struct svalue *r,
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | PCHARP str,
PCHARP *ptr,
int base,
|
31ea27 | 1999-10-22 | Fredrik Noring | | int maxlength)
{
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | PCHARP str_start;
|
31ea27 | 1999-10-22 | Fredrik Noring | |
|
6ee24a | 1999-10-24 | Fredrik Noring | | INT_TYPE xx, neg = 0, is_bignum = 0, implicit_base = 0;
|
31ea27 | 1999-10-22 | Fredrik Noring | | INT_TYPE val;
INT_TYPE c;
maxlength--;
str_start = str;
r->type = T_INT;
r->subtype = NUMBER_NUMBER;
r->u.integer = 0;
if(ptr != 0)
*ptr = str;
if(base < 0 || MBASE < base)
return 0;
|
bbee34 | 2000-03-31 | Fredrik Hübinette (Hubbe) | | if(!WIDE_ISALNUM(c = EXTRACT_PCHARP(str)))
|
31ea27 | 1999-10-22 | Fredrik Noring | | {
|
bbee34 | 2000-03-31 | Fredrik Hübinette (Hubbe) | | while(WIDE_ISSPACE(c))
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | {
INC_PCHARP(str,1);
c = EXTRACT_PCHARP(str);
}
|
31ea27 | 1999-10-22 | Fredrik Noring | |
switch (c)
{
case '-':
neg++;
case '+':
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | INC_PCHARP(str,1);
c = EXTRACT_PCHARP(str);
|
31ea27 | 1999-10-22 | Fredrik Noring | | }
}
if(base == 0)
{
|
6ee24a | 1999-10-24 | Fredrik Noring | | implicit_base = 1;
|
31ea27 | 1999-10-22 | Fredrik Noring | | if(c != '0')
base = 10;
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | else if(INDEX_PCHARP(str,1) == 'x' || INDEX_PCHARP(str,1) == 'X')
|
31ea27 | 1999-10-22 | Fredrik Noring | | base = 16;
|
565645 | 1999-10-26 | Fredrik Noring | | else if(INDEX_PCHARP(str,1) == 'b' || INDEX_PCHARP(str,1) == 'B')
base = 2;
|
31ea27 | 1999-10-22 | Fredrik Noring | | else
base = 8;
}
|
bbee34 | 2000-03-31 | Fredrik Hübinette (Hubbe) | | if(!WIDE_ISALNUM(c) || (xx = DIGIT(c)) >= base)
|
31ea27 | 1999-10-22 | Fredrik Noring | | return 0;
|
565645 | 1999-10-26 | Fredrik Noring | | if(implicit_base && c == '0' &&
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | INDEX_PCHARP(str,2) < 256 &&
isxdigit(INDEX_PCHARP(str,2)) &&
|
565645 | 1999-10-26 | Fredrik Noring | | ((base==16 && (INDEX_PCHARP(str,1)=='x' || INDEX_PCHARP(str,1)=='X')) ||
(base==2 && (INDEX_PCHARP(str,1)=='b' || INDEX_PCHARP(str,1)=='B'))))
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | {
|
11e89c | 1999-10-30 | Fredrik Noring | |
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | INC_PCHARP(str,2);
c=EXTRACT_PCHARP(str);
}
|
31ea27 | 1999-10-22 | Fredrik Noring | |
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | for(val = -DIGIT(c);
|
bbee34 | 2000-03-31 | Fredrik Hübinette (Hubbe) | | (INC_PCHARP(str,1), WIDE_ISALNUM(c = EXTRACT_PCHARP(str) )) &&
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | (xx = DIGIT(c)) < base &&
0 != maxlength--; )
|
31ea27 | 1999-10-22 | Fredrik Noring | | {
#ifdef AUTO_BIGNUM
if(INT_TYPE_MUL_OVERFLOW(val, base))
is_bignum = 1;
#endif /* AUTO_BIGNUM */
|
11e89c | 1999-10-30 | Fredrik Noring | | val = base * val;
|
31ea27 | 1999-10-22 | Fredrik Noring | |
|
11e89c | 1999-10-30 | Fredrik Noring | | #ifdef AUTO_BIGNUM
if(INT_TYPE_SUB_OVERFLOW(val, xx))
is_bignum = 1;
#endif /* AUTO_BIGNUM */
val -= xx;
|
31ea27 | 1999-10-22 | Fredrik Noring | | }
if(ptr != 0)
*ptr = str;
|
11e89c | 1999-10-30 | Fredrik Noring | | if(neg)
r->u.integer = val;
else
{
#ifdef AUTO_BIGNUM
if(INT_TYPE_NEG_OVERFLOW(val))
is_bignum = 1;
#endif /* AUTO_BIGNUM */
r->u.integer = -val;
}
|
31ea27 | 1999-10-22 | Fredrik Noring | |
#ifdef AUTO_BIGNUM
|
11e89c | 1999-10-30 | Fredrik Noring | | if(is_bignum)
|
31ea27 | 1999-10-22 | Fredrik Noring | | {
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | push_string(make_shared_binary_pcharp(str_start,
SUBTRACT_PCHARP(str,str_start)));
|
6ee24a | 1999-10-24 | Fredrik Noring | | if(implicit_base)
{
convert_stack_top_to_bignum();
}
else
{
push_int(base);
convert_stack_top_with_base_to_bignum();
}
|
31ea27 | 1999-10-22 | Fredrik Noring | |
*r = *--sp;
}
#endif /* AUTO_BIGNUM */
return 1;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int convert_stack_top_string_to_inumber(int base)
|
31ea27 | 1999-10-22 | Fredrik Noring | | {
struct svalue r;
|
775f3d | 1999-10-23 | Fredrik Noring | | int i;
|
31ea27 | 1999-10-22 | Fredrik Noring | |
if(sp[-1].type != T_STRING)
error("Cannot convert stack top to integer number.\n");
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | i=pcharp_to_svalue_inumber(&r, MKPCHARP_STR(sp[-1].u.string), 0, base, 0);
|
31ea27 | 1999-10-22 | Fredrik Noring | |
free_string(sp[-1].u.string);
sp[-1] = r;
|
775f3d | 1999-10-23 | Fredrik Noring | |
return i;
|
31ea27 | 1999-10-22 | Fredrik Noring | | }
|
f3ece8 | 1999-02-28 | Fredrik Hübinette (Hubbe) | |
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT double STRTOD_PCHARP(PCHARP nptr, PCHARP *endptr)
|
f3ece8 | 1999-02-28 | Fredrik Hübinette (Hubbe) | | {
register PCHARP s;
short int sign;
double num;
int got_dot;
int got_digit;
long int exponent;
if (nptr.ptr == NULL)
{
errno = EINVAL;
goto noconv;
}
s = nptr;
|
bbee34 | 2000-03-31 | Fredrik Hübinette (Hubbe) | | while (EXTRACT_PCHARP(s) <256 && WIDE_ISSPACE(EXTRACT_PCHARP(s))) INC_PCHARP(s,1);
|
f3ece8 | 1999-02-28 | Fredrik Hübinette (Hubbe) | |
sign = EXTRACT_PCHARP(s) == '-' ? -1 : 1;
if (EXTRACT_PCHARP(s) == '-' || EXTRACT_PCHARP(s) == '+')
INC_PCHARP(s,1);
num = 0.0;
got_dot = 0;
got_digit = 0;
exponent = 0;
for (;; INC_PCHARP(s,1))
{
|
bbee34 | 2000-03-31 | Fredrik Hübinette (Hubbe) | | if (EXTRACT_PCHARP(s)<256 && WIDE_ISDIGIT (EXTRACT_PCHARP(s)))
|
f3ece8 | 1999-02-28 | Fredrik Hübinette (Hubbe) | | {
got_digit = 1;
if (num > DBL_MAX * 0.1)
++exponent;
else
num = (num * 10.0) + (EXTRACT_PCHARP(s) - '0');
if (got_dot)
--exponent;
}
else if (!got_dot && (char) EXTRACT_PCHARP(s) == '.')
got_dot = 1;
else
break;
}
if (!got_digit)
goto noconv;
if (EXTRACT_PCHARP(s) <256 && tolower(EXTRACT_PCHARP(s)) == 'e')
{
int save = errno;
PCHARP end;
long int exp;
errno = 0;
INC_PCHARP(s,1);
exp = STRTOL_PCHARP(s, &end, 10);
if (errno == ERANGE)
{
if (endptr != NULL)
*endptr = end;
if (exp < 0)
goto underflow;
else
goto overflow;
}
else if (COMPARE_PCHARP(end,==,s))
end = ADD_PCHARP(s,-1);
errno = save;
s = end;
exponent += exp;
}
if(got_dot && INDEX_PCHARP(s,-1)=='.') INC_PCHARP(s,-1);
if (endptr != NULL)
*endptr = s;
if (num == 0.0)
return 0.0;
if (exponent < 0)
{
if (num < DBL_MIN * pow(10.0, (double) -exponent))
goto underflow;
}
else if (exponent > 0)
{
if (num > DBL_MAX * pow(10.0, (double) -exponent))
goto overflow;
}
|
bbee34 | 2000-03-31 | Fredrik Hübinette (Hubbe) | | if(exponent < 0 && exponent >-100)
num /= pow(10.0, (double) -exponent);
else
num *= pow(10.0, (double) exponent);
|
f3ece8 | 1999-02-28 | Fredrik Hübinette (Hubbe) | |
return num * sign;
overflow:
errno = ERANGE;
return HUGE * sign;
underflow:
if (endptr != NULL)
*endptr = nptr;
errno = ERANGE;
return 0.0;
noconv:
if (endptr != NULL)
*endptr = nptr;
return 0.0;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT p_wchar0 *require_wstring0(struct pike_string *s,
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | char **to_free)
{
switch(s->size_shift)
{
case 0:
*to_free=0;
return STR0(s);
case 1:
case 2:
return 0;
default:
fatal("Illegal shift size in string.\n");
}
return 0;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT p_wchar1 *require_wstring1(struct pike_string *s,
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | char **to_free)
{
switch(s->size_shift)
{
case 0:
*to_free=xalloc((s->len+1)*2);
convert_0_to_1((p_wchar1 *)*to_free, STR0(s),s->len+1);
return (p_wchar1 *)*to_free;
case 1:
*to_free=0;
return STR1(s);
case 2:
return 0;
default:
fatal("Illegal shift size in string.\n");
}
return 0;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT p_wchar2 *require_wstring2(struct pike_string *s,
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | char **to_free)
{
switch(s->size_shift)
{
case 0:
*to_free=xalloc((s->len+1)*4);
convert_0_to_2((p_wchar2 *)*to_free, STR0(s),s->len+1);
return (p_wchar2 *)*to_free;
case 1:
*to_free=xalloc((s->len+1)*4);
convert_1_to_2((p_wchar2 *)*to_free, STR1(s),s->len+1);
return (p_wchar2 *)*to_free;
case 2:
*to_free=0;
return STR2(s);
default:
fatal("Illegal shift size in string.\n");
}
return 0;
}
|