e576bb | 2002-10-11 | Martin Nilsson | |
|
aedfb1 | 2002-10-09 | Martin Nilsson | |
|
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"
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | #include "pike_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"
|
6f3ad0 | 2001-07-02 | Martin Stjernholm | | #include "operators.h"
|
686ef2 | 2004-11-11 | Henrik Grubbström (Grubba) | | #include "pike_float.h"
|
d47659 | 2013-06-12 | Arne Goedeke | | #include "block_allocator.h"
|
1d15d4 | 2004-11-11 | Henrik Grubbström (Grubba) | | #include "port.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) | |
|
e85df8 | 2001-09-06 | Fredrik Hübinette (Hubbe) | | #define SET_HSIZE(X) htable_mask=(htable_size=(1<<(X)))-1
#define HMODULO(X) ((X) & (htable_mask))
|
dbce71 | 2011-05-15 | Per Hedbor | | static unsigned INT32 htable_mask;
|
e85df8 | 2001-09-06 | Fredrik Hübinette (Hubbe) | |
|
a54964 | 2003-03-17 | Henrik Grubbström (Grubba) | | #if (SIZEOF_LONG == 4) && defined(_LP64)
#undef LONG_MIN
#undef LONG_MAX
#undef ULONG_MAX
#define LONG_MIN INT_MIN
#define LONG_MAX INT_MAX
#define ULONG_MAX UINT_MAX
#endif
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | |
#if PIKE_RUN_UNLOCKED
|
3ac5e8 | 2001-03-30 | Fredrik Hübinette (Hubbe) | |
#define BUCKET_LOCKS 2048
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | static PIKE_MUTEX_T *bucket_locks;
|
3ac5e8 | 2001-03-30 | Fredrik Hübinette (Hubbe) | | #define BUCKETLOCK(HVAL) \
|
e85df8 | 2001-09-06 | Fredrik Hübinette (Hubbe) | | (bucket_locks + (HMODULO(hval__) & (BUCKET_LOCKS-1)))
|
3ac5e8 | 2001-03-30 | Fredrik Hübinette (Hubbe) | |
#define LOCK_BUCKET(HVAL) do { \
size_t hval__=(HVAL); \
PIKE_MUTEX_T *bucket_lock; \
while(1) \
{ \
bucket_lock=BUCKETLOCK(hval__); \
mt_lock(bucket_lock); \
if(bucket_lock == BUCKETLOCK(hval__)) \
break; \
mt_unlock(bucket_lock); \
} \
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | }while(0)
#define UNLOCK_BUCKET(HVAL) do { \
size_t hval__=(HVAL); \
|
3ac5e8 | 2001-03-30 | Fredrik Hübinette (Hubbe) | | mt_unlock(BUCKETLOCK(hval__)); \
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | }while(0)
#else
#define LOCK_BUCKET(HVAL)
#define UNLOCK_BUCKET(HVAL)
|
a20d82 | 2013-06-08 | Martin Nilsson | | #endif /* PIKE_RUN_UNLOCKED */
|
24ddc7 | 1998-03-28 | Henrik Grubbström (Grubba) | |
|
ed2bed | 2013-06-14 | Per Hedbor | | #define BEGIN_HASH_SIZE 1024
|
2cbf7c | 1999-09-01 | Fredrik Hübinette (Hubbe) | |
|
8282ca | 2013-11-02 | Per Hedbor | | static unsigned int hash_prefix_len=64;
|
6ed3d2 | 2005-01-17 | Henrik Grubbström (Grubba) | | static unsigned int need_more_hash_prefix_depth=0;
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
|
abce51 | 2013-11-06 | Arne Goedeke | | static unsigned int need_new_hashkey_depth=0;
|
e9d7c5 | 2013-11-02 | Per Hedbor | | static size_t hashkey = 0;
|
0169c6 | 2011-12-30 | Henrik Grubbström (Grubba) | |
|
bcafc3 | 2004-09-19 | Martin Nilsson | | static 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;
|
bcafc3 | 2004-09-19 | Martin Nilsson | | static unsigned INT32 num_strings=0;
|
4edb1a | 2002-09-11 | David Hedbor | | PMOD_EXPORT struct pike_string *empty_pike_string = 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)
|
8282ca | 2013-11-02 | Per Hedbor | | #define low_do_hash(STR,LEN,SHIFT) low_hashmem( (STR), (LEN)<<(SHIFT), hash_prefix_len<<(SHIFT), hashkey )
|
34ffc0 | 2011-05-15 | Per Hedbor | | #define do_hash(STR) low_do_hash(STR->str,STR->len,STR->size_shift)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
|
992551 | 2013-05-31 | Per Hedbor | |
PMOD_EXPORT int string_range_contains( struct pike_string *str, int n )
{
INT32 min, max;
check_string_range( str, 1, &min, &max );
if( n >= min && n <= max )
return 1;
return 0;
}
PMOD_EXPORT int string_range_contains_string( struct pike_string *str1,
struct pike_string *str2 )
{
INT32 max1, min1;
INT32 max2, min2;
|
c037bf | 2013-06-11 | Martin Nilsson | | if( !str2->len ) return 1;
|
992551 | 2013-05-31 | Per Hedbor | | check_string_range( str1, 1, &min1, &max1 );
check_string_range( str2, 1, &min2, &max2 );
if( (min2 < min1) || (max2 > max1) )
{
if( (str1->flags & STRING_CONTENT_CHECKED) ==
(str2->flags & STRING_CONTENT_CHECKED) )
return 0;
return str1->size_shift >= str2->size_shift;
}
return 1;
}
PMOD_EXPORT void check_string_range( struct pike_string *str,
int loose,
INT32 *min, INT32 *max )
{
INT32 s_min = MAX_INT32;
INT32 s_max = MIN_INT32;
|
37647e | 2013-11-03 | Tobias S. Josefowitz | | ptrdiff_t i;
|
992551 | 2013-05-31 | Per Hedbor | |
if( loose || ((str->flags & STRING_CONTENT_CHECKED ) && (!str->size_shift || !max)) )
{
if( str->flags & STRING_CONTENT_CHECKED )
{
s_min = str->min;
s_max = str->max;
if( str->size_shift )
{
s_min <<= 8 * str->size_shift;
s_max <<= 8 * str->size_shift;
if( s_min )
s_min -= (1<<(8*str->size_shift))-1;
s_max += str->size_shift == 1 ? 255 : 65535;
}
}
else
{
switch( str->size_shift )
{
case 2: s_min = MIN_INT32; s_max=MAX_INT32; break;
case 1: s_min = 0; s_max = 65535; break;
case 0: s_min = 0; s_max = 255; break;
}
}
}
else
{
str->flags |= STRING_CONTENT_CHECKED;
switch( str->size_shift )
{
case 0:
{
p_wchar0 *p = (p_wchar0*)str->str;
int upper = 0, lower = 0;
for( i=0; i<str->len; i++,p++ )
{
if( *p >= 'A' && *p <= 'Z') upper++;
if( *p >= 'a' && *p <= 'z') lower++;
if( *p > s_max ) s_max = *p;
if( *p < s_min ) s_min = *p;
}
if( s_max < 128 )
{
|
3a059b | 2013-06-09 | Chris Angelico | | if( !lower )
|
992551 | 2013-05-31 | Per Hedbor | | str->flags |= STRING_IS_UPPERCASE;
|
3a059b | 2013-06-09 | Chris Angelico | | if( !upper )
|
992551 | 2013-05-31 | Per Hedbor | | str->flags |= STRING_IS_LOWERCASE;
}
}
str->min = s_min;
str->max = s_max;
break;
case 1:
{
p_wchar1 *p = (p_wchar1*)str->str;
for( i=0; i<str->len; i++,p++ )
{
if( *p > s_max ) s_max = *p;
if( *p < s_min ) s_min = *p;
}
}
str->min = (s_min+255) >> 8;
str->max = (s_max+255) >> 8;
break;
case 2:
{
p_wchar2 *p = (p_wchar2*)str->str;
for( i=0; i<str->len; i++,p++ )
{
if( *p > s_max ) s_max = *p;
if( *p < s_min ) s_min = *p;
}
}
str->min = (s_min+65535) >> 16;
str->max = (s_max+65535) >> 16;
break;
}
}
if( min ) *min = s_min;
if( max ) *max = s_max;
}
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
|
2eaf02 | 2008-06-29 | Marcus Comstedt | | static INLINE int find_magnitude1(const p_wchar1 *s, ptrdiff_t len)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
|
4e808c | 2011-05-01 | Per Hedbor | | const p_wchar1 *e=s+len;
while(s<e)
if(*s++>=256)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | return 1;
return 0;
}
|
2eaf02 | 2008-06-29 | Marcus Comstedt | | static INLINE int find_magnitude2(const p_wchar2 *s, ptrdiff_t len)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
|
4e808c | 2011-05-01 | Per Hedbor | | const p_wchar2 *e=s+len;
while(s<e)
|
34ffc0 | 2011-05-15 | Per Hedbor | | {
|
a8a46f | 2011-05-10 | Per Hedbor | | if((unsigned INT32)*s>=256)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
do
{
|
4e808c | 2011-05-01 | Per Hedbor | | if((unsigned INT32)*s++>=65536)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | return 2;
|
4e808c | 2011-05-01 | Per Hedbor | | }while(s<e);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | return 1;
}
|
a8a46f | 2011-05-10 | Per Hedbor | | s++;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | }
return 0;
}
|
a9b817 | 2014-04-05 | Martin Nilsson | | static INLINE int min_magnitude(const p_wchar2 c)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
|
2eaf02 | 2008-06-29 | Marcus Comstedt | | if(c<0) return 2;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | if(c<256) return 0;
if(c<65536) return 1;
return 2;
}
|
5de269 | 2012-05-28 | Martin Stjernholm | | 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
|
b99d88 | 2003-05-15 | Martin Stjernholm | | if(pos > s->len || pos<0) {
if (s->len) {
Pike_fatal("String index %"PRINTPTRDIFFT"d is out of "
"range 0..%"PRINTPTRDIFFT"d.\n",
pos, s->len-1);
} else {
Pike_fatal("Attempt to index the empty string with %"PRINTPTRDIFFT"d.\n",
pos);
}
}
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | if(pos == s->len && value)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("string zero termination foul!\n");
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | #endif
|
9cd037 | 2005-11-03 | Henrik Grubbström (Grubba) | | s->flags |= STRING_NOT_HASHED;
|
ed2bed | 2013-06-14 | Per Hedbor | |
if(!s->size_shift)
STR0(s)[pos]=value;
else if(s->size_shift == 1)
STR1(s)[pos]=value;
else
STR2(s)[pos]=value;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | }
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
d7d61d | 2004-03-19 | Henrik Grubbström (Grubba) | | PMOD_EXPORT 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)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Wrong STRX macro used!\n");
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | return a;
}
#endif
|
024adc | 2004-11-14 | Martin Stjernholm | | #define CONVERT(FROM,TO) \
void PIKE_CONCAT4(convert_,FROM,_to_,TO) (PIKE_CONCAT(p_wchar,TO) *to, \
const PIKE_CONCAT(p_wchar,FROM) *from, \
ptrdiff_t len) \
{ \
|
09d063 | 2008-07-16 | Martin Stjernholm | | while(--len>=0) *(to++)= (PIKE_CONCAT (p_wchar, TO)) *(from++); \
|
024adc | 2004-11-14 | Martin Stjernholm | | } \
INT32 PIKE_CONCAT4(compare_,FROM,_to_,TO) (const PIKE_CONCAT(p_wchar,TO) *to, \
const PIKE_CONCAT(p_wchar,FROM) *from, \
ptrdiff_t len) \
{ \
int tmp; \
while(--len>=0) \
if((tmp=*(to++)-*(from++))) \
return tmp; \
return 0; \
}
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | |
CONVERT(0,1)
CONVERT(0,2)
CONVERT(1,0)
CONVERT(1,2)
CONVERT(2,0)
CONVERT(2,1)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | #define TWO_SIZES(X,Y) (((X)<<2)+(Y))
|
66d928 | 2011-05-01 | Per Hedbor | | void generic_memcpy(PCHARP to,
|
a9b817 | 2014-04-05 | Martin Nilsson | | const PCHARP from,
|
66d928 | 2011-05-01 | Per Hedbor | | ptrdiff_t len)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
|
68d913 | 1999-04-01 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
if(len<0)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Cannot copy %ld bytes!\n",
|
a7979d | 2000-08-11 | Henrik Grubbström (Grubba) | | DO_NOT_WARN((long)len));
|
68d913 | 1999-04-01 | Fredrik Hübinette (Hubbe) | | #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;
}
}
|
a9b817 | 2014-04-05 | Martin Nilsson | | PMOD_EXPORT void pike_string_cpy(PCHARP to, const 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
|
a9b817 | 2014-04-05 | Martin Nilsson | | PMOD_EXPORT p_wchar2 index_shared_string(const struct pike_string *s,
|
e9117b | 2014-02-25 | Per Hedbor | | ptrdiff_t pos)
{
if(pos > s->len || pos<0) {
if (s->len) {
Pike_fatal("String index %"PRINTPTRDIFFT"d is out of "
"range 0..%"PRINTPTRDIFFT"d.\n",
pos, s->len-1);
} else {
Pike_fatal("Attempt to index the empty string with %"PRINTPTRDIFFT"d.\n",
pos);
}
}
return generic_extract(s->str,s->size_shift,pos);
}
PMOD_EXPORT p_wchar2 generic_extract (const void *str, int size, ptrdiff_t pos)
{
switch(size)
{
case 0: return ((p_wchar0 *)str)[pos];
case 1: return ((p_wchar1 *)str)[pos];
case 2: return ((p_wchar2 *)str)[pos];
}
Pike_fatal("Unsupported string shift: %d\n", size);
return 0;
}
|
abe3a8 | 2014-05-06 | Arne Goedeke | | static void locate_problem(int (*isproblem)(const struct pike_string *))
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | {
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) | | {
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | LOCK_BUCKET(e);
|
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));
}
}
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | UNLOCK_BUCKET(e);
|
9e5238 | 1998-03-01 | Fredrik Hübinette (Hubbe) | | }
|
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) | | }
|
a9b817 | 2014-04-05 | Martin Nilsson | | static int bad_pointer(const struct pike_string *s)
|
4bdf5f | 2001-03-30 | Henrik Grubbström (Grubba) | | {
|
cfc984 | 2001-03-30 | Henrik Grubbström (Grubba) | | return (((ptrdiff_t)s)&(sizeof(struct pike_string *)-1));
|
4bdf5f | 2001-03-30 | Henrik Grubbström (Grubba) | | }
|
a9b817 | 2014-04-05 | Martin Nilsson | | static int has_zero_refs(const struct pike_string *s)
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | {
return s->refs<=0;
}
|
a9b817 | 2014-04-05 | Martin Nilsson | | static int wrong_hash(const struct pike_string *s)
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | {
|
8bcb3b | 2001-03-28 | Fredrik Hübinette (Hubbe) | | return s->hval != do_hash(s);
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | }
|
a9b817 | 2014-04-05 | Martin Nilsson | | static int improper_zero_termination(const struct pike_string *s)
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | {
|
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)
|
a20d82 | 2013-06-08 | Martin Nilsson | | #endif /* PIKE_DEBUG */
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
fe3c9f | 1999-09-06 | Henrik Grubbström (Grubba) | |
|
ed2bed | 2013-06-14 | Per Hedbor | | static struct pike_string *internal_findstring(const char *s,
|
a9b817 | 2014-04-05 | Martin Nilsson | | ptrdiff_t len,
int size_shift,
size_t hval)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
ed2bed | 2013-06-14 | Per Hedbor | | struct pike_string *curr;
|
2cbf7c | 1999-09-01 | Fredrik Hübinette (Hubbe) | | unsigned int depth=0;
|
0169c6 | 2011-12-30 | Henrik Grubbström (Grubba) | | unsigned int prefix_depth=0;
|
8282ca | 2013-11-02 | Per Hedbor | |
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | size_t h;
LOCK_BUCKET(hval);
|
e85df8 | 2001-09-06 | Fredrik Hübinette (Hubbe) | | h=HMODULO(hval);
|
ed2bed | 2013-06-14 | Per Hedbor | | for(curr = base_table[h]; curr; curr = curr->next)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
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);
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_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) | |
|
ed2bed | 2013-06-14 | Per Hedbor | | if ( len == curr->len &&
size_shift == curr->size_shift &&
hval == curr->hval &&
( curr->str == s ||
!MEMCMP(curr->str, s,len<<size_shift)))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
ed2bed | 2013-06-14 | Per Hedbor | |
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | UNLOCK_BUCKET(hval);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return curr;
}
|
0169c6 | 2011-12-30 | Henrik Grubbström (Grubba) | | depth++;
|
8282ca | 2013-11-02 | Per Hedbor | | if (curr->len > (ptrdiff_t)hash_prefix_len)
|
0169c6 | 2011-12-30 | Henrik Grubbström (Grubba) | | prefix_depth++;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
0169c6 | 2011-12-30 | Henrik Grubbström (Grubba) | | if (depth > need_new_hashkey_depth) {
need_new_hashkey_depth = depth;
}
|
2cbf7c | 1999-09-01 | Fredrik Hübinette (Hubbe) | |
|
0169c6 | 2011-12-30 | Henrik Grubbström (Grubba) | | if (prefix_depth > need_more_hash_prefix_depth)
|
2cbf7c | 1999-09-01 | Fredrik Hübinette (Hubbe) | | {
|
6ed3d2 | 2005-01-17 | Henrik Grubbström (Grubba) | | #if 0
fprintf(stderr,
|
0169c6 | 2011-12-30 | Henrik Grubbström (Grubba) | | "prefix_depth=%d num_strings=%d need_more_hash_prefix_depth=%d\n"
|
8282ca | 2013-11-02 | Per Hedbor | | " hash_prefix_len=%d\n",
|
0169c6 | 2011-12-30 | Henrik Grubbström (Grubba) | | prefix_depth, num_strings, need_more_hash_prefix_depth,
|
8282ca | 2013-11-02 | Per Hedbor | | hash_prefix_len);
|
6ed3d2 | 2005-01-17 | Henrik Grubbström (Grubba) | | #endif /* 0 */
|
0169c6 | 2011-12-30 | Henrik Grubbström (Grubba) | | need_more_hash_prefix_depth = prefix_depth;
|
2cbf7c | 1999-09-01 | Fredrik Hübinette (Hubbe) | | }
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | UNLOCK_BUCKET(hval);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return 0;
}
|
5de269 | 2012-05-28 | Martin Stjernholm | | struct pike_string *binary_findstring(const char *foo, ptrdiff_t 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) | | }
|
eb3d13 | 2014-05-10 | Per Hedbor | | struct pike_string *binary_findstring_pcharp(PCHARP foo, ptrdiff_t l)
|
dd4aeb | 2014-05-05 | Per Hedbor | | {
|
eb3d13 | 2014-05-10 | Per Hedbor | | int in = foo.shift;
void *tmp = NULL;
struct pike_string *res;
|
4cc405 | 2014-05-10 | Per Hedbor | | if( !foo.shift )
return binary_findstring( (void*)foo.ptr, l );
|
eb3d13 | 2014-05-10 | Per Hedbor | |
|
4cc405 | 2014-05-10 | Per Hedbor | | if( UNLIKELY(foo.shift == 2) )
|
eb3d13 | 2014-05-10 | Per Hedbor | | foo.shift=find_magnitude2( (void*)foo.ptr, l );
else if( foo.shift == 1 )
foo.shift=find_magnitude1( (void*)foo.ptr, l );
|
4cc405 | 2014-05-10 | Per Hedbor | | if( UNLIKELY(foo.shift != in) )
|
eb3d13 | 2014-05-10 | Per Hedbor | | {
tmp = malloc( l * (1<<foo.shift) );
switch(in)
{
case 1:
convert_1_to_0( tmp, (void*)foo.ptr, l );
break;
case 2:
if( foo.shift == 1 )
convert_2_to_1( tmp, (void*)foo.ptr, l );
else
convert_2_to_0( tmp, (void*)foo.ptr, l );
}
foo.ptr = tmp;
}
|
4cc405 | 2014-05-10 | Per Hedbor | | res=internal_findstring((void*)foo.ptr, l, foo.shift,
|
eb3d13 | 2014-05-10 | Per Hedbor | | low_do_hash(foo.ptr,l,foo.shift));
if( tmp )
free( tmp );
return res;
|
dd4aeb | 2014-05-05 | Per Hedbor | | }
|
5de269 | 2012-05-28 | Martin Stjernholm | | 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,
|
89fc4c | 2000-08-10 | Henrik Grubbström (Grubba) | | ptrdiff_t 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);
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_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) | | {
|
1bfe77 | 2005-01-14 | Henrik Grubbström (Grubba) | | struct pike_string *prev = NULL;
struct pike_string *next;
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | if(!s) return;
|
1bfe77 | 2005-01-14 | Henrik Grubbström (Grubba) | |
while ((next = s->next)) {
s->next = prev;
prev = s;
s = next;
}
s->next = prev;
do {
ptrdiff_t h = HMODULO(s->hval);
next = s->next;
s->next = base_table[h];
base_table[h] = s;
} while ((s = next));
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | }
|
aef30b | 1996-10-11 | Fredrik Hübinette (Hubbe) | |
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | static void stralloc_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) | |
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | old=htable_size;
old_base=base_table;
|
3ac5e8 | 2001-03-30 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_RUN_UNLOCKED
mt_lock(bucket_locks);
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | if(old != htable_size)
{
|
3ac5e8 | 2001-03-30 | Fredrik Hübinette (Hubbe) | | mt_lock(bucket_locks);
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | return;
}
|
3ac5e8 | 2001-03-30 | Fredrik Hübinette (Hubbe) | | for(h=1;h<BUCKET_LOCKS;h++) mt_lock(bucket_locks+h);
#endif
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
|
e85df8 | 2001-09-06 | Fredrik Hübinette (Hubbe) | | SET_HSIZE( ++hashprimes_entry );
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | |
|
9c14f3 | 2014-04-27 | Martin Nilsson | | base_table=xcalloc(sizeof(struct pike_string *), htable_size);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
|
6ed3d2 | 2005-01-17 | Henrik Grubbström (Grubba) | | need_more_hash_prefix_depth = 0;
|
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)
|
0ec752 | 2014-04-27 | Martin Nilsson | | free(old_base);
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | |
#ifdef PIKE_RUN_UNLOCKED
|
3ac5e8 | 2001-03-30 | Fredrik Hübinette (Hubbe) | | for(h=0;h<BUCKET_LOCKS;h++) mt_unlock(bucket_locks + h);
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | #endif
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
|
b0289e | 2000-12-01 | Henrik Grubbström (Grubba) | |
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
|
3c0860 | 2008-05-02 | Martin Stjernholm | |
struct pike_string_hdr {
PIKE_STRING_CONTENTS;
};
|
b0289e | 2000-12-01 | Henrik Grubbström (Grubba) | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | #define SHORT_STRING_BLOCK 256
|
ed2bed | 2013-06-14 | Per Hedbor | |
#define SHORT_STRING_THRESHOLD 15
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | |
struct short_pike_string0 {
|
f59922 | 2001-07-03 | Fredrik Hübinette (Hubbe) | | PIKE_STRING_CONTENTS;
|
16b314 | 2001-08-15 | Fredrik Hübinette (Hubbe) | | p_wchar0 str[SHORT_STRING_THRESHOLD+1];
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | };
|
ed2bed | 2013-06-14 | Per Hedbor | | static struct block_allocator string_allocator = BA_INIT(sizeof(struct short_pike_string0), SHORT_STRING_BLOCK);
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | |
|
fb2294 | 2008-06-16 | Martin Stjernholm | | #define free_unlinked_pike_string(s) do { \
|
ed2bed | 2013-06-14 | Per Hedbor | | if (s->flags & STRING_IS_SHORT) { \
ba_free(&string_allocator, s); \
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | } else { \
|
0ec752 | 2014-04-27 | Martin Nilsson | | debug_free(s, DMALLOC_LOCATION(), 1); \
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | } \
} while(0)
|
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
|
ed2bed | 2013-06-14 | Per Hedbor | | if (len <= SHORT_STRING_THRESHOLD)
{
|
dc8d02 | 2014-04-27 | Martin Nilsson | | t=ba_alloc(&string_allocator);
|
d47659 | 2013-06-12 | Arne Goedeke | | t->flags = STRING_NOT_HASHED | STRING_NOT_SHARED | STRING_IS_SHORT;
|
ed2bed | 2013-06-14 | Per Hedbor | | } else
{
|
dc8d02 | 2014-04-27 | Martin Nilsson | | t=xalloc(len + 1 + sizeof(struct pike_string_hdr));
|
9cd037 | 2005-11-03 | Henrik Grubbström (Grubba) | | t->flags = STRING_NOT_HASHED | STRING_NOT_SHARED;
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | }
|
938632 | 2011-07-21 | Henrik Grubbström (Grubba) | | #ifdef ATOMIC_SVALUE
t->ref_type = T_STRING;
#endif
|
d229e3 | 2008-11-05 | Henrik Grubbström (Grubba) | | t->refs = 0;
add_ref(t);
|
ca74dd | 1996-10-08 | Fredrik Hübinette (Hubbe) | | t->str[len]=0;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | t->len=len;
|
992551 | 2013-05-31 | Per Hedbor | |
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | t->size_shift=0;
|
0e602a | 2006-01-12 | Henrik Grubbström (Grubba) | | DO_IF_DEBUG(t->next = NULL);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return t;
}
|
8bcb3b | 2001-03-28 | Fredrik Hübinette (Hubbe) | | static void link_pike_string(struct pike_string *s, size_t hval)
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | {
|
8bcb3b | 2001-03-28 | Fredrik Hübinette (Hubbe) | | size_t h;
|
9cd037 | 2005-11-03 | Henrik Grubbström (Grubba) | |
#ifdef PIKE_DEBUG
if (!(s->flags & STRING_NOT_SHARED)) {
debug_dump_pike_string(s, 70);
Pike_fatal("String already linked.\n");
}
|
fc6ea0 | 2008-07-18 | Martin Stjernholm | |
if (PIKE_MEM_NOT_DEF_RANGE (s->str, (s->len + 1) << s->size_shift))
Pike_fatal ("Got undefined contents in pike string %p.\n", s);
|
9cd037 | 2005-11-03 | Henrik Grubbström (Grubba) | | #endif
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | LOCK_BUCKET(hval);
|
e85df8 | 2001-09-06 | Fredrik Hübinette (Hubbe) | | h=HMODULO(hval);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | s->next = base_table[h];
base_table[h] = s;
|
8bcb3b | 2001-03-28 | Fredrik Hübinette (Hubbe) | | s->hval=hval;
|
9cd037 | 2005-11-03 | Henrik Grubbström (Grubba) | | s->flags &= ~(STRING_NOT_HASHED|STRING_NOT_SHARED);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | num_strings++;
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | UNLOCK_BUCKET(hval);
|
ed2bed | 2013-06-14 | Per Hedbor | | if(num_strings > htable_size) {
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | stralloc_rehash();
|
0169c6 | 2011-12-30 | Henrik Grubbström (Grubba) | | }
|
2cbf7c | 1999-09-01 | Fredrik Hübinette (Hubbe) | |
|
6ed3d2 | 2005-01-17 | Henrik Grubbström (Grubba) | |
|
ed2bed | 2013-06-14 | Per Hedbor | | if((need_more_hash_prefix_depth > 4) ||
(need_new_hashkey_depth > 128))
|
2cbf7c | 1999-09-01 | Fredrik Hübinette (Hubbe) | | {
|
6ed3d2 | 2005-01-17 | Henrik Grubbström (Grubba) | | |
8282ca | 2013-11-02 | Per Hedbor | | * Increase hash_prefix_len if there's some bucket containing
|
ed2bed | 2013-06-14 | Per Hedbor | | * more than 4 strings that are longer
|
8282ca | 2013-11-02 | Per Hedbor | | * than hash_prefix_len.
|
6ed3d2 | 2005-01-17 | Henrik Grubbström (Grubba) | | * /grubba
|
0169c6 | 2011-12-30 | Henrik Grubbström (Grubba) | | *
* Changed heuristic 2011-12-30:
*
* Generate a new hash key if there's some bucket containing
|
ed2bed | 2013-06-14 | Per Hedbor | | * more than 16 strings. This ought to
|
0169c6 | 2011-12-30 | Henrik Grubbström (Grubba) | | * suffice to alleviate the #hashdos vulnerability.
*
* /grubba
|
6ed3d2 | 2005-01-17 | Henrik Grubbström (Grubba) | | */
|
2cbf7c | 1999-09-01 | Fredrik Hübinette (Hubbe) | | */
|
8bcb3b | 2001-03-28 | Fredrik Hübinette (Hubbe) | |
|
abce51 | 2013-11-06 | Arne Goedeke | | if (need_new_hashkey_depth > 128) {
hashkey ^= (hashkey << 5) ^ (current_time.tv_sec ^ current_time.tv_usec);
need_new_hashkey_depth = 0;
}
|
3ac5e8 | 2001-03-30 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_RUN_UNLOCKED
mt_lock(bucket_locks);
|
ed2bed | 2013-06-14 | Per Hedbor | | if(need_more_hash_prefix_depth <= 4)
|
3ac5e8 | 2001-03-30 | Fredrik Hübinette (Hubbe) | | {
mt_lock(bucket_locks);
return;
}
for(h=1;h<BUCKET_LOCKS;h++) mt_lock(bucket_locks+h);
#endif
|
8282ca | 2013-11-02 | Per Hedbor | | if (need_more_hash_prefix_depth > 4)
{
hash_prefix_len=hash_prefix_len*2;
|
0169c6 | 2011-12-30 | Henrik Grubbström (Grubba) | | #if 0
|
8282ca | 2013-11-02 | Per Hedbor | | fprintf(stderr, "Doubling hash_prefix_len to %d and rehashing\n",
hash_prefix_len);
|
0169c6 | 2011-12-30 | Henrik Grubbström (Grubba) | | #endif /* 0 */
}
|
6ed3d2 | 2005-01-17 | Henrik Grubbström (Grubba) | | * be done on demand.
*/
need_more_hash_prefix_depth=0;
|
2cbf7c | 1999-09-01 | Fredrik Hübinette (Hubbe) | |
for(h=0;h<htable_size;h++)
{
struct pike_string *tmp=base_table[h];
base_table[h]=0;
while(tmp)
{
|
d3b06f | 2000-08-10 | Henrik Grubbström (Grubba) | | size_t h2;
|
2cbf7c | 1999-09-01 | Fredrik Hübinette (Hubbe) | | struct pike_string *tmp2=tmp;
tmp=tmp2->next;
|
8bcb3b | 2001-03-28 | Fredrik Hübinette (Hubbe) | | tmp2->hval=do_hash(tmp2);
|
e85df8 | 2001-09-06 | Fredrik Hübinette (Hubbe) | | h2=HMODULO(tmp2->hval);
|
2cbf7c | 1999-09-01 | Fredrik Hübinette (Hubbe) | |
tmp2->next=base_table[h2];
base_table[h2]=tmp2;
}
}
|
3ac5e8 | 2001-03-30 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_RUN_UNLOCKED
for(h=0;h<BUCKET_LOCKS;h++) mt_unlock(bucket_locks + h);
#endif
|
2cbf7c | 1999-09-01 | Fredrik Hübinette (Hubbe) | | }
|
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) | | {
|
4170b9 | 2004-11-06 | Henrik Grubbström (Grubba) | | struct pike_string *t = NULL;
|
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
|
ed2bed | 2013-06-14 | Per Hedbor | | if ((len<<shift) <= SHORT_STRING_THRESHOLD) {
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
|
d47659 | 2013-06-12 | Arne Goedeke | | if (shift > 2)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Unsupported string shift: %d\n", shift);
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | #endif /* PIKE_DEBUG */
|
dc8d02 | 2014-04-27 | Martin Nilsson | | t=ba_alloc(&string_allocator);
|
d47659 | 2013-06-12 | Arne Goedeke | | t->flags = STRING_NOT_HASHED|STRING_NOT_SHARED|STRING_IS_SHORT;
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | } else {
|
dc8d02 | 2014-04-27 | Martin Nilsson | | t=xalloc(((len + 1)<<shift) + sizeof(struct pike_string_hdr));
|
9cd037 | 2005-11-03 | Henrik Grubbström (Grubba) | | t->flags = STRING_NOT_HASHED|STRING_NOT_SHARED;
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | }
|
938632 | 2011-07-21 | Henrik Grubbström (Grubba) | | #ifdef ATOMIC_SVALUE
t->ref_type = T_STRING;
#endif
|
dc245f | 2011-07-21 | Henrik Grubbström (Grubba) | | t->refs = 0;
add_ref(t);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | t->len=len;
t->size_shift=shift;
|
0e602a | 2006-01-12 | Henrik Grubbström (Grubba) | | DO_IF_DEBUG(t->next = NULL);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | low_set_index(t,len,0);
return t;
}
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | |
|
66d928 | 2011-05-01 | Per Hedbor | | struct pike_string *low_end_shared_string(struct pike_string *s)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
2eed0b | 2000-10-08 | Henrik Grubbström (Grubba) | | ptrdiff_t len;
|
ec51ce | 2006-04-25 | David Hedbor | | size_t h=0;
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *s2;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
e8371e | 2008-06-23 | Martin Stjernholm | | #ifdef PIKE_DEBUG
if (d_flag) {
switch (s->size_shift) {
case 0:
break;
case 1:
if(!find_magnitude1(STR1(s),s->len))
Pike_fatal ("String %p that should have shift 1 really got 0.\n", s);
break;
case 2: {
int m = find_magnitude2 (STR2 (s), s->len);
if (m != 2)
Pike_fatal ("String %p that should have shift 2 really got %d.\n",
s, m);
break;
}
default:
Pike_fatal("ARGHEL! size_shift:%d\n", s->size_shift);
}
}
#endif
|
d3b06f | 2000-08-10 | Henrik Grubbström (Grubba) | | len = s->len;
|
9cd037 | 2005-11-03 | Henrik Grubbström (Grubba) | | if (s->flags & STRING_NOT_HASHED) {
h = s->hval = do_hash(s);
s->flags &= ~STRING_NOT_HASHED;
}
|
2eed0b | 2000-10-08 | Henrik Grubbström (Grubba) | | 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)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("end_shared_string called twice! (or something like that)\n");
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | #endif
if(s2)
{
|
9cd037 | 2005-11-03 | Henrik Grubbström (Grubba) | | free_string(s);
|
2eed0b | 2000-10-08 | Henrik Grubbström (Grubba) | | s = s2;
|
9cd037 | 2005-11-03 | Henrik Grubbström (Grubba) | | add_ref(s);
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | }else{
link_pike_string(s, h);
}
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:
|
e8371e | 2008-06-23 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("ARGHEL! size_shift:%d\n", s->size_shift);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
case 2:
|
e8371e | 2008-06-23 | Martin Stjernholm | | #endif
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | 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);
|
9cd037 | 2005-11-03 | Henrik Grubbström (Grubba) | | free_string(s);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | 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);
|
9cd037 | 2005-11-03 | Henrik Grubbström (Grubba) | | free_string(s);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | s=s2;
}
break;
|
992551 | 2013-05-31 | Per Hedbor | |
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | 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);
|
9cd037 | 2005-11-03 | Henrik Grubbström (Grubba) | | free_string(s);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | 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) | | }
|
d5b1e2 | 2000-11-29 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct pike_string *end_and_resize_shared_string(struct pike_string *str, ptrdiff_t len)
{
struct pike_string *tmp;
#ifdef PIKE_DEBUG
if(len > str->len)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Cannot extend string here!\n");
|
d5b1e2 | 2000-11-29 | Fredrik Hübinette (Hubbe) | | #endif
|
d229e3 | 2008-11-05 | Henrik Grubbström (Grubba) | | if( (str->len <= SHORT_STRING_THRESHOLD) ||
((len > SHORT_STRING_THRESHOLD) && (str->len <= (len<<1))) )
|
d5b1e2 | 2000-11-29 | Fredrik Hübinette (Hubbe) | | {
|
d229e3 | 2008-11-05 | Henrik Grubbström (Grubba) | |
|
d5b1e2 | 2000-11-29 | Fredrik Hübinette (Hubbe) | | str->len=len;
|
f2f763 | 2008-11-05 | Henrik Grubbström (Grubba) | | SET_INDEX_PCHARP(MKPCHARP_STR(str), len, 0);
|
d5b1e2 | 2000-11-29 | Fredrik Hübinette (Hubbe) | | return end_shared_string(str);
}
tmp = make_shared_binary_pcharp(MKPCHARP_STR(str),len);
|
9cd037 | 2005-11-03 | Henrik Grubbström (Grubba) | | free_string(str);
|
d5b1e2 | 2000-11-29 | Fredrik Hübinette (Hubbe) | | return tmp;
}
|
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;
|
89fc4c | 2000-08-10 | Henrik Grubbström (Grubba) | | ptrdiff_t h = StrHash(str, len);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
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);
|
531730 | 2005-11-05 | Henrik Grubbström (Grubba) | | } else {
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);
|
c6b604 | 2008-05-03 | Martin Nilsson | | #ifdef PIKE_DEBUG
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | default:
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Unknown string width!\n");
|
c6b604 | 2008-05-03 | Martin Nilsson | | #endif
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | }
|
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;
|
89fc4c | 2000-08-10 | Henrik Grubbström (Grubba) | | ptrdiff_t h;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
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);
|
531730 | 2005-11-05 | Henrik Grubbström (Grubba) | | } else {
add_ref(s);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | }
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;
|
89fc4c | 2000-08-10 | Henrik Grubbström (Grubba) | | ptrdiff_t h;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
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);
|
531730 | 2005-11-05 | Henrik Grubbström (Grubba) | | } else {
add_ref(s);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | }
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) | |
|
66d928 | 2011-05-01 | Per Hedbor | | static void unlink_pike_string(struct pike_string *s)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | size_t h;
LOCK_BUCKET(s->hval);
|
e85df8 | 2001-09-06 | Fredrik Hübinette (Hubbe) | | h= HMODULO(s->hval);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | propagate_shared_string(s,h);
|
4bdf5f | 2001-03-30 | Henrik Grubbström (Grubba) | | #ifdef PIKE_DEBUG
if (base_table[h] != s) {
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("propagate_shared_string() failed. Probably got bogus pike_string.\n");
|
4bdf5f | 2001-03-30 | Henrik Grubbström (Grubba) | | }
#endif /* PIKE_DEBUG */
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | base_table[h]=s->next;
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
89fc4c | 2000-08-10 | Henrik Grubbström (Grubba) | | s->next=(struct pike_string *)(ptrdiff_t)-1;
|
230223 | 1998-04-23 | Fredrik Hübinette (Hubbe) | | #endif
|
760b26 | 1996-12-03 | Fredrik Hübinette (Hubbe) | | num_strings--;
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | UNLOCK_BUCKET(s->hval);
|
9cd037 | 2005-11-03 | Henrik Grubbström (Grubba) | | s->flags |= STRING_NOT_SHARED;
|
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) | | }
|
fb2294 | 2008-06-16 | Martin Stjernholm | | PMOD_EXPORT void do_free_unlinked_pike_string(struct pike_string *s)
|
d5b1e2 | 2000-11-29 | Fredrik Hübinette (Hubbe) | | {
if (s)
|
fb2294 | 2008-06-16 | Martin Stjernholm | | free_unlinked_pike_string(s);
|
d5b1e2 | 2000-11-29 | 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;
|
d631b8 | 2002-12-01 | Martin Stjernholm | | if (s->refs) {
#ifdef DEBUG_MALLOC
describe_something(s, T_STRING, 0,2,0, NULL);
#endif
Pike_fatal("Freeing string with %d references.\n", s->refs);
}
|
f88e29 | 2007-03-29 | Marcus Comstedt | | if(d_flag > 2 && !(s->flags & STRING_NOT_SHARED))
|
d631b8 | 2002-12-01 | Martin Stjernholm | | {
if(s->next == (struct pike_string *)(ptrdiff_t)-1)
Pike_fatal("Freeing shared string again!\n");
|
7abf49 | 1998-04-17 | Fredrik Hübinette (Hubbe) | |
|
d631b8 | 2002-12-01 | Martin Stjernholm | | if(((ptrdiff_t)s->next) & 1)
Pike_fatal("Freeing shared string again, memory corrupt or other bug!\n");
|
936735 | 1997-01-27 | Fredrik Hübinette (Hubbe) | | }
|
d47659 | 2013-06-12 | Arne Goedeke | | if (s->size_shift > 2) {
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Freeing string with bad shift (0x%08x); could it be a type?\n",
|
c7eadf | 2001-03-29 | Henrik Grubbström (Grubba) | | s->size_shift);
}
|
936735 | 1997-01-27 | Fredrik Hübinette (Hubbe) | | #endif
|
9cd037 | 2005-11-03 | Henrik Grubbström (Grubba) | | if (!(s->flags & STRING_NOT_SHARED))
unlink_pike_string(s);
|
8a1454 | 2008-06-29 | Martin Nilsson | | if (s->flags & STRING_CLEAR_ON_EXIT)
|
0a146b | 2013-03-12 | Arne Goedeke | | guaranteed_memset(s->str, 0, s->len<<s->size_shift);
|
fb2294 | 2008-06-16 | Martin Stjernholm | | free_unlinked_pike_string(s);
|
6cb783 | 2000-09-15 | Martin Stjernholm | | GC_FREE_SIMPLE_BLOCK(s);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
66d928 | 2011-05-01 | Per Hedbor | | void do_really_free_string(struct pike_string *s)
|
fb2294 | 2008-06-16 | Martin Stjernholm | | {
if (s)
really_free_string(s);
}
|
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) | | {
|
50ea68 | 2003-03-14 | Henrik Grubbström (Grubba) | | if(!sub_ref(s))
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | 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) | | {
|
af8026 | 2013-02-07 | Henrik Grubbström (Grubba) | | struct string_builder s;
init_string_builder(&s, 0);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
if (verbose)
{
|
af8026 | 2013-02-07 | Henrik Grubbström (Grubba) | | long alloced_strings[8] = {0,0,0,0,0,0,0,0};
long alloced_bytes[8] = {0,0,0,0,0,0,0,0};
long num_distinct_strings[8] = {0,0,0,0,0,0,0,0};
long bytes_distinct_strings[8] = {0,0,0,0,0,0,0,0};
long overhead_bytes[8] = {0,0,0,0,0,0,0,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) | | {
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | LOCK_BUCKET(e);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | for(p=base_table[e];p;p=p->next)
{
|
af8026 | 2013-02-07 | Henrik Grubbström (Grubba) | | int is_short = (p->len <= SHORT_STRING_THRESHOLD);
int key = (is_short?0:4) | p->size_shift;
num_distinct_strings[key]++;
if (is_short) {
bytes_distinct_strings[key] +=
DO_ALIGN(SHORT_STRING_THRESHOLD << p->size_shift, sizeof(void *));
} else {
bytes_distinct_strings[key] +=
DO_ALIGN(p->len << p->size_shift, sizeof(void *));
}
alloced_strings[key] += p->refs;
alloced_bytes[key] +=
p->refs*DO_ALIGN((p->len+3) << p->size_shift,sizeof(void *));
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | UNLOCK_BUCKET(e);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
af8026 | 2013-02-07 | Henrik Grubbström (Grubba) | | string_builder_sprintf(&s,
"\nShared string hash table:\n"
"-------------------------\n"
"\n"
"Type Count Distinct Bytes Actual Overhead %%\n"
"------------------------------------------------------------\n");
for(e = 0; e < 8; e++) {
int shift = e & 3;
ptrdiff_t overhead;
if (!num_distinct_strings[e]) continue;
if (shift != 3) {
if (e < 4) {
string_builder_sprintf(&s, "Short/%-2d ", 8<<shift);
} else {
string_builder_sprintf(&s, "Long/%-2d ", 8<<shift);
}
overhead_bytes[e] =
DO_NOT_WARN((long)sizeof(struct pike_string_hdr) *
num_distinct_strings[e]);
alloced_strings[e|3] += alloced_strings[e];
alloced_bytes[e|3] += alloced_bytes[e];
num_distinct_strings[e|3] += num_distinct_strings[e];
bytes_distinct_strings[e|3] += bytes_distinct_strings[e];
overhead_bytes[e|3] += overhead_bytes[e];
} else {
if (e < 4) {
string_builder_sprintf(&s, "Total short");
} else {
string_builder_sprintf(&s, "Total long ");
}
}
string_builder_sprintf(&s,
"%8ld %8ld %8ld %8ld %8ld ",
alloced_strings[e], num_distinct_strings[e],
alloced_bytes[e], bytes_distinct_strings[e],
overhead_bytes[e]);
if (alloced_bytes[e]) {
string_builder_sprintf(&s, "%4d\n",
(bytes_distinct_strings[e] +
overhead_bytes[e]) * 100 /
alloced_bytes[e]);
} else {
string_builder_strcat(&s, " -\n");
}
}
alloced_strings[7] += alloced_strings[3];
alloced_bytes[7] += alloced_bytes[3];
num_distinct_strings[7] += num_distinct_strings[3];
bytes_distinct_strings[7] += bytes_distinct_strings[3];
overhead_bytes[7] += overhead_bytes[3];
string_builder_sprintf(&s,
"------------------------------------------------------------\n"
"Total %8ld %8ld %8ld %8ld %8ld ",
alloced_strings[7], num_distinct_strings[7],
alloced_bytes[7], bytes_distinct_strings[7],
overhead_bytes[7]);
if (alloced_bytes[7]) {
string_builder_sprintf(&s, "%4d\n",
(bytes_distinct_strings[7] +
overhead_bytes[7]) * 100 /
alloced_bytes[7]);
} else {
string_builder_strcat(&s, " -\n");
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
af8026 | 2013-02-07 | Henrik Grubbström (Grubba) | | return finish_string_builder(&s);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | |
#ifdef PIKE_DEBUG
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
|
6b997c | 2001-09-04 | Fredrik Hübinette (Hubbe) | | static long last_stralloc_verify=0;
extern long current_do_debug_cycle;
|
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) | | {
|
6b997c | 2001-09-04 | Fredrik Hübinette (Hubbe) | | if(current_do_debug_cycle == last_stralloc_verify)
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | {
|
6b997c | 2001-09-04 | Fredrik Hübinette (Hubbe) | | if(debug_findstring(s) !=s)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Shared string not shared.\n");
|
6b997c | 2001-09-04 | Fredrik Hübinette (Hubbe) | | }else{
|
abdf6b | 2005-04-02 | Martin Stjernholm | |
switch (s->size_shift) {
case 0:
break;
case 1: {
ptrdiff_t i;
p_wchar1 *str = STR1 (s);
for (i = 0; i < s->len; i++)
if (str[i] > 0xff)
goto size_shift_check_done;
Pike_fatal ("Shared string is too wide.\n");
}
case 2: {
ptrdiff_t i;
p_wchar2 *str = STR2 (s);
for (i = 0; i < s->len; i++)
|
3e9918 | 2008-06-29 | Henrik Grubbström (Grubba) | | if ((str[i] > 0xffff) || (str[i] < 0))
|
abdf6b | 2005-04-02 | Martin Stjernholm | | goto size_shift_check_done;
Pike_fatal ("Shared string is too wide.\n");
}
default:
Pike_fatal ("Invalid size shift %d.\n", s->size_shift);
}
size_shift_check_done:;
|
6b997c | 2001-09-04 | Fredrik Hübinette (Hubbe) | | if(do_hash(s) != s->hval)
{
locate_problem(wrong_hash);
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Hash value changed?\n");
|
6b997c | 2001-09-04 | Fredrik Hübinette (Hubbe) | | }
|
992551 | 2013-05-31 | Per Hedbor | |
|
6b997c | 2001-09-04 | Fredrik Hübinette (Hubbe) | | if(debug_findstring(s) !=s)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Shared string not shared.\n");
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
|
6b997c | 2001-09-04 | Fredrik Hübinette (Hubbe) | | if(index_shared_string(s,s->len))
{
locate_problem(improper_zero_termination);
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Shared string is not zero terminated properly.\n");
|
6b997c | 2001-09-04 | Fredrik Hübinette (Hubbe) | | }
|
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;
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | struct pike_string *s;
|
6b997c | 2001-09-04 | Fredrik Hübinette (Hubbe) | | last_stralloc_verify=current_do_debug_cycle;
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | for(e=0;e<htable_size;e++)
{
h=0;
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | LOCK_BUCKET(e);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | 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++;
|
4bdf5f | 2001-03-30 | Henrik Grubbström (Grubba) | |
if (bad_pointer(s)) {
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Odd string pointer in string table!\n");
|
4bdf5f | 2001-03-30 | Henrik Grubbström (Grubba) | | }
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | if(s->len < 0)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Shared string shorter than zero bytes.\n");
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
if(s->refs <= 0)
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | {
locate_problem(has_zero_refs);
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_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);
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_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) | |
|
8bcb3b | 2001-03-28 | Fredrik Hübinette (Hubbe) | | if(do_hash(s) != s->hval)
|
8be482 | 2004-11-06 | Henrik Grubbström (Grubba) | | {
locate_problem(wrong_hash);
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Shared string hashed to other number.\n");
|
8be482 | 2004-11-06 | Henrik Grubbström (Grubba) | | }
|
8bcb3b | 2001-03-28 | Fredrik Hübinette (Hubbe) | |
|
e85df8 | 2001-09-06 | Fredrik Hübinette (Hubbe) | | if(HMODULO(s->hval) != e)
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | {
locate_problem(wrong_hash);
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_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(h>10000)
{
struct pike_string *s2;
for(s2=s;s2;s2=s2->next)
if(s2 == s)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Shared string table is cyclic.\n");
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | h=0;
}
}
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | UNLOCK_BUCKET(e);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | }
|
beac72 | 1998-04-16 | Fredrik Hübinette (Hubbe) | | if(num != num_strings)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Num strings is wrong %d!=%d\n",num,num_strings);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | }
|
66d928 | 2011-05-01 | Per Hedbor | | 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;
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | LOCK_BUCKET(e);
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | | for(p=base_table[e];p;p=p->next)
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | {
if(p==foo)
{
UNLOCK_BUCKET(e);
return 1;
}
}
UNLOCK_BUCKET(e);
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | | }
return 0;
}
|
66d928 | 2011-05-01 | Per Hedbor | | struct pike_string *debug_findstring(const struct pike_string *foo)
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | {
struct pike_string *tmp;
|
e85df8 | 2001-09-06 | Fredrik Hübinette (Hubbe) | | tmp=propagate_shared_string(foo, HMODULO(foo->hval));
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
#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);
|
8bcb3b | 2001-03-28 | Fredrik Hübinette (Hubbe) | |
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | LOCK_BUCKET(foo->hval);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | fprintf(stderr,"------ %p %ld\n",
|
e85df8 | 2001-09-06 | Fredrik Hübinette (Hubbe) | | base_table[HMODULO(foo->hval)],
|
8bcb3b | 2001-03-28 | Fredrik Hübinette (Hubbe) | | foo->hval);
|
e85df8 | 2001-09-06 | Fredrik Hübinette (Hubbe) | | for(tmp2=base_table[HMODULO(foo->hval)];tmp2;tmp2=tmp2->next)
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | {
if(tmp2 == tmp)
fprintf(stderr,"!!%p!!->",tmp2);
else
fprintf(stderr,"%p->",tmp2);
}
fprintf(stderr,"0\n");
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | UNLOCK_BUCKET(foo->hval);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
for(e=0;e<htable_size;e++)
{
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | LOCK_BUCKET(e);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | for(tmp2=base_table[e];tmp2;tmp2=tmp2->next)
{
if(tmp2 == tmp)
fprintf(stderr,"String found in hashbin %ld (not %ld)\n",
(long)e,
|
e85df8 | 2001-09-06 | Fredrik Hübinette (Hubbe) | | (long)HMODULO(foo->hval));
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | }
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | UNLOCK_BUCKET(e);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | }
}
|
a20d82 | 2013-06-08 | Martin Nilsson | | #endif /* 0 */
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | 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,
|
89fc4c | 2000-08-10 | Henrik Grubbström (Grubba) | | DO_NOT_WARN((long)s->len),
|
a73744 | 1998-10-11 | Henrik Grubbström (Grubba) | | s->size_shift,
|
89fc4c | 2000-08-10 | Henrik Grubbström (Grubba) | | DO_NOT_WARN((unsigned long)s->hval),
DO_NOT_WARN((unsigned long)StrHash(s->str, s->len)));
|
38d608 | 1998-02-07 | Fredrik Hübinette (Hubbe) | | 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++)
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | {
LOCK_BUCKET(e);
|
024adc | 2004-11-14 | Martin Stjernholm | | for(p=base_table[e];p;p=p->next) {
|
38d608 | 1998-02-07 | Fredrik Hübinette (Hubbe) | | debug_dump_pike_string(p, 70);
|
024adc | 2004-11-14 | Martin Stjernholm | | #ifdef DEBUG_MALLOC
debug_malloc_dump_references (p, 2, 1, 0);
#endif
}
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | UNLOCK_BUCKET(e);
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
a20d82 | 2013-06-08 | Martin Nilsson | | #endif /* PIKE_DEBUG */
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
|
a9b817 | 2014-04-05 | Martin Nilsson | | int low_quick_binary_strcmp(const char *a, ptrdiff_t alen,
const char *b, ptrdiff_t blen)
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | {
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) | |
|
66d928 | 2011-05-01 | Per Hedbor | | ptrdiff_t generic_quick_binary_strcmp(const char *a,
|
89fc4c | 2000-08-10 | Henrik Grubbström (Grubba) | | ptrdiff_t alen, int asize,
const char *b,
ptrdiff_t blen, int bsize)
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | {
if(!asize && !bsize)
{
int tmp;
|
8dc56f | 2006-03-11 | Henrik Grubbström (Grubba) | |
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | 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{
|
8dc56f | 2006-03-11 | Henrik Grubbström (Grubba) | | ptrdiff_t pos;
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | for(pos=0;pos< MINIMUM(alen,blen) ;pos++)
{
|
8dc56f | 2006-03-11 | Henrik Grubbström (Grubba) | | p_wchar2 ac=generic_extract(a,asize,pos);
p_wchar2 bc=generic_extract(b,bsize,pos);
|
d7cc37 | 2006-03-10 | Henrik Grubbström (Grubba) | | if(ac != bc) {
if (ac < bc) return -1;
return 1;
}
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | }
return alen-blen;
}
}
|
d7cc37 | 2006-03-10 | Henrik Grubbström (Grubba) | |
|
66d928 | 2011-05-01 | Per Hedbor | | ptrdiff_t generic_find_binary_prefix(const char *a,
|
d7cc37 | 2006-03-10 | Henrik Grubbström (Grubba) | | ptrdiff_t alen, int asize,
const char *b,
ptrdiff_t blen, int bsize)
{
ptrdiff_t pos;
ptrdiff_t len = MINIMUM(alen, blen);
switch(TWO_SIZES(asize, bsize)) {
#define CASE(AZ, BZ) \
case TWO_SIZES(AZ, BZ): { \
PIKE_CONCAT(p_wchar, AZ) *a_arr = \
(PIKE_CONCAT(p_wchar, AZ) *)a; \
|
8dc56f | 2006-03-11 | Henrik Grubbström (Grubba) | | PIKE_CONCAT(p_wchar, BZ) *b_arr = \
(PIKE_CONCAT(p_wchar, BZ) *)b; \
|
d7cc37 | 2006-03-10 | Henrik Grubbström (Grubba) | | for (pos=0; pos<len; pos++) { \
if (a_arr[pos] == b_arr[pos]) \
continue; \
if (a_arr[pos] < b_arr[pos]) \
return ~pos; \
return pos+1; \
} \
} break
CASE(0,0);
CASE(0,1);
CASE(0,2);
CASE(1,0);
CASE(1,1);
CASE(1,2);
CASE(2,0);
CASE(2,1);
CASE(2,2);
#undef CASE
}
if (alen == blen) return 0;
if (alen < blen) return ~alen;
return blen+1;
}
|
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
|
c80ee8 | 2000-08-11 | Henrik Grubbström (Grubba) | | static int low_binary_strcmp(char *a, ptrdiff_t alen,
char *b, ptrdiff_t blen)
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | {
low_quick_binary_strcmp(a,alen,b,blen);
}
#else
|
c80ee8 | 2000-08-11 | Henrik Grubbström (Grubba) | | static int low_binary_strcmp(char *a, ptrdiff_t alen,
char *b, ptrdiff_t blen)
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | {
while(alen>0 && blen>0)
{
|
986b52 | 2001-03-17 | Henrik Grubbström (Grubba) | | int tmp1 = strcoll(a,b);
ptrdiff_t tmp2;
if(tmp1) return (int)tmp1;
tmp2 = strlen(a)+1;
a += tmp2;
b += tmp2;
alen -= tmp2;
blen -= tmp2;
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | }
if(alen==blen) return 0;
if(alen > blen) return 1;
return -1;
}
#endif
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | |
|
89fc4c | 2000-08-10 | Henrik Grubbström (Grubba) | | PMOD_EXPORT ptrdiff_t 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) | | }
|
89fc4c | 2000-08-10 | Henrik Grubbström (Grubba) | | PMOD_EXPORT ptrdiff_t 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:
{
|
89fc4c | 2000-08-10 | Henrik Grubbström (Grubba) | | ptrdiff_t e, l = MINIMUM(a->len, b->len);
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | 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) | | }
|
5de269 | 2012-05-28 | Martin Stjernholm | | struct pike_string *realloc_unlinked_string(struct pike_string *a,
ptrdiff_t size)
|
8d28be | 1997-02-10 | Fredrik Hübinette (Hubbe) | | {
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | struct pike_string *r = NULL;
|
ed2bed | 2013-06-14 | Per Hedbor | | if (a->flags & STRING_IS_SHORT )
{
if (size <= SHORT_STRING_THRESHOLD/(1<<a->size_shift)) {
|
e464e0 | 2008-06-23 | Martin Stjernholm | |
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | a->len = size;
low_set_index(a, size, 0);
return a;
}
|
ed2bed | 2013-06-14 | Per Hedbor | | } else {
|
dc8d02 | 2014-04-27 | Martin Nilsson | | r=realloc(a, sizeof(struct pike_string_hdr)+((size+1)<<a->size_shift));
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | }
|
ed2bed | 2013-06-14 | Per Hedbor | |
|
8d28be | 1997-02-10 | Fredrik Hübinette (Hubbe) | | if(!r)
{
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | r=begin_wide_shared_string(size, a->size_shift);
|
a2a581 | 2013-08-25 | Arne Goedeke | | r->flags |= a->flags & ~15;
|
ed2bed | 2013-06-14 | Per Hedbor | | r->min = a->min;
r->max = a->max;
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | if (a->len <= size) {
MEMCPY(r->str, a->str, a->len<<a->size_shift);
} else {
MEMCPY(r->str, a->str, size<<a->size_shift);
}
|
9cd037 | 2005-11-03 | Henrik Grubbström (Grubba) | | free_string(a);
|
8d28be | 1997-02-10 | Fredrik Hübinette (Hubbe) | | }
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;
}
|
66d928 | 2011-05-01 | Per Hedbor | | static struct pike_string *realloc_shared_string(struct pike_string *a,
ptrdiff_t 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);
|
a2a581 | 2013-08-25 | Arne Goedeke | | r->flags |= a->flags & ~15;
|
ed2bed | 2013-06-14 | Per Hedbor | | r->min = a->min;
r->max = a->max;
|
709463 | 1997-02-24 | Fredrik Hübinette (Hubbe) | | free_string(a);
|
8d28be | 1997-02-10 | Fredrik Hübinette (Hubbe) | | return r;
}
}
|
66d928 | 2011-05-01 | Per Hedbor | | 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);
|
a2a581 | 2013-08-25 | Arne Goedeke | | r->flags |= (a->flags & ~15);
|
ed2bed | 2013-06-14 | Per Hedbor | | r->min = a->min;
r->max = a->max;
|
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) | | */
|
66d928 | 2011-05-01 | Per Hedbor | | 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)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Index out of range in modify_shared_string()\n");
|
0d3ea5 | 1998-01-19 | Fredrik Hübinette (Hubbe) | | #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);
|
c6b604 | 2008-05-03 | Martin Nilsson | | #ifdef PIKE_DEBUG
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | default:
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Odd wide string conversion!\n");
|
c6b604 | 2008-05-03 | Martin Nilsson | | #endif
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | }
}
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:
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Unshrinkable!\n");
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
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) | |
|
e94f07 | 2005-01-18 | Henrik Grubbström (Grubba) | | unlink_pike_string(a);
low_set_index(a, index, c);
|
992551 | 2013-05-31 | Per Hedbor | | CLEAR_STRING_CHECKED(a);
|
8282ca | 2013-11-02 | Per Hedbor | | if((((unsigned int)index) >= hash_prefix_len) && (index < a->len-8))
|
0d3ea5 | 1998-01-19 | Fredrik Hübinette (Hubbe) | | {
|
6ed3d2 | 2005-01-17 | Henrik Grubbström (Grubba) | | struct pike_string *old;
|
8282ca | 2013-11-02 | Per Hedbor | |
|
5cc19b | 2005-05-18 | Martin Nilsson | | #ifdef PIKE_DEBUG
|
950ade | 2005-05-17 | Henrik Grubbström (Grubba) | | if (wrong_hash(a)) {
Pike_fatal("Broken hash optimization.\n");
}
|
5cc19b | 2005-05-18 | Martin Nilsson | | #endif
|
6ed3d2 | 2005-01-17 | Henrik Grubbström (Grubba) | | old = internal_findstring(a->str, a->len, a->size_shift, a->hval);
if (old) {
|
9cd037 | 2005-11-03 | Henrik Grubbström (Grubba) | | free_string(a);
|
6ed3d2 | 2005-01-17 | Henrik Grubbström (Grubba) | | add_ref(a = old);
} else {
link_pike_string(a, a->hval);
}
|
0d3ea5 | 1998-01-19 | Fredrik Hübinette (Hubbe) | | }else{
|
e94f07 | 2005-01-18 | Henrik Grubbström (Grubba) | | a = end_shared_string(a);
|
0d3ea5 | 1998-01-19 | Fredrik Hübinette (Hubbe) | | }
|
e94f07 | 2005-01-18 | Henrik Grubbström (Grubba) | | return a;
|
0d3ea5 | 1998-01-19 | Fredrik Hübinette (Hubbe) | | }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);
}
}
|
992551 | 2013-05-31 | Per Hedbor | | PMOD_EXPORT void set_flags_for_add( struct pike_string *ret,
unsigned char aflags,
unsigned char amin,
unsigned char amax,
struct pike_string *b)
{
if( !b->len ) {
|
a2a581 | 2013-08-25 | Arne Goedeke | | ret->flags |= aflags & ~15;
|
992551 | 2013-05-31 | Per Hedbor | | ret->min = amin;
ret->max = amax;
return;
}
|
afd5eb | 2013-06-03 | Martin Nilsson | | if( aflags & b->flags & STRING_CONTENT_CHECKED )
|
992551 | 2013-05-31 | Per Hedbor | | {
|
6431dc | 2013-06-17 | Henrik Grubbström (Grubba) | | ret->min = MINIMUM( amin, b->min );
ret->max = MAXIMUM( amax, b->max );
|
992551 | 2013-05-31 | Per Hedbor | | ret->flags |= STRING_CONTENT_CHECKED;
}
else
ret->flags &= ~STRING_CONTENT_CHECKED;
|
a21b58 | 2013-06-09 | Martin Nilsson | | ret->flags &= ~(STRING_IS_LOWERCASE | STRING_IS_UPPERCASE);
ret->flags |= (aflags & b->flags & (STRING_IS_LOWERCASE | STRING_IS_UPPERCASE));
|
992551 | 2013-05-31 | Per Hedbor | | }
PMOD_EXPORT void update_flags_for_add( struct pike_string *a, struct pike_string *b)
{
if( !b->len ) return;
if( a->flags & STRING_CONTENT_CHECKED )
{
if(b->flags & STRING_CONTENT_CHECKED)
{
if( b->min < a->min ) a->min = b->min;
if( b->max > a->max ) a->max = b->max;
}
else
a->flags &= ~STRING_CONTENT_CHECKED;
}
|
f3b33d | 2013-06-03 | Martin Nilsson | | a->flags &= ~(STRING_IS_LOWERCASE | STRING_IS_UPPERCASE) | b->flags;
|
992551 | 2013-05-31 | Per Hedbor | | }
|
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,
|
992551 | 2013-05-31 | Per Hedbor | | 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);
|
992551 | 2013-05-31 | Per Hedbor | | set_flags_for_add( ret, a->flags, a->min, a->max, b );
|
1743c8 | 2001-02-03 | Fredrik Hübinette (Hubbe) | | return low_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,
|
992551 | 2013-05-31 | Per Hedbor | | struct pike_string *b)
|
b1f4eb | 1998-01-13 | Fredrik Hübinette (Hubbe) | | {
|
89fc4c | 2000-08-10 | Henrik Grubbström (Grubba) | | ptrdiff_t alen = a->len;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | if(a->size_shift == b->size_shift)
{
|
992551 | 2013-05-31 | Per Hedbor | | a = realloc_shared_string(a, alen + b->len);
|
ed2bed | 2013-06-14 | Per Hedbor | | update_flags_for_add( a, b );
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | MEMCPY(a->str+(alen<<a->size_shift),b->str,b->len<<b->size_shift);
free_string(b);
|
9cd037 | 2005-11-03 | Henrik Grubbström (Grubba) | | a->flags |= STRING_NOT_HASHED;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | return end_shared_string(a);
}else{
struct pike_string *ret=add_shared_strings(a,b);
free_string(a);
free_string(b);
return ret;
}
}
|
89fc4c | 2000-08-10 | Henrik Grubbström (Grubba) | | PMOD_EXPORT ptrdiff_t string_search(struct pike_string *haystack,
struct pike_string *needle,
ptrdiff_t start)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
|
9b1f03 | 2000-10-09 | Fredrik Hübinette (Hubbe) | | SearchMojt mojt;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | char *r;
|
992551 | 2013-05-31 | Per Hedbor | | if( !string_range_contains_string( haystack, needle ) )
return -1;
if(start + needle->len > haystack->len)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | return -1;
|
bfcfb0 | 2001-11-08 | Fredrik Hübinette (Hubbe) | | if(!needle->len) return start;
|
9b1f03 | 2000-10-09 | Fredrik Hübinette (Hubbe) | | mojt=compile_memsearcher(MKPCHARP_STR(needle),
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | needle->len,
|
5d5423 | 2000-10-09 | Fredrik Hübinette (Hubbe) | | haystack->len,
|
9b1f03 | 2000-10-09 | Fredrik Hübinette (Hubbe) | | needle);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
|
6e54c7 | 2004-03-24 | Henrik Grubbström (Grubba) | | r = (char *)mojt.vtab->funcN(mojt.data,
ADD_PCHARP(MKPCHARP_STR(haystack), start),
haystack->len - start).ptr;
|
9b1f03 | 2000-10-09 | Fredrik Hübinette (Hubbe) | |
|
8c1183 | 2008-06-23 | Martin Stjernholm | | if (mojt.container) free_object (mojt.container);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
if(!r) return -1;
|
5d5423 | 2000-10-09 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
bd742e | 2000-10-19 | Henrik Grubbström (Grubba) | | if((r < haystack->str) ||
(r - haystack->str)>>haystack->size_shift > haystack->len)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("string_search did a bobo!\n");
|
5d5423 | 2000-10-09 | Fredrik Hübinette (Hubbe) | | #endif
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | 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 )
{
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("string_slice, start = %ld, len = %ld, s->len = %ld\n",
|
a7979d | 2000-08-11 | Henrik Grubbström (Grubba) | | DO_NOT_WARN((long)start),
DO_NOT_WARN((long)len),
DO_NOT_WARN((long)s->len));
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | }
#endif
|
6a12e4 | 2011-05-03 | Per Hedbor | | if( len == 0)
{
add_ref(empty_pike_string);
return empty_pike_string;
}
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | |
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);
}
|
c6b604 | 2008-05-03 | Martin Nilsson | | #ifdef PIKE_DEBUG
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Illegal shift size!\n");
|
c6b604 | 2008-05-03 | Martin Nilsson | | #endif
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | 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) | |
|
5d5423 | 2000-10-09 | Fredrik Hübinette (Hubbe) | | typedef char *(* replace_searchfunc)(void *,void *,size_t);
|
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;
|
5d5423 | 2000-10-09 | Fredrik Hübinette (Hubbe) | | SearchMojt mojt;
|
8c1183 | 2008-06-23 | Martin Stjernholm | | ONERROR mojt_uwp;
|
41b0b2 | 2000-10-20 | Henrik Grubbström (Grubba) | | replace_searchfunc f = (replace_searchfunc)0;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
4dd43e | 2013-06-10 | Arne Goedeke | | if(!str->len || !string_range_contains_string(str, del))
|
a99145 | 1997-07-08 | Fredrik Hübinette (Hubbe) | | {
|
4dd43e | 2013-06-10 | Arne Goedeke | | add_ref(str);
return str;
|
a99145 | 1997-07-08 | Fredrik Hübinette (Hubbe) | | }
|
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) | | {
|
5d5423 | 2000-10-09 | Fredrik Hübinette (Hubbe) | | mojt=compile_memsearcher(MKPCHARP_STR(del),
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | del->len,
str->len,
|
5d5423 | 2000-10-09 | Fredrik Hübinette (Hubbe) | | del);
|
8c1183 | 2008-06-23 | Martin Stjernholm | | SET_ONERROR (mojt_uwp, do_free_object, mojt.container);
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | ret=begin_wide_shared_string(str->len,shift);
|
5d5423 | 2000-10-09 | Fredrik Hübinette (Hubbe) | | switch(str->size_shift)
{
case 0: f=(replace_searchfunc)mojt.vtab->func0; break;
case 1: f=(replace_searchfunc)mojt.vtab->func1; break;
case 2: f=(replace_searchfunc)mojt.vtab->func2; break;
#ifdef PIKE_DEBUG
|
5aad93 | 2002-08-15 | Marcus Comstedt | | default: Pike_fatal("Illegal shift.\n");
|
5d5423 | 2000-10-09 | Fredrik Hübinette (Hubbe) | | #endif
}
|
1f515a | 1997-02-15 | Fredrik Hübinette (Hubbe) | | }else{
INT32 delimeters=0;
|
5d5423 | 2000-10-09 | Fredrik Hübinette (Hubbe) | | mojt=compile_memsearcher(MKPCHARP_STR(del),
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | del->len,
str->len*2,
|
5d5423 | 2000-10-09 | Fredrik Hübinette (Hubbe) | | del);
|
8c1183 | 2008-06-23 | Martin Stjernholm | | SET_ONERROR (mojt_uwp, do_free_object, mojt.container);
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | |
|
5d5423 | 2000-10-09 | Fredrik Hübinette (Hubbe) | | switch(str->size_shift)
{
case 0: f=(replace_searchfunc)mojt.vtab->func0; break;
case 1: f=(replace_searchfunc)mojt.vtab->func1; break;
case 2: f=(replace_searchfunc)mojt.vtab->func2; break;
#ifdef PIKE_DEBUG
|
5aad93 | 2002-08-15 | Marcus Comstedt | | default: Pike_fatal("Illegal shift.\n");
|
5d5423 | 2000-10-09 | Fredrik Hübinette (Hubbe) | | #endif
}
while((s = f(mojt.data, s, (end-s)>>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)
{
|
8c1183 | 2008-06-23 | Martin Stjernholm | | CALL_AND_UNSET_ONERROR (mojt_uwp);
|
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) | |
|
5d5423 | 2000-10-09 | Fredrik Hübinette (Hubbe) | | while((tmp = f(mojt.data, s, (end-s)>>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)
|
362d30 | 2004-03-08 | Martin Nilsson | | Pike_fatal("SearchMojt found a match beyond end of string!!!\n");
|
68d913 | 1999-04-01 | Fredrik Hübinette (Hubbe) | | #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) | |
|
8c1183 | 2008-06-23 | Martin Stjernholm | | CALL_AND_UNSET_ONERROR (mojt_uwp);
|
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++);
|
e85df8 | 2001-09-06 | Fredrik Hübinette (Hubbe) | | SET_HSIZE(hashprimes_entry);
|
9c14f3 | 2014-04-27 | Martin Nilsson | | base_table=xcalloc(sizeof(struct pike_string *), htable_size);
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_RUN_UNLOCKED
{
int h;
|
dc8d02 | 2014-04-27 | Martin Nilsson | | bucket_locks=xalloc(sizeof(PIKE_MUTEX_T)*BUCKET_LOCKS);
|
3ac5e8 | 2001-03-30 | Fredrik Hübinette (Hubbe) | | for(h=0;h<BUCKET_LOCKS;h++) mt_init(bucket_locks + h);
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | }
#endif
|
4edb1a | 2002-09-11 | David Hedbor | | empty_pike_string = make_shared_string("");
|
992551 | 2013-05-31 | Per Hedbor | | empty_pike_string->flags |= STRING_CONTENT_CHECKED | STRING_IS_LOWERCASE | STRING_IS_UPPERCASE;
empty_pike_string->min = empty_pike_string->max = 0;
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | }
|
31a868 | 2004-09-27 | Martin Stjernholm | | #ifdef DO_PIKE_CLEANUP
|
00e668 | 2006-07-05 | Martin Stjernholm | | PMOD_EXPORT struct shared_string_location *all_shared_string_locations;
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | #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) | |
|
4edb1a | 2002-09-11 | David Hedbor | | if (empty_pike_string) {
free_string(empty_pike_string);
empty_pike_string = 0;
|
7ff571 | 2001-12-20 | Martin Stjernholm | | }
|
31a868 | 2004-09-27 | Martin Stjernholm | | #ifdef DO_PIKE_CLEANUP
|
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;
}
|
31a868 | 2004-09-27 | Martin Stjernholm | | if (exit_with_cleanup)
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | {
|
f757d0 | 2008-05-01 | Martin Stjernholm | | size_t num,size;
|
3c0c28 | 1998-01-26 | Fredrik Hübinette (Hubbe) | | count_memory_in_strings(&num,&size);
if(num)
{
|
f757d0 | 2008-05-01 | Martin Stjernholm | | fprintf(stderr,"Strings left: %"PRINTSIZET"d "
"(%"PRINTSIZET"d bytes) (zapped)\n",num,size);
|
31a868 | 2004-09-27 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
3c0c28 | 1998-01-26 | Fredrik Hübinette (Hubbe) | | dump_stralloc_strings();
|
31a868 | 2004-09-27 | Martin Stjernholm | | #endif
|
3c0c28 | 1998-01-26 | Fredrik Hübinette (Hubbe) | | }
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | }
#endif
|
46563d | 2000-12-01 | Henrik Grubbström (Grubba) | |
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | for(e=0;e<htable_size;e++)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | LOCK_BUCKET(e);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | for(s=base_table[e];s;s=next)
{
next=s->next;
#ifdef REALLY_FREE
|
fb2294 | 2008-06-16 | Martin Stjernholm | | free_unlinked_pike_string(s);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #else
s->next=0;
#endif
}
base_table[e]=0;
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | UNLOCK_BUCKET(e);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
0ec752 | 2014-04-27 | Martin Nilsson | | free(base_table);
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | base_table=0;
num_strings=0;
|
46563d | 2000-12-01 | Henrik Grubbström (Grubba) | |
|
0d7069 | 2002-11-28 | Martin Stjernholm | | #ifdef DO_PIKE_CLEANUP
|
22287c | 2013-06-16 | Arne Goedeke | | ba_destroy(&string_allocator);
|
0d7069 | 2002-11-28 | Martin Stjernholm | | #endif /* DO_PIKE_CLEANUP */
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
c3c703 | 1996-12-04 | Fredrik Hübinette (Hubbe) | |
|
3c0860 | 2008-05-02 | Martin Stjernholm | | static INLINE size_t memory_in_string (struct pike_string *s)
{
|
ed2bed | 2013-06-14 | Per Hedbor | | if (s->flags & STRING_IS_SHORT )
return sizeof (struct short_pike_string0);
|
3c0860 | 2008-05-02 | Martin Stjernholm | | else
return sizeof (struct pike_string_hdr) + ((s->len + 1) << s->size_shift);
}
|
041a53 | 2012-03-08 | Henrik Grubbström (Grubba) | | void count_memory_in_short_pike_strings(size_t *num, size_t *size)
{
|
ed2bed | 2013-06-14 | Per Hedbor | | ba_count_all(&string_allocator, num, size);
|
041a53 | 2012-03-08 | Henrik Grubbström (Grubba) | | }
|
f757d0 | 2008-05-01 | Martin Stjernholm | | void count_memory_in_strings(size_t *num, size_t *size)
|
c3c703 | 1996-12-04 | Fredrik Hübinette (Hubbe) | | {
|
f757d0 | 2008-05-01 | Martin Stjernholm | | unsigned INT32 e;
size_t 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;
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | LOCK_BUCKET(e);
|
c3c703 | 1996-12-04 | Fredrik Hübinette (Hubbe) | | for(p=base_table[e];p;p=p->next)
{
num_++;
|
3c0860 | 2008-05-02 | Martin Stjernholm | | size_ += memory_in_string (p);
|
c3c703 | 1996-12-04 | Fredrik Hübinette (Hubbe) | | }
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | UNLOCK_BUCKET(e);
|
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_)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_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) | |
|
1eb985 | 2008-05-11 | Martin Stjernholm | | PMOD_EXPORT void visit_string (struct pike_string *s, int action)
|
ad8d05 | 2008-05-02 | Martin Stjernholm | | {
|
5e8344 | 2008-05-11 | Martin Stjernholm | | switch (action) {
#ifdef PIKE_DEBUG
default:
Pike_fatal ("Unknown visit action %d.\n", action);
case VISIT_NORMAL:
case VISIT_COMPLEX_ONLY:
break;
#endif
case VISIT_COUNT_BYTES:
mc_counted_bytes += memory_in_string (s);
break;
}
|
ad8d05 | 2008-05-02 | Martin Stjernholm | | }
|
7a2672 | 2000-09-04 | Martin Stjernholm | | #ifdef PIKE_DEBUG
unsigned gc_touch_all_strings(void)
{
unsigned INT32 e;
unsigned n = 0;
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) debug_gc_touch(p), n++;
}
return n;
}
|
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;
|
5e8344 | 2008-05-11 | Martin Stjernholm | | for(p=base_table[e];p;p=p->next) gc_is_referenced(p);
|
936735 | 1997-01-27 | Fredrik Hübinette (Hubbe) | | }
}
|
30431f | 2001-09-27 | Martin Stjernholm | | #endif
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
|
f7cfa8 | 2001-09-04 | Martin Stjernholm | | struct pike_string *next_pike_string (struct pike_string *s)
{
struct pike_string *next = s->next;
if (!next) {
size_t h = s->hval;
do {
h++;
LOCK_BUCKET(h);
|
e85df8 | 2001-09-06 | Fredrik Hübinette (Hubbe) | | h = HMODULO(h);
|
f7cfa8 | 2001-09-04 | Martin Stjernholm | | next = base_table[h];
UNLOCK_BUCKET(h);
} while (!next);
}
return next;
}
|
058cc4 | 2009-01-06 | Stephen R. van den Berg | | PMOD_EXPORT void init_string_builder_alloc(struct string_builder *s, ptrdiff_t length, int mag)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
|
058cc4 | 2009-01-06 | Stephen R. van den Berg | | s->s=begin_wide_shared_string(length,mag);
s->malloced=length;
s->known_shift=0;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | s->s->len=0;
|
e8371e | 2008-06-23 | Martin Stjernholm | | low_set_index (s->s, 0, 0);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | }
|
058cc4 | 2009-01-06 | Stephen R. van den Berg | | PMOD_EXPORT void init_string_builder(struct string_builder *s, int mag)
|
0cd426 | 2001-02-02 | Martin Stjernholm | | {
|
058cc4 | 2009-01-06 | Stephen R. van den Berg | | init_string_builder_alloc(s, 256, mag);
|
0cd426 | 2001-02-02 | Martin Stjernholm | | }
|
8d3b38 | 2003-04-07 | Martin Stjernholm | | PMOD_EXPORT void init_string_builder_copy(struct string_builder *to,
struct string_builder *from)
{
to->malloced = from->malloced;
|
e8371e | 2008-06-23 | Martin Stjernholm | | to->s = begin_wide_shared_string (from->malloced, from->s->size_shift);
to->s->len = from->s->len;
MEMCPY (to->s->str, from->s->str, (from->s->len + 1) << from->s->size_shift);
|
8d3b38 | 2003-04-07 | Martin Stjernholm | | to->known_shift = from->known_shift;
}
|
97c558 | 2004-04-15 | Martin Stjernholm | |
PMOD_EXPORT int init_string_builder_with_string (struct string_builder *s,
struct pike_string *str)
{
if (str->refs == 1 && str->len > SHORT_STRING_THRESHOLD) {
unlink_pike_string (str);
|
0d379b | 2013-06-12 | Arne Goedeke | | str->flags = STRING_NOT_SHARED;
|
97c558 | 2004-04-15 | Martin Stjernholm | | s->s = str;
s->malloced = str->len;
s->known_shift = str->size_shift;
return 1;
}
return 0;
}
PMOD_EXPORT void string_build_mkspace(struct string_builder *s,
ptrdiff_t chars, int mag)
|
024adc | 2004-11-14 | Martin Stjernholm | |
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
if(mag > s->s->size_shift)
{
struct pike_string *n;
|
c9f031 | 2000-08-10 | Henrik Grubbström (Grubba) | | ptrdiff_t l = s->s->len + chars + s->malloced;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | 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;
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | s->s->len = s->malloced;
|
9cd037 | 2005-11-03 | Henrik Grubbström (Grubba) | | free_string(s->s);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | s->malloced=l;
s->s=n;
}
|
97c558 | 2004-04-15 | Martin Stjernholm | | else if(s->s->len+chars > s->malloced)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
|
97c558 | 2004-04-15 | Martin Stjernholm | | ptrdiff_t newlen = MAXIMUM(s->malloced*2,
s->s->len + chars);
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | ptrdiff_t oldlen = s->s->len;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
|
ef17c0 | 2001-09-21 | Henrik Grubbström (Grubba) | | s->s->len = s->malloced;
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | s->s = realloc_unlinked_string(s->s, newlen);
s->s->len = oldlen;
s->malloced = newlen;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | }
}
|
c9f031 | 2000-08-10 | Henrik Grubbström (Grubba) | | PMOD_EXPORT void *string_builder_allocate(struct string_builder *s, ptrdiff_t chars, int mag)
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | {
void *ret;
|
c9f031 | 2000-08-10 | Henrik Grubbström (Grubba) | | string_build_mkspace(s, chars, mag);
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | if(chars<0) s->known_shift=0;
|
c9f031 | 2000-08-10 | Henrik Grubbström (Grubba) | | ret = s->s->str + (s->s->len<<s->s->size_shift);
s->s->len += chars;
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | 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) | | {
|
89fc4c | 2000-08-10 | Henrik Grubbström (Grubba) | | ptrdiff_t i;
|
b0289e | 2000-12-01 | Henrik Grubbström (Grubba) | | int mag = min_magnitude(ch);
|
5bc68f | 2010-06-15 | Henrik Grubbström (Grubba) | | string_build_mkspace(s, 1, mag);
if (mag > s->known_shift) {
|
6f1871 | 2004-11-14 | Martin Stjernholm | | s->known_shift = mag;
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | }
|
89fc4c | 2000-08-10 | Henrik Grubbström (Grubba) | | i = s->s->len++;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | low_set_index(s->s,i,ch);
|
cb2e38 | 2001-08-29 | Henrik Grubbström (Grubba) | |
s->s->str[s->s->len << s->s->size_shift] = 0;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | }
|
abeaca | 2010-05-28 | Martin Stjernholm | | PMOD_EXPORT void string_builder_putchars(struct string_builder *s, int ch,
ptrdiff_t count)
{
ptrdiff_t len = s->s->len;
int mag = min_magnitude(ch);
|
1b2020 | 2011-01-11 | Henrik Grubbström (Grubba) | |
if (count < 0)
Pike_fatal("Non-positive count in call to string_builder_putchars().\n");
|
b963e5 | 2011-01-11 | Arne Goedeke | | if (!count) return;
|
5bc68f | 2010-06-15 | Henrik Grubbström (Grubba) | | string_build_mkspace(s, count, mag);
if (mag > s->known_shift) {
|
abeaca | 2010-05-28 | Martin Stjernholm | | s->known_shift = mag;
}
switch (s->s->size_shift) {
case 0:
MEMSET (STR0 (s->s) + s->s->len, ch, count);
break;
case 1: {
int i;
for (i = 0; i < count; i++)
(STR1 (s->s) + s->s->len)[i] = ch;
break;
}
case 2: {
int i;
for (i = 0; i < count; i++)
(STR2 (s->s) + s->s->len)[i] = ch;
break;
}
}
s->s->len += count;
s->s->str[s->s->len << s->s->size_shift] = 0;
}
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
|
024adc | 2004-11-14 | Martin Stjernholm | | PMOD_EXPORT void string_builder_binary_strcat0(struct string_builder *s,
const p_wchar0 *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)
{
|
024adc | 2004-11-14 | Martin Stjernholm | | case 0: convert_0_to_0(STR0(s->s)+s->s->len,str,len); break;
case 1: convert_0_to_1(STR1(s->s)+s->s->len,str,len); break;
case 2: convert_0_to_2(STR2(s->s)+s->s->len,str,len); break;
#ifdef PIKE_DEBUG
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | default:
|
024adc | 2004-11-14 | Martin Stjernholm | | Pike_fatal ("Illegal magnitude! (%d)\n", s->s->size_shift);
#endif
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | }
s->s->len+=len;
|
cb2e38 | 2001-08-29 | Henrik Grubbström (Grubba) | |
s->s->str[s->s->len << s->s->size_shift] = 0;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | }
|
024adc | 2004-11-14 | Martin Stjernholm | | PMOD_EXPORT void string_builder_binary_strcat1(struct string_builder *s,
const p_wchar1 *str, ptrdiff_t len)
{
if (s->s->size_shift == 0) {
if (find_magnitude1 (str, len) == 0) {
string_build_mkspace (s, len, 0);
convert_1_to_0 (STR0(s->s) + s->s->len, str, len);
s->s->len += len;
s->s->str[s->s->len] = 0;
return;
}
s->known_shift = 1;
}
string_build_mkspace (s, len, 1);
if (s->s->size_shift == 1)
convert_1_to_1 (STR1(s->s)+s->s->len, str, len);
else {
#ifdef PIKE_DEBUG
if (s->s->size_shift != 2)
Pike_fatal ("I aint got no clue 'bout nothing, dude. (%d)\n",
s->s->size_shift);
#endif
convert_1_to_2 (STR2(s->s)+s->s->len, str, len);
}
s->s->len += len;
s->s->str[s->s->len << s->s->size_shift] = 0;
}
PMOD_EXPORT void string_builder_binary_strcat2(struct string_builder *s,
const p_wchar2 *str, ptrdiff_t len)
{
if (s->s->size_shift < 2) {
int shift = find_magnitude2 (str, len);
if (shift > s->s->size_shift) {
string_build_mkspace (s, len, shift);
if (shift == 1)
convert_2_to_1 (STR1(s->s) + s->s->len, str, len);
else {
#ifdef PIKE_DEBUG
if (shift != 2) Pike_fatal ("Uhh.. Like, what? (%d)\n", shift);
#endif
convert_2_to_2 (STR2(s->s) + s->s->len, str, len);
}
s->known_shift = shift;
}
else {
string_build_mkspace (s, len, 0);
if (s->s->size_shift == 0)
convert_2_to_0 (STR0(s->s) + s->s->len, str, len);
else {
#ifdef PIKE_DEBUG
if (s->s->size_shift != 1)
Pike_fatal ("This is soo way bogus, man. (%d)\n", s->s->size_shift);
#endif
convert_2_to_1 (STR1(s->s) + s->s->len, str, len);
}
}
}
else {
string_build_mkspace (s, len, 2);
convert_2_to_2 (STR2(s->s) + s->s->len, str, len);
}
s->s->len += len;
s->s->str[s->s->len << s->s->size_shift] = 0;
}
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
|
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) | | {
|
024adc | 2004-11-14 | Martin Stjernholm | | int shift = from.shift;
if (shift > s->s->size_shift) {
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | if (shift == 1) {
shift = find_magnitude1((p_wchar1 *)from.ptr, len);
} else {
shift = find_magnitude2((p_wchar2 *)from.ptr, len);
}
|
024adc | 2004-11-14 | Martin Stjernholm | | if (shift > s->known_shift)
s->known_shift = shift;
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | }
string_build_mkspace(s, len, shift);
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | generic_memcpy(MKPCHARP_STR_OFF(s->s,s->s->len), from, len);
s->s->len+=len;
|
cb2e38 | 2001-08-29 | Henrik Grubbström (Grubba) | |
s->s->str[s->s->len << s->s->size_shift] = 0;
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | }
|
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;
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | int shift;
|
c3dbe5 | 2000-08-09 | Henrik Grubbström (Grubba) | |
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | if(len<=0)
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Cannot fill with zero length strings!\n");
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | #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);
|
cb2e38 | 2001-08-29 | Henrik Grubbström (Grubba) | |
s->s->str[s->s->len << s->s->size_shift] = 0;
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | return;
}
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | if ((shift = from.shift) > s->s->size_shift) {
if (shift == 1) {
shift = find_magnitude1((p_wchar1 *)from.ptr, len);
} else {
shift = find_magnitude2((p_wchar2 *)from.ptr, len);
}
}
string_build_mkspace(s, howmany, 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)
{
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;
}
}
|
cb2e38 | 2001-08-29 | Henrik Grubbström (Grubba) | |
s->s->str[s->s->len << s->s->size_shift] = 0;
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | }
|
357a52 | 2011-04-22 | Henrik Grubbström (Grubba) | |
PMOD_EXPORT void string_builder_utf16_strcat(struct string_builder *s,
const p_wchar1 *utf16str)
{
p_wchar1 uc;
while ((uc = *(utf16str++))) {
if ((uc & 0xf800) == 0xd800) {
p_wchar2 wchar = uc & 0x03ff;
if (!(uc & 0x0400)) {
wchar <<= 10;
}
uc = *(utf16str++);
if (uc & 0x0400) {
wchar |= (uc & 0x3ff);
} else {
wchar |= (uc & 0x3ff) << 10;
}
string_builder_putchar(s, wchar + 0x00010000);
} else {
string_builder_putchar(s, uc);
}
}
}
|
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);
|
6f1871 | 2004-11-14 | Martin Stjernholm | | s->known_shift=MAXIMUM(s->known_shift,str->size_shift);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | s->s->len+=str->len;
|
cb2e38 | 2001-08-29 | Henrik Grubbström (Grubba) | |
s->s->str[s->s->len << s->s->size_shift] = 0;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | }
|
711f44 | 2006-03-20 | Henrik Grubbström (Grubba) | | PMOD_EXPORT ptrdiff_t string_builder_quote_string(struct string_builder *buf,
struct pike_string *str,
ptrdiff_t i,
ptrdiff_t max_len,
int flags)
|
64b077 | 2006-03-20 | Henrik Grubbström (Grubba) | | {
ptrdiff_t old_len = buf->s->len;
|
711f44 | 2006-03-20 | Henrik Grubbström (Grubba) | | for (; i < str->len; i++) {
|
64b077 | 2006-03-20 | Henrik Grubbström (Grubba) | | p_wchar2 ch = index_shared_string(str, i);
|
2eaf02 | 2008-06-29 | Marcus Comstedt | | if (ch < 0 || ch > 0xffff) {
|
64b077 | 2006-03-20 | Henrik Grubbström (Grubba) | |
string_builder_binary_strcat(buf, "\\U", 2);
|
b84824 | 2014-01-15 | Arne Goedeke | | string_builder_append_integer(buf, (unsigned INT32)ch, 16, APPEND_ZERO_PAD, 8, 8);
|
64b077 | 2006-03-20 | Henrik Grubbström (Grubba) | | } else if (ch > 0xff) {
string_builder_binary_strcat(buf, "\\u", 2);
string_builder_append_integer(buf, ch, 16, APPEND_ZERO_PAD, 4, 4);
} else if (ch & 0x60) {
if (ch == '\177') {
|
a66b81 | 2009-04-10 | Henrik Grubbström (Grubba) | | goto ctrl_char;
|
64b077 | 2006-03-20 | Henrik Grubbström (Grubba) | | } else if ((ch == '"') || (ch == '\\')) {
string_builder_putchar(buf, '\\');
}
string_builder_putchar(buf, ch);
} else {
p_wchar2 next_ch;
|
34f38e | 2009-04-10 | Henrik Grubbström (Grubba) | | ctrl_char:
|
64b077 | 2006-03-20 | Henrik Grubbström (Grubba) | |
string_builder_putchar(buf, '\\');
if ((ch > 6) && (ch < 14)) {
string_builder_putchar(buf, "0123456abtnvfr"[ch]);
|
711f44 | 2006-03-20 | Henrik Grubbström (Grubba) | | if ((ch == 10) && (flags & QUOTE_BREAK_AT_LF)) {
if (buf->s->len > max_len) {
buf->s->len = old_len;
return i;
}
return i+1;
}
|
89347a | 2006-03-20 | Henrik Grubbström (Grubba) | | goto next;
|
64b077 | 2006-03-20 | Henrik Grubbström (Grubba) | | }
if (ch == 27) {
string_builder_putchar(buf, 'e');
|
89347a | 2006-03-20 | Henrik Grubbström (Grubba) | | goto next;
|
64b077 | 2006-03-20 | Henrik Grubbström (Grubba) | | }
if ((i+1 < str->len) &&
((next_ch = index_shared_string(str, i+1)) >= '0') &&
(next_ch <= '7')) {
if (flags & QUOTE_NO_STRING_CONCAT) {
string_builder_putchar(buf, 'u');
|
ee0180 | 2006-03-20 | Henrik Grubbström (Grubba) | | string_builder_append_integer(buf, ch, 16, APPEND_ZERO_PAD, 4, 4);
|
64b077 | 2006-03-20 | Henrik Grubbström (Grubba) | | } else {
string_builder_append_integer(buf, ch, 8, 0, 1, 1);
string_builder_binary_strcat(buf, "\"\"", 2);
}
|
89347a | 2006-03-20 | Henrik Grubbström (Grubba) | | goto next;
|
64b077 | 2006-03-20 | Henrik Grubbström (Grubba) | | }
string_builder_append_integer(buf, ch, 8, 0, 1, 1);
}
|
89347a | 2006-03-20 | Henrik Grubbström (Grubba) | | next:
|
64b077 | 2006-03-20 | Henrik Grubbström (Grubba) | | if (buf->s->len > max_len) {
buf->s->len = old_len;
|
711f44 | 2006-03-20 | Henrik Grubbström (Grubba) | | return i;
|
64b077 | 2006-03-20 | Henrik Grubbström (Grubba) | | }
old_len = buf->s->len;
}
|
711f44 | 2006-03-20 | Henrik Grubbström (Grubba) | | return i;
|
64b077 | 2006-03-20 | Henrik Grubbström (Grubba) | | }
|
8be482 | 2004-11-06 | Henrik Grubbström (Grubba) | | PMOD_EXPORT void string_builder_append_integer(struct string_builder *s,
LONGEST val,
unsigned int base,
|
bcc589 | 2004-11-06 | Henrik Grubbström (Grubba) | | int flags,
size_t min_width,
size_t precision)
|
8be482 | 2004-11-06 | Henrik Grubbström (Grubba) | | {
unsigned LONGEST tmp;
|
bcc589 | 2004-11-06 | Henrik Grubbström (Grubba) | | size_t len = 1;
|
8be482 | 2004-11-06 | Henrik Grubbström (Grubba) | | 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, '+');
}
|
bcc589 | 2004-11-06 | Henrik Grubbström (Grubba) | | if ((flags & APPEND_ZERO_PAD) && (precision < min_width)) {
precision = min_width;
}
|
8be482 | 2004-11-06 | Henrik Grubbström (Grubba) | | tmp = val;
if (base & (base - 1)) {
|
456946 | 2013-02-07 | Henrik Grubbström (Grubba) | | size_t cnt;
|
8be482 | 2004-11-06 | Henrik Grubbström (Grubba) | |
|
bcc589 | 2004-11-06 | Henrik Grubbström (Grubba) | | len = 0;
|
8be482 | 2004-11-06 | Henrik Grubbström (Grubba) | | do {
len++;
tmp /= base;
} while (tmp);
|
bcc589 | 2004-11-06 | Henrik Grubbström (Grubba) | |
if (len < precision) len = precision;
|
6f7471 | 2013-02-07 | Henrik Grubbström (Grubba) | | if (!(flags & APPEND_LEFT)) {
if (len < min_width) {
string_builder_fill(s, min_width - len, MKPCHARP(" ", 0),
4, 0);
}
|
bcc589 | 2004-11-06 | Henrik Grubbström (Grubba) | | min_width = 0;
}
|
456946 | 2013-02-07 | Henrik Grubbström (Grubba) | | cnt = len;
|
8be482 | 2004-11-06 | Henrik Grubbström (Grubba) | | tmp = val;
switch(s->s->size_shift) {
case 0:
{
p_wchar0 *p = string_builder_allocate(s, len, 0);
do {
|
456946 | 2013-02-07 | Henrik Grubbström (Grubba) | | p[--cnt] = numbers[tmp%base];
|
8be482 | 2004-11-06 | Henrik Grubbström (Grubba) | | tmp /= base;
|
456946 | 2013-02-07 | Henrik Grubbström (Grubba) | | } while (cnt);
|
8be482 | 2004-11-06 | Henrik Grubbström (Grubba) | | }
break;
case 1:
{
p_wchar1 *p = string_builder_allocate(s, len, 0);
do {
|
456946 | 2013-02-07 | Henrik Grubbström (Grubba) | | p[--cnt] = numbers[tmp%base];
|
8be482 | 2004-11-06 | Henrik Grubbström (Grubba) | | tmp /= base;
|
456946 | 2013-02-07 | Henrik Grubbström (Grubba) | | } while (cnt);
|
8be482 | 2004-11-06 | Henrik Grubbström (Grubba) | | }
break;
case 2:
{
p_wchar2 *p = string_builder_allocate(s, len, 0);
do {
|
456946 | 2013-02-07 | Henrik Grubbström (Grubba) | | p[--cnt] = numbers[tmp%base];
|
8be482 | 2004-11-06 | Henrik Grubbström (Grubba) | | tmp /= base;
|
456946 | 2013-02-07 | Henrik Grubbström (Grubba) | | } while (cnt);
|
8be482 | 2004-11-06 | Henrik Grubbström (Grubba) | | }
break;
}
} else {
int delta;
|
bcc589 | 2004-11-06 | Henrik Grubbström (Grubba) | | size_t shift;
|
8be482 | 2004-11-06 | Henrik Grubbström (Grubba) | | unsigned int mask;
for(delta = 1; (base>>delta) > 1; delta++)
;
mask = (1<<delta)-1;
|
bcc589 | 2004-11-06 | Henrik Grubbström (Grubba) | |
if (precision) shift = (len = precision) * delta;
else shift = delta;
|
5bd348 | 2014-01-11 | Tobias S. Josefowitz | | for (; shift < SIZEOF_LONGEST * 8 && tmp >> shift; shift += delta, len++)
|
8be482 | 2004-11-06 | Henrik Grubbström (Grubba) | | ;
|
bcc589 | 2004-11-06 | Henrik Grubbström (Grubba) | |
if ((len < min_width) && !(flags & APPEND_LEFT)) {
string_builder_fill(s, min_width - len, MKPCHARP(" ", 0),
4, 0);
min_width = 0;
}
while(shift) {
|
8be482 | 2004-11-06 | Henrik Grubbström (Grubba) | | shift -= delta;
|
bcc589 | 2004-11-06 | Henrik Grubbström (Grubba) | | string_builder_putchar(s, numbers[(tmp>>shift) & mask]);
|
8be482 | 2004-11-06 | Henrik Grubbström (Grubba) | | }
}
|
bcc589 | 2004-11-06 | Henrik Grubbström (Grubba) | | if (len < min_width) {
string_builder_fill(s, min_width - len, MKPCHARP(" ", 0),
4, 0);
}
|
4170b9 | 2004-11-06 | Henrik Grubbström (Grubba) | | }
|
bcc589 | 2004-11-06 | Henrik Grubbström (Grubba) | |
|
46a4ce | 2004-11-09 | Henrik Grubbström (Grubba) | |
#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
static LONGEST pike_va_int(VA_LIST_PTR args, int flags)
|
4170b9 | 2004-11-06 | Henrik Grubbström (Grubba) | | {
switch (flags & (APPEND_WIDTH_MASK|APPEND_SIGNED)) {
case APPEND_WIDTH_HALF:
|
46a4ce | 2004-11-09 | Henrik Grubbström (Grubba) | | return va_arg(VA_LIST_DEREF(args), unsigned int) & 0xffff;
|
4170b9 | 2004-11-06 | Henrik Grubbström (Grubba) | | case APPEND_WIDTH_HALF|APPEND_SIGNED:
|
46a4ce | 2004-11-09 | Henrik Grubbström (Grubba) | | return (short)va_arg(VA_LIST_DEREF(args), int);
|
4170b9 | 2004-11-06 | Henrik Grubbström (Grubba) | | case 0:
|
46a4ce | 2004-11-09 | Henrik Grubbström (Grubba) | | return va_arg(VA_LIST_DEREF(args), unsigned int);
|
4170b9 | 2004-11-06 | Henrik Grubbström (Grubba) | | case APPEND_SIGNED:
|
46a4ce | 2004-11-09 | Henrik Grubbström (Grubba) | | return va_arg(VA_LIST_DEREF(args), int);
|
4170b9 | 2004-11-06 | Henrik Grubbström (Grubba) | | case APPEND_WIDTH_LONG:
|
46a4ce | 2004-11-09 | Henrik Grubbström (Grubba) | | return va_arg(VA_LIST_DEREF(args), unsigned long);
|
4170b9 | 2004-11-06 | Henrik Grubbström (Grubba) | | case APPEND_WIDTH_LONG|APPEND_SIGNED:
|
46a4ce | 2004-11-09 | Henrik Grubbström (Grubba) | | return va_arg(VA_LIST_DEREF(args), long);
|
4170b9 | 2004-11-06 | Henrik Grubbström (Grubba) | | #ifdef INT64
case APPEND_WIDTH_LONG_LONG:
|
46a4ce | 2004-11-09 | Henrik Grubbström (Grubba) | | return va_arg(VA_LIST_DEREF(args), unsigned INT64);
|
4170b9 | 2004-11-06 | Henrik Grubbström (Grubba) | | case APPEND_WIDTH_LONG_LONG|APPEND_SIGNED:
|
46a4ce | 2004-11-09 | Henrik Grubbström (Grubba) | | return va_arg(VA_LIST_DEREF(args), INT64);
|
4170b9 | 2004-11-06 | Henrik Grubbström (Grubba) | | #endif /* INT64 */
}
|
6cde65 | 2004-11-08 | Henrik Grubbström (Grubba) | | Pike_fatal("string_builder_append_integerv(): Unsupported flags: 0x%04x\n",
flags);
return 0;
|
8be482 | 2004-11-06 | Henrik Grubbström (Grubba) | | }
|
686ef2 | 2004-11-11 | Henrik Grubbström (Grubba) | |
#define STATE_MIN_WIDTH 1
#define STATE_PRECISION 2
|
f619da | 2004-11-05 | Henrik Grubbström (Grubba) | | PMOD_EXPORT void string_builder_vsprintf(struct string_builder *s,
const char *fmt,
va_list args)
{
while (*fmt) {
if (*fmt == '%') {
|
bcc589 | 2004-11-06 | Henrik Grubbström (Grubba) | | int flags = 0;
size_t min_width = 0;
size_t precision = 0;
int state = 0;
|
f619da | 2004-11-05 | Henrik Grubbström (Grubba) | | fmt++;
|
e9864c | 2004-11-06 | Henrik Grubbström (Grubba) | | while (1) {
switch (*(fmt++)) {
case '%':
string_builder_putchar(s, '%');
break;
|
7a1f0e | 2004-11-06 | Henrik Grubbström (Grubba) | |
|
bcc589 | 2004-11-06 | Henrik Grubbström (Grubba) | | case '+':
flags |= APPEND_POSITIVE;
|
7a1f0e | 2004-11-06 | Henrik Grubbström (Grubba) | | continue;
|
bcc589 | 2004-11-06 | Henrik Grubbström (Grubba) | | case '-':
flags |= APPEND_LEFT;
|
7a1f0e | 2004-11-06 | Henrik Grubbström (Grubba) | | continue;
|
bcc589 | 2004-11-06 | Henrik Grubbström (Grubba) | |
case '0':
if (!state) {
flags |= APPEND_ZERO_PAD;
}
case '1': case '2': case '3':
case '4': case '5': case '6':
case '7': case '8': case '9':
|
f4193c | 2004-11-06 | Henrik Grubbström (Grubba) | | if (state == STATE_PRECISION) {
|
24d0c1 | 2004-11-06 | Henrik Grubbström (Grubba) | | precision = precision * 10 + fmt[-1] - '0';
|
bcc589 | 2004-11-06 | Henrik Grubbström (Grubba) | | } else {
state = STATE_MIN_WIDTH;
|
24d0c1 | 2004-11-06 | Henrik Grubbström (Grubba) | | min_width = min_width * 10 + fmt[-1] - '0';
|
bcc589 | 2004-11-06 | Henrik Grubbström (Grubba) | | }
|
7a1f0e | 2004-11-06 | Henrik Grubbström (Grubba) | | continue;
|
f4193c | 2004-11-06 | Henrik Grubbström (Grubba) | |
|
bcc589 | 2004-11-06 | Henrik Grubbström (Grubba) | | case '.':
state = STATE_PRECISION;
|
7a1f0e | 2004-11-06 | Henrik Grubbström (Grubba) | | continue;
|
4170b9 | 2004-11-06 | Henrik Grubbström (Grubba) | |
case 'h':
flags |= APPEND_WIDTH_HALF;
continue;
|
7b9fd1 | 2004-11-06 | Henrik Grubbström (Grubba) | |
|
538254 | 2004-11-06 | Henrik Grubbström (Grubba) | | case 'w':
|
4170b9 | 2004-11-06 | Henrik Grubbström (Grubba) | | case 'l':
if (flags & APPEND_WIDTH_LONG) {
flags |= APPEND_WIDTH_LONG_LONG;
} else {
flags |= APPEND_WIDTH_LONG;
}
continue;
|
1d15d4 | 2004-11-11 | Henrik Grubbström (Grubba) | |
case 't':
case 'z':
flags = (flags & ~APPEND_WIDTH_MASK) | APPEND_WIDTH_PTR;
continue;
|
bcc589 | 2004-11-06 | Henrik Grubbström (Grubba) | |
|
e9864c | 2004-11-06 | Henrik Grubbström (Grubba) | | case 'O':
{
|
8a2cd6 | 2004-11-06 | Henrik Grubbström (Grubba) | |
|
e9864c | 2004-11-06 | Henrik Grubbström (Grubba) | | dynamic_buffer old_buf;
init_buf(&old_buf);
describe_svalue(va_arg(args, struct svalue *), 0, NULL);
string_builder_binary_strcat(s, pike_global_buffer.s.str,
pike_global_buffer.s.len);
toss_buffer(&pike_global_buffer);
restore_buffer(&old_buf);
}
break;
case 'S':
|
7b9fd1 | 2004-11-06 | Henrik Grubbström (Grubba) | |
|
bcc589 | 2004-11-06 | Henrik Grubbström (Grubba) | | {
struct pike_string *str = va_arg(args, struct pike_string *);
size_t len = str->len;
if (precision && (precision < len)) len = precision;
if (min_width > len) {
if (flags & APPEND_LEFT) {
string_builder_append(s, MKPCHARP_STR(str), len);
string_builder_fill(s, min_width - len, MKPCHARP(" ", 0),
4, 0);
} else {
string_builder_fill(s, min_width - len, MKPCHARP(" ", 0),
4, 0);
string_builder_append(s, MKPCHARP_STR(str), len);
}
} else {
string_builder_append(s, MKPCHARP_STR(str), len);
}
}
|
e9864c | 2004-11-06 | Henrik Grubbström (Grubba) | | break;
case 's':
|
7b9fd1 | 2004-11-06 | Henrik Grubbström (Grubba) | | if (flags & APPEND_WIDTH_LONG) {
PCHARP str;
size_t len;
if ((flags & APPEND_WIDTH_LONG)== APPEND_WIDTH_LONG) {
str = MKPCHARP(va_arg(args, p_wchar1 *), 1);
} else {
str = MKPCHARP(va_arg(args, p_wchar2 *), 2);
}
len = pcharp_strlen(str);
if (precision && precision < len) len = precision;
if (min_width > len) {
if (flags & APPEND_LEFT) {
string_builder_append(s, str, len);
string_builder_fill(s, min_width - len, MKPCHARP(" ", 0),
4, 0);
} else {
string_builder_fill(s, min_width - len, MKPCHARP(" ", 0),
4, 0);
string_builder_append(s, str, len);
}
} else {
string_builder_append(s, str, len);
}
} else {
|
e9864c | 2004-11-06 | Henrik Grubbström (Grubba) | | const char *str = va_arg(args, char *);
|
bcc589 | 2004-11-06 | Henrik Grubbström (Grubba) | | size_t len = strlen(str);
if (precision && precision < len) len = precision;
if (min_width > len) {
if (flags & APPEND_LEFT) {
string_builder_binary_strcat(s, str, len);
string_builder_fill(s, min_width - len, MKPCHARP(" ", 0),
4, 0);
} else {
string_builder_fill(s, min_width - len, MKPCHARP(" ", 0),
4, 0);
string_builder_binary_strcat(s, str, len);
}
} else {
string_builder_binary_strcat(s, str, len);
}
|
e9864c | 2004-11-06 | Henrik Grubbström (Grubba) | | }
break;
case 'c':
|
8a2cd6 | 2004-11-06 | Henrik Grubbström (Grubba) | |
|
4170b9 | 2004-11-06 | Henrik Grubbström (Grubba) | | string_builder_putchar(s, va_arg(args, int));
|
e9864c | 2004-11-06 | Henrik Grubbström (Grubba) | | break;
case 'b':
|
46a4ce | 2004-11-09 | Henrik Grubbström (Grubba) | | string_builder_append_integer(s, pike_va_int(VA_LIST_ADDR(args), flags), 2,
|
6cde65 | 2004-11-08 | Henrik Grubbström (Grubba) | | flags, min_width, precision);
|
e9864c | 2004-11-06 | Henrik Grubbström (Grubba) | | break;
case 'o':
|
46a4ce | 2004-11-09 | Henrik Grubbström (Grubba) | | string_builder_append_integer(s, pike_va_int(VA_LIST_ADDR(args), flags), 8,
|
6cde65 | 2004-11-08 | Henrik Grubbström (Grubba) | | flags, min_width, precision);
|
e9864c | 2004-11-06 | Henrik Grubbström (Grubba) | | break;
case 'x':
|
46a4ce | 2004-11-09 | Henrik Grubbström (Grubba) | | string_builder_append_integer(s, pike_va_int(VA_LIST_ADDR(args), flags), 16,
|
6cde65 | 2004-11-08 | Henrik Grubbström (Grubba) | | flags, min_width, precision);
|
e9864c | 2004-11-06 | Henrik Grubbström (Grubba) | | break;
case 'X':
|
46a4ce | 2004-11-09 | Henrik Grubbström (Grubba) | | string_builder_append_integer(s, pike_va_int(VA_LIST_ADDR(args), flags), 16,
|
6cde65 | 2004-11-08 | Henrik Grubbström (Grubba) | | flags | APPEND_UPPER_CASE,
min_width, precision);
|
e9864c | 2004-11-06 | Henrik Grubbström (Grubba) | | break;
case 'u':
|
46a4ce | 2004-11-09 | Henrik Grubbström (Grubba) | | string_builder_append_integer(s, pike_va_int(VA_LIST_ADDR(args), flags), 10,
|
6cde65 | 2004-11-08 | Henrik Grubbström (Grubba) | | flags, min_width, precision);
|
e9864c | 2004-11-06 | Henrik Grubbström (Grubba) | | break;
case 'd':
|
cc9fcb | 2005-03-09 | Martin Stjernholm | | flags |= APPEND_SIGNED;
|
46a4ce | 2004-11-09 | Henrik Grubbström (Grubba) | | string_builder_append_integer(s, pike_va_int(VA_LIST_ADDR(args), flags), 10,
|
cc9fcb | 2005-03-09 | Martin Stjernholm | | flags, min_width, precision);
|
e9864c | 2004-11-06 | Henrik Grubbström (Grubba) | | break;
|
7b9fd1 | 2004-11-06 | Henrik Grubbström (Grubba) | |
|
686ef2 | 2004-11-11 | Henrik Grubbström (Grubba) | |
|
f74ecc | 2009-11-30 | Arne Goedeke | | case 'a':
case 'e':
case 'E':
|
686ef2 | 2004-11-11 | Henrik Grubbström (Grubba) | | case 'f':
|
f74ecc | 2009-11-30 | Arne Goedeke | | case 'g':
case 'G':
|
686ef2 | 2004-11-11 | Henrik Grubbström (Grubba) | | {
double val = va_arg(args, double);
size_t bytes;
|
f74ecc | 2009-11-30 | Arne Goedeke | | char nfmt[] = { '%', fmt[-1], 0 };
|
686ef2 | 2004-11-11 | Henrik Grubbström (Grubba) | |
if (PIKE_ISNAN(val)) {
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, '+');
}
|
f74ecc | 2009-11-30 | Arne Goedeke | | if ((val+val == val) && (val > 0.0)) {
string_builder_strcat(s, "inf");
|
686ef2 | 2004-11-11 | Henrik Grubbström (Grubba) | | break;
}
|
f74ecc | 2009-11-30 | Arne Goedeke | | if ((bytes = SNPRINTF(NULL, 0, nfmt, val))) {
|
686ef2 | 2004-11-11 | Henrik Grubbström (Grubba) | | p_wchar0 *p = string_builder_allocate(s, bytes, 0);
|
f74ecc | 2009-11-30 | Arne Goedeke | | size_t check = SNPRINTF((char*)p, bytes+1, nfmt, val);
|
686ef2 | 2004-11-11 | Henrik Grubbström (Grubba) | | if (check != bytes) {
|
f74ecc | 2009-11-30 | Arne Goedeke | | Pike_fatal("string_builder_vsprintf(): snprintf(\"%s\", %f) "
"is not trustworthy: "
"%"PRINTSIZET"u != %"PRINTSIZET"u\n",
nfmt, val, bytes, check);
|
686ef2 | 2004-11-11 | Henrik Grubbström (Grubba) | | }
if (s->s->size_shift) {
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;
|
7b9fd1 | 2004-11-06 | Henrik Grubbström (Grubba) | |
|
e9864c | 2004-11-06 | Henrik Grubbström (Grubba) | | default:
Pike_fatal("string_builder_vsprintf(): Invalid formatting method: "
|
f74ecc | 2009-11-30 | Arne Goedeke | | "\"%%%c\" 0x%x.\n", (fmt[-1] & 0xff), fmt[-1]);
|
f619da | 2004-11-05 | Henrik Grubbström (Grubba) | | }
break;
}
} else {
const char *start = fmt;
while (*fmt && (*fmt != '%'))
fmt++;
string_builder_binary_strcat(s, start, fmt-start);
}
}
}
|
46a4ce | 2004-11-09 | Henrik Grubbström (Grubba) | |
|
f619da | 2004-11-05 | Henrik Grubbström (Grubba) | | PMOD_EXPORT void string_builder_sprintf(struct string_builder *s,
const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
string_builder_vsprintf(s, fmt, args);
va_end(args);
}
|
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;
|
cb2e38 | 2001-08-29 | Henrik Grubbström (Grubba) | |
|
e8371e | 2008-06-23 | Martin Stjernholm | | low_set_index (s->s, 0, 0);
|
723806 | 1998-10-11 | Fredrik Hübinette (Hubbe) | | }
|
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) | | {
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | s->s->len = s->malloced;
|
9cd037 | 2005-11-03 | Henrik Grubbström (Grubba) | | free_string(s->s);
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | }
|
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) | | {
|
e464e0 | 2008-06-23 | Martin Stjernholm | | ptrdiff_t len = s->s->len;
if (len != s->malloced) {
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | s->s->len = s->malloced;
s->s = realloc_unlinked_string(s->s, len);
}
|
e464e0 | 2008-06-23 | Martin Stjernholm | | else
low_set_index(s->s,s->s->len,0);
|
6f1871 | 2004-11-14 | Martin Stjernholm | | if(s->known_shift == s->s->size_shift)
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | 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)
{
|
66d928 | 2011-05-01 | Per Hedbor | | case 0: return MKPCHARP(MEMCHR(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) | | }
|
c6b604 | 2008-05-03 | Martin Nilsson | | #ifdef PIKE_DEBUG
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Illegal shift in MEMCHR_PCHARP.\n");
|
c6b604 | 2008-05-03 | Martin Nilsson | | #endif
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | 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) | | {
|
90784a | 2003-02-26 | Martin Stjernholm | |
unsigned long val, mul_limit;
int c;
int xx, neg = 0, add_limit, overflow = 0;
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | |
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) | | {
|
90784a | 2003-02-26 | Martin Stjernholm | | while (WIDE_ISSPACE(c))
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | {
INC_PCHARP(str,1);
c=EXTRACT_PCHARP(str);
}
switch (c)
{
case '-':
neg++;
|
f74ecc | 2009-11-30 | Arne Goedeke | |
case '+':
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | 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);
}
|
90784a | 2003-02-26 | Martin Stjernholm | |
|
a54964 | 2003-03-17 | Henrik Grubbström (Grubba) | | mul_limit = ((unsigned long)LONG_MAX)/base;
add_limit = (int) (LONG_MAX % base);
|
90784a | 2003-02-26 | Martin Stjernholm | | if (neg) {
|
a54964 | 2003-03-17 | Henrik Grubbström (Grubba) | | if (++add_limit == base) {
add_limit = 0;
mul_limit++;
}
|
90784a | 2003-02-26 | Martin Stjernholm | | }
val=DIGIT(c);
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | 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;
|
a54964 | 2003-03-17 | Henrik Grubbström (Grubba) | | if (val > mul_limit || (val == mul_limit && xx > add_limit)) {
|
90784a | 2003-02-26 | Martin Stjernholm | | overflow = 1;
|
a54964 | 2003-03-17 | Henrik Grubbström (Grubba) | | } else
|
90784a | 2003-02-26 | Martin Stjernholm | | val = base * val + xx;
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | }
|
90784a | 2003-02-26 | Martin Stjernholm | |
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | if (ptr) *ptr = str;
|
90784a | 2003-02-26 | Martin Stjernholm | | if (overflow) {
errno = ERANGE;
return neg ? LONG_MIN : LONG_MAX;
}
else {
if (neg)
|
a54964 | 2003-03-17 | Henrik Grubbström (Grubba) | | return (long)(~val + 1);
|
90784a | 2003-02-26 | Martin Stjernholm | | else
return (long) val;
}
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | }
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | |
|
66d928 | 2011-05-01 | Per Hedbor | | |
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;
}
|
66d928 | 2011-05-01 | Per Hedbor | | */
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | |
|
66d928 | 2011-05-01 | Per Hedbor | | int wide_string_to_svalue_inumber(struct svalue *r,
|
8c37d1 | 2000-08-15 | Henrik Grubbström (Grubba) | | void * str,
|
f4778d | 2003-07-30 | Martin Stjernholm | | void *ptr,
|
8c37d1 | 2000-08-15 | Henrik Grubbström (Grubba) | | int base,
ptrdiff_t maxlength,
int shift)
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | {
PCHARP tmp;
int ret=pcharp_to_svalue_inumber(r,
MKPCHARP(str,shift),
&tmp,
base,
maxlength);
|
f4778d | 2003-07-30 | Martin Stjernholm | | if(ptr) *(p_wchar0 **)ptr=tmp.ptr;
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | return ret;
}
|
15f63a | 2008-07-23 | Martin Stjernholm | | int safe_wide_string_to_svalue_inumber(struct svalue *r,
void * str,
void *ptr,
int base,
ptrdiff_t maxlength,
int shift)
{
PCHARP tmp;
JMP_BUF recovery;
int ret = 0;
free_svalue (&throw_value);
mark_free_svalue (&throw_value);
if (SETJMP (recovery)) {
call_handle_error();
ret = 0;
}
else
ret = pcharp_to_svalue_inumber(r,
MKPCHARP(str,shift),
&tmp,
base,
maxlength);
UNSETJMP (recovery);
if(ptr) *(p_wchar0 **)ptr=tmp.ptr;
return ret;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int pcharp_to_svalue_inumber(struct svalue *r,
|
8c37d1 | 2000-08-15 | Henrik Grubbström (Grubba) | | PCHARP str,
PCHARP *ptr,
int base,
ptrdiff_t maxlength)
|
31ea27 | 1999-10-22 | Fredrik Noring | | {
|
90784a | 2003-02-26 | Martin Stjernholm | |
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | PCHARP str_start;
|
31ea27 | 1999-10-22 | Fredrik Noring | |
|
90784a | 2003-02-26 | Martin Stjernholm | | unsigned INT_TYPE val, mul_limit;
int c;
int xx, neg = 0, add_limit, overflow = 0;
|
31ea27 | 1999-10-22 | Fredrik Noring | |
maxlength--;
str_start = str;
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | SET_SVAL(*r, T_INT, NUMBER_NUMBER, integer, 0);
|
31ea27 | 1999-10-22 | Fredrik Noring | | 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)
{
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;
|
573983 | 2013-08-02 | Arne Goedeke | |
if(c == '0' &&
|
565645 | 1999-10-26 | Fredrik Noring | | ((base==16 && (INDEX_PCHARP(str,1)=='x' || INDEX_PCHARP(str,1)=='X')) ||
|
573983 | 2013-08-02 | Arne Goedeke | | (base==2 && (INDEX_PCHARP(str,1)=='b' || INDEX_PCHARP(str,1)=='B'))) &&
INDEX_PCHARP(str,2) < 256 &&
isxdigit(INDEX_PCHARP(str,2)))
|
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);
}
|
29406f | 2001-06-05 | Fredrik Hübinette (Hubbe) | | str_start=str;
|
90784a | 2003-02-26 | Martin Stjernholm | |
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);
}
|
31ea27 | 1999-10-22 | Fredrik Noring | |
|
90784a | 2003-02-26 | Martin Stjernholm | | 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 | | {
|
90784a | 2003-02-26 | Martin Stjernholm | | if (val > mul_limit || (val == mul_limit && xx > add_limit))
overflow = 1;
else
val = base * val + xx;
|
31ea27 | 1999-10-22 | Fredrik Noring | | }
if(ptr != 0)
*ptr = str;
|
90784a | 2003-02-26 | Martin Stjernholm | | if (overflow) {
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | push_string(make_shared_binary_pcharp(str_start,
SUBTRACT_PCHARP(str,str_start)));
|
90784a | 2003-02-26 | Martin Stjernholm | | |
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | * in some situations that might not be desirable...
* take care.
* /Hubbe
|
29406f | 2001-06-05 | Fredrik Hübinette (Hubbe) | | *
* It could probably also be faster...
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | */
|
29406f | 2001-06-05 | Fredrik Hübinette (Hubbe) | | push_int(base);
convert_stack_top_with_base_to_bignum();
if(neg) o_negate();
|
31ea27 | 1999-10-22 | Fredrik Noring | |
|
9b150a | 2002-05-11 | Martin Nilsson | | *r = *--Pike_sp;
|
90784a | 2003-02-26 | Martin Stjernholm | | dmalloc_touch_svalue (r);
|
31ea27 | 1999-10-22 | Fredrik Noring | | }
|
90784a | 2003-02-26 | Martin Stjernholm | | 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;
}
|
31ea27 | 1999-10-22 | Fredrik Noring | | 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 | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(Pike_sp[-1]) != T_STRING)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Cannot convert stack top to integer number.\n");
|
31ea27 | 1999-10-22 | Fredrik Noring | |
|
9b150a | 2002-05-11 | Martin Nilsson | | i=pcharp_to_svalue_inumber(&r, MKPCHARP_STR(Pike_sp[-1].u.string), 0, base, 0);
|
31ea27 | 1999-10-22 | Fredrik Noring | |
|
9b150a | 2002-05-11 | Martin Nilsson | | free_string(Pike_sp[-1].u.string);
Pike_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) | | {
|
71d7d5 | 2003-02-26 | Martin Stjernholm | |
|
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)
{
|
7ad412 | 2003-10-03 | Henrik Grubbström (Grubba) | |
p_wchar2 c;
while(WIDE_ISSPACE(c = EXTRACT_PCHARP(s))) {
INC_PCHARP(s, 1);
}
|
f3ece8 | 1999-02-28 | Fredrik Hübinette (Hubbe) | | if (endptr != NULL)
*endptr = end;
|
7ad412 | 2003-10-03 | Henrik Grubbström (Grubba) | | if (c == '-')
|
f3ece8 | 1999-02-28 | Fredrik Hübinette (Hubbe) | | 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:
|
a4a172 | 2000-12-05 | Per Hedbor | |
|
f3ece8 | 1999-02-28 | Fredrik Hübinette (Hubbe) | | errno = ERANGE;
|
90784a | 2003-02-26 | Martin Stjernholm | | return HUGE_VAL * sign;
|
f3ece8 | 1999-02-28 | Fredrik Hübinette (Hubbe) | |
underflow:
|
a4a172 | 2000-12-05 | Per Hedbor | |
|
71d7d5 | 2003-02-26 | Martin Stjernholm | | #if 0
|
f3ece8 | 1999-02-28 | Fredrik Hübinette (Hubbe) | | if (endptr != NULL)
*endptr = nptr;
|
71d7d5 | 2003-02-26 | Martin Stjernholm | | #endif
|
f3ece8 | 1999-02-28 | Fredrik Hübinette (Hubbe) | | 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;
|
c6b604 | 2008-05-03 | Martin Nilsson | | #ifdef PIKE_DEBUG
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | default:
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Illegal shift size in string.\n");
|
c6b604 | 2008-05-03 | Martin Nilsson | | #endif
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | }
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;
|
c6b604 | 2008-05-03 | Martin Nilsson | | #ifdef PIKE_DEBUG
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | default:
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Illegal shift size in string.\n");
|
c6b604 | 2008-05-03 | Martin Nilsson | | #endif
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | }
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);
|
c6b604 | 2008-05-03 | Martin Nilsson | | #ifdef PIKE_DEBUG
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | default:
|
5aad93 | 2002-08-15 | Marcus Comstedt | | Pike_fatal("Illegal shift size in string.\n");
|
c6b604 | 2008-05-03 | Martin Nilsson | | #endif
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | }
return 0;
}
|