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"
|
2d10fb | 2016-12-29 | Arne Goedeke | | #include "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"
|
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"
|
97bfe2 | 2015-10-11 | Henrik Grubbström (Grubba) | | #include "pike_types.h"
|
d47659 | 2013-06-12 | Arne Goedeke | | #include "block_allocator.h"
|
c05454 | 2016-12-17 | Martin Nilsson | | #include "whitespace.h"
|
5f9006 | 2017-01-10 | Martin Nilsson | | #include "stuff.h"
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
f3ece8 | 1999-02-28 | Fredrik Hübinette (Hubbe) | | #include <errno.h>
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | |
|
ddad7a | 2014-10-20 | Martin Nilsson | | #define SET_HSIZE(X) htable_mask=(htable_size=(X))-1
|
e85df8 | 2001-09-06 | Fredrik Hübinette (Hubbe) | | #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) | |
|
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;
|
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 )
{
|
f1298d | 2014-07-02 | Arne Goedeke | | switch (str->size_shift) {
case eightbit:
s_min = str->min;
s_max = str->max;
break;
case sixteenbit:
s_min = str->min;
s_max = str->max;
s_min *= 256;
s_max *= 256;
s_max += 255;
break;
case thirtytwobit: {
unsigned INT32 tmp;
tmp = str->min;
tmp *= (1 << 24);
s_min = tmp;
tmp = str->max;
tmp *= (1 << 24);
tmp += (1 << 24) - 1;
s_max = tmp;
break;
}
|
992551 | 2013-05-31 | Per Hedbor | | }
}
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;
}
}
|
f1298d | 2014-07-02 | Arne Goedeke | | str->min = s_min / 256;
str->max = s_max / 256;
|
992551 | 2013-05-31 | Per Hedbor | | 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;
}
}
|
f1298d | 2014-07-02 | Arne Goedeke | | str->min = (unsigned INT32)s_min / (1 << 24);
str->max = (unsigned INT32)s_max / (1 << 24);
|
992551 | 2013-05-31 | Per Hedbor | | break;
}
}
if( min ) *min = s_min;
if( max ) *max = s_max;
}
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
|
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;
|
13670c | 2015-05-25 | Martin Nilsson | | else
|
ed2bed | 2013-06-14 | Per Hedbor | | STR2(s)[pos]=value;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | }
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
ed0414 | 2015-09-27 | Per Hedbor | | PMOD_EXPORT struct pike_string *debug_check_size_shift(const struct pike_string *a, enum size_shift 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");
|
cae4ab | 2014-09-04 | Stephen R. van den Berg | | return (struct pike_string*)a;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | }
#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 | | }
|
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)
|
bd6739 | 2015-10-14 | Martin Nilsson | | Pike_fatal("Cannot copy %ld bytes!\n", (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];
}
|
759c42 | 2015-10-17 | Martin Nilsson | | UNREACHABLE(return 0);
|
e9117b | 2014-02-25 | Per Hedbor | | }
|
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) | | {
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | for(s=base_table[e];s;s=s->next)
|
9e5238 | 1998-03-01 | Fredrik Hübinette (Hubbe) | | {
if(isproblem(s))
{
fprintf(stderr,"***Guilty string:\n");
debug_dump_pike_string(s, 70);
DM(add_marks_to_memhdr(yes,s));
}else{
DM(add_marks_to_memhdr(no,s));
}
}
}
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | |
|
9e5238 | 1998-03-01 | Fredrik Hübinette (Hubbe) | | DM(fprintf(stderr,"Plausible problem location(s):\n"));
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | DM(dump_memhdr_locations(yes,0,0));
|
9e5238 | 1998-03-01 | Fredrik Hübinette (Hubbe) | |
DM(fprintf(stderr,"More Plausible problem location(s):\n"));
|
a4033e | 2000-04-14 | Fredrik Hübinette (Hubbe) | | DM(dump_memhdr_locations(yes,no,0));
|
2043ba | 1998-02-10 | Fredrik Hübinette (Hubbe) | | }
|
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) | | |
13670c | 2015-05-25 | Martin Nilsson | | * This assumes that the string is minimized!!!!
|
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,
|
ed0414 | 2015-09-27 | Per Hedbor | | enum size_shift size_shift,
|
a9b817 | 2014-04-05 | Martin Nilsson | | 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;
|
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 ||
|
67074e | 2014-09-03 | Martin Nilsson | | !memcmp(curr->str, s,len<<size_shift)))
|
ed0414 | 2015-09-27 | Per Hedbor | | 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) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return 0;
}
|
9506a1 | 2016-08-20 | Martin Nilsson | |
struct pike_string *binary_findstring(const char *str, ptrdiff_t len)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
9506a1 | 2016-08-20 | Martin Nilsson | | return internal_findstring(str, len, 0, StrHash(str,len));
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
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));
}
|
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;
|
ddad7a | 2014-10-20 | Martin Nilsson | | SET_HSIZE(htable_size<<1);
|
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);
|
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) | |
|
60e6cf | 2013-11-09 | Arne Goedeke | | #define STRING_BLOCK 2048
|
8f0b9a | 2014-06-19 | Per Hedbor | |
|
ed0414 | 2015-09-27 | Per Hedbor | | static struct block_allocator string_allocator =
|
5d2319 | 2015-12-10 | Per Hedbor | | BA_INIT_PAGES(sizeof(struct pike_string), 2);
|
ed0414 | 2015-09-27 | Per Hedbor | | static struct block_allocator substring_allocator =
|
5d2319 | 2015-12-10 | Per Hedbor | | BA_INIT_PAGES(sizeof(struct substring_pike_string), 1);
|
358724 | 2015-08-22 | Per Hedbor | |
|
ed0414 | 2015-09-27 | Per Hedbor | | static void free_string_content(struct pike_string * s)
{
switch (s->alloc_type)
{
case STRING_ALLOC_STATIC:
break;
case STRING_ALLOC_MALLOC:
free(s->str);
break;
case STRING_ALLOC_BA:
ba_free(&string_allocator, s->str);
break;
case STRING_ALLOC_SUBSTRING:
free_string(((struct substring_pike_string*)s)->parent);
break;
}
}
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | |
|
358724 | 2015-08-22 | Per Hedbor | | static void free_unlinked_pike_string(struct pike_string * s)
{
|
ed0414 | 2015-09-27 | Per Hedbor | | free_string_content(s);
switch(s->struct_type)
{
case STRING_STRUCT_STRING:
ba_free(&string_allocator, s);
break;
case STRING_STRUCT_SUBSTRING:
ba_free(&substring_allocator, s);
break;
}
|
60e6cf | 2013-11-09 | Arne Goedeke | | }
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | |
|
ed0414 | 2015-09-27 | Per Hedbor | |
|
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) | | {
|
60e6cf | 2013-11-09 | Arne Goedeke | | return debug_begin_wide_shared_string(len, 0);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
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
|
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) | |
|
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;
}
|
557f74 | 2014-05-23 | Per Hedbor | | if (need_more_hash_prefix_depth > 4)
|
8282ca | 2013-11-02 | Per Hedbor | | hash_prefix_len=hash_prefix_len*2;
|
557f74 | 2014-05-23 | Per Hedbor | |
|
0169c6 | 2011-12-30 | Henrik Grubbström (Grubba) | | |
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;
}
}
}
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | }
|
ed0414 | 2015-09-27 | Per Hedbor | | PMOD_EXPORT struct pike_string *debug_begin_wide_shared_string(size_t len, enum size_shift shift)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
|
4170b9 | 2004-11-06 | Henrik Grubbström (Grubba) | | struct pike_string *t = NULL;
|
1b4205 | 2015-11-23 | Arne Goedeke | | size_t bytes;
|
23bdcd | 2015-08-22 | Per Hedbor | | ONERROR fe;
|
1b4205 | 2015-11-23 | Arne Goedeke | |
if ((ptrdiff_t)len < 0 || DO_SIZE_T_ADD_OVERFLOW(len, 1, &bytes) ||
DO_SIZE_T_MUL_OVERFLOW(bytes, 1 << shift, &bytes)) {
Pike_error("String is too large.\n");
}
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | if(d_flag>10)
verify_shared_strings_tables();
#endif
|
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 */
|
ed0414 | 2015-09-27 | Per Hedbor | | t=ba_alloc(&string_allocator);
|
23bdcd | 2015-08-22 | Per Hedbor | | |
119e1e | 2014-08-22 | Arne Goedeke | | */
|
358724 | 2015-08-22 | Per Hedbor | | t->flags = STRING_NOT_HASHED|STRING_NOT_SHARED;
t->alloc_type = STRING_ALLOC_STATIC;
|
ed0414 | 2015-09-27 | Per Hedbor | | t->struct_type = STRING_STRUCT_STRING;
|
23bdcd | 2015-08-22 | Per Hedbor | | SET_ONERROR(fe,free_unlinked_pike_string,t);
if (bytes <= sizeof(struct pike_string))
{
|
119e1e | 2014-08-22 | Arne Goedeke | | t->str = ba_alloc(&string_allocator);
|
358724 | 2015-08-22 | Per Hedbor | | t->alloc_type = STRING_ALLOC_BA;
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | } else {
|
23bdcd | 2015-08-22 | Per Hedbor | | t->str = xalloc(bytes);
|
358724 | 2015-08-22 | Per Hedbor | | t->alloc_type = STRING_ALLOC_MALLOC;
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | | }
|
dc245f | 2011-07-21 | Henrik Grubbström (Grubba) | | t->refs = 0;
|
a495ca | 2014-08-23 | Arne Goedeke | | t->size_shift=shift;
|
dc245f | 2011-07-21 | Henrik Grubbström (Grubba) | | add_ref(t);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | t->len=len;
|
0e602a | 2006-01-12 | Henrik Grubbström (Grubba) | | DO_IF_DEBUG(t->next = NULL);
|
516615 | 2015-08-22 | Per Hedbor | | UNSET_ONERROR(fe);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | low_set_index(t,len,0);
return t;
}
|
23bdcd | 2015-08-22 | Per Hedbor | | static struct pike_string * make_static_string(const char * str, size_t len,
enum size_shift shift)
{
|
119e1e | 2014-08-22 | Arne Goedeke | | struct pike_string * t = ba_alloc(&string_allocator);
|
358724 | 2015-08-22 | Per Hedbor | | t->flags = STRING_NOT_HASHED|STRING_NOT_SHARED;
|
ed0414 | 2015-09-27 | Per Hedbor | | t->size_shift = shift;
|
358724 | 2015-08-22 | Per Hedbor | | t->alloc_type = STRING_ALLOC_STATIC;
|
ed0414 | 2015-09-27 | Per Hedbor | | t->struct_type = STRING_STRUCT_STRING;
|
516615 | 2015-08-22 | Per Hedbor | | t->str = (char *)str;
|
119e1e | 2014-08-22 | Arne Goedeke | | t->refs = 0;
t->len = len;
|
ed0414 | 2015-09-27 | Per Hedbor | | add_ref(t);
|
119e1e | 2014-08-22 | Arne Goedeke | |
return t;
}
PMOD_EXPORT struct pike_string * make_shared_static_string(const char *str, size_t len,
enum size_shift shift)
{
struct pike_string *s;
ptrdiff_t h = StrHash(str, len);
s = internal_findstring(str,len,shift,h);
if (!s) {
s = make_static_string(str, len, shift);
link_pike_string(s, h);
} else {
|
ed0414 | 2015-09-27 | Per Hedbor | | if (!string_is_static(s))
{
free_string_content(s);
s->alloc_type = STRING_ALLOC_STATIC;
s->str = (char*)str;
|
7ed4d8 | 2014-08-24 | Arne Goedeke | | }
|
119e1e | 2014-08-22 | Arne Goedeke | | add_ref(s);
}
return s;
}
|
36bfbf | 2016-11-08 | Arne Goedeke | | PMOD_EXPORT struct pike_string * make_shared_malloc_string(char *str, size_t len,
enum size_shift shift)
{
struct pike_string *s;
ptrdiff_t h = StrHash(str, len);
s = internal_findstring(str,len,shift,h);
if (!s) {
s = ba_alloc(&string_allocator);
s->flags = STRING_NOT_HASHED|STRING_NOT_SHARED;
s->size_shift = shift;
s->alloc_type = STRING_ALLOC_MALLOC;
s->struct_type = STRING_STRUCT_STRING;
s->str = str;
s->refs = 0;
s->len = len;
add_ref(s);
link_pike_string(s, h);
} else {
free(str);
add_ref(s);
}
return s;
}
|
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:
|
ed0414 | 2015-09-27 | Per Hedbor | | break;
|
e8371e | 2008-06-23 | Martin Stjernholm | |
case 1:
|
ed0414 | 2015-09-27 | Per Hedbor | | if(!find_magnitude1(STR1(s),s->len))
Pike_fatal ("String %p that should have shift 1 really got 0.\n", s);
break;
|
e8371e | 2008-06-23 | Martin Stjernholm | |
case 2: {
|
ed0414 | 2015-09-27 | Per Hedbor | | 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;
|
e8371e | 2008-06-23 | Martin Stjernholm | | }
default:
|
ed0414 | 2015-09-27 | Per Hedbor | | Pike_fatal("ARGHEL! size_shift:%d\n", s->size_shift);
|
e8371e | 2008-06-23 | Martin Stjernholm | | }
}
#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
|
13670c | 2015-05-25 | Martin Nilsson | | 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;
|
23bdcd | 2015-08-22 | Per Hedbor | | switch(UNLIKELY(s->size_shift))
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
case 2:
switch(find_magnitude2(STR2(s),s->len))
{
|
ed0414 | 2015-09-27 | Per Hedbor | | case 0:
s2=begin_shared_string(s->len);
convert_2_to_0(STR0(s2),STR2(s),s->len);
free_string(s);
s=s2;
break;
case 1:
s2=begin_wide_shared_string(s->len,1);
convert_2_to_1(STR1(s2),STR2(s),s->len);
free_string(s);
s=s2;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | }
break;
|
992551 | 2013-05-31 | Per Hedbor | |
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | case 1:
if(!find_magnitude1(STR1(s),s->len))
{
|
ed0414 | 2015-09-27 | Per Hedbor | | s2=begin_shared_string(s->len);
convert_1_to_0(STR0(s2),STR1(s),s->len);
free_string(s);
s=s2;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | }
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
|
9bb0ef | 2016-01-18 | Henrik Grubbström (Grubba) | | if (len == str->len) {
return end_shared_string(str);
}
|
d5b1e2 | 2000-11-29 | Fredrik Hübinette (Hubbe) | | 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;
}
|
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);
|
13670c | 2015-05-25 | Martin Nilsson | | if (!s)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
s=begin_shared_string(len);
|
59fc9e | 2014-09-03 | Martin Nilsson | | 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);
}
|
9282fd | 2015-09-27 | Martin Nilsson | | UNREACHABLE(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);
|
13670c | 2015-05-25 | Martin Nilsson | | if (!s)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
s=begin_wide_shared_string(len,1);
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(s->str, str, len<<1);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | 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);
|
13670c | 2015-05-25 | Martin Nilsson | | if (!s)
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | {
s=begin_wide_shared_string(len,2);
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(s->str, str, len<<2);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | 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) | |
|
2a3bfa | 2017-01-26 | Henrik Grubbström (Grubba) | | void unlink_pike_string(struct pike_string *s)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
ed0414 | 2015-09-27 | Per Hedbor | | size_t h=HMODULO(s->hval);
struct pike_string *tmp=base_table[h], *p=NULL;
|
23bdcd | 2015-08-22 | Per Hedbor | |
while( tmp )
{
if( tmp == s )
{
if( p )
p->next = s->next;
else
base_table[h] = s->next;
break;
}
p = tmp;
tmp = tmp->next;
|
4bdf5f | 2001-03-30 | Henrik Grubbström (Grubba) | | }
|
516615 | 2015-08-22 | Per Hedbor | |
|
23bdcd | 2015-08-22 | Per Hedbor | | if( !tmp )
Pike_fatal("unlink on non-shared string\n");
|
516615 | 2015-08-22 | Per Hedbor | |
|
89fc4c | 2000-08-10 | Henrik Grubbström (Grubba) | | s->next=(struct pike_string *)(ptrdiff_t)-1;
|
760b26 | 1996-12-03 | Fredrik Hübinette (Hubbe) | | num_strings--;
|
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
|
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",
|
ed0414 | 2015-09-27 | Per Hedbor | | s->size_shift);
|
c7eadf | 2001-03-29 | Henrik Grubbström (Grubba) | | }
|
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) | | }
|
ed0414 | 2015-09-27 | Per Hedbor | |
|
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);
}
|
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) | | {
for(p=base_table[e];p;p=p->next)
{
|
ed0414 | 2015-09-27 | Per Hedbor | | int key = p->size_shift + (string_is_malloced(p)?4:0);
num_distinct_strings[key]++;
|
119e1e | 2014-08-22 | Arne Goedeke | | alloced_bytes[key] += p->refs*sizeof(struct pike_string);
|
ed0414 | 2015-09-27 | Per Hedbor | | alloced_strings[key] += p->refs;
|
119e1e | 2014-08-22 | Arne Goedeke | | if (string_is_block_allocated(p)) {
|
ca7685 | 2014-08-18 | Arne Goedeke | | alloced_bytes[key] +=
|
119e1e | 2014-08-22 | Arne Goedeke | | p->refs*sizeof(struct pike_string);
|
ca7685 | 2014-08-18 | Arne Goedeke | | } else {
|
119e1e | 2014-08-22 | Arne Goedeke | | alloced_bytes[key] +=
p->refs*DO_ALIGN((p->len+3) << p->size_shift,sizeof(void *));
|
ca7685 | 2014-08-18 | Arne Goedeke | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
af8026 | 2013-02-07 | Henrik Grubbström (Grubba) | | string_builder_sprintf(&s,
|
ed0414 | 2015-09-27 | Per Hedbor | | "\nShared string hash table:\n"
"-------------------------\n"
"\n"
"Type Count Distinct Bytes Actual Overhead %%\n"
"------------------------------------------------------------\n");
|
af8026 | 2013-02-07 | Henrik Grubbström (Grubba) | | for(e = 0; e < 8; e++) {
int shift = e & 3;
ptrdiff_t overhead;
if (!num_distinct_strings[e]) continue;
if (shift != 3) {
|
ed0414 | 2015-09-27 | Per Hedbor | | if (e < 4) {
string_builder_sprintf(&s, "Short/%-2d ", 8<<shift);
} else {
string_builder_sprintf(&s, "Long/%-2d ", 8<<shift);
}
|
af8026 | 2013-02-07 | Henrik Grubbström (Grubba) | |
|
ed0414 | 2015-09-27 | Per Hedbor | | overhead_bytes[e] =
|
bd6739 | 2015-10-14 | Martin Nilsson | | (long)sizeof(struct pike_string) * num_distinct_strings[e];
|
af8026 | 2013-02-07 | Henrik Grubbström (Grubba) | |
|
ed0414 | 2015-09-27 | Per Hedbor | | 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];
|
af8026 | 2013-02-07 | Henrik Grubbström (Grubba) | | } else {
|
ed0414 | 2015-09-27 | Per Hedbor | | if (e < 4) {
string_builder_sprintf(&s, "Total short");
} else {
string_builder_sprintf(&s, "Total long ");
}
|
af8026 | 2013-02-07 | Henrik Grubbström (Grubba) | | }
string_builder_sprintf(&s,
|
ed0414 | 2015-09-27 | Per Hedbor | | "%8ld %8ld %8ld %8ld %8ld ",
alloced_strings[e], num_distinct_strings[e],
alloced_bytes[e], bytes_distinct_strings[e],
overhead_bytes[e]);
|
af8026 | 2013-02-07 | Henrik Grubbström (Grubba) | | if (alloced_bytes[e]) {
|
ed0414 | 2015-09-27 | Per Hedbor | | string_builder_sprintf(&s, "%4d\n",
(bytes_distinct_strings[e] +
overhead_bytes[e]) * 100 /
alloced_bytes[e]);
|
af8026 | 2013-02-07 | Henrik Grubbström (Grubba) | | } else {
|
ed0414 | 2015-09-27 | Per Hedbor | | string_builder_strcat(&s, " -\n");
|
af8026 | 2013-02-07 | Henrik Grubbström (Grubba) | | }
}
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,
|
ed0414 | 2015-09-27 | Per Hedbor | | "------------------------------------------------------------\n"
"Total %8ld %8ld %8ld %8ld %8ld ",
alloced_strings[7], num_distinct_strings[7],
alloced_bytes[7], bytes_distinct_strings[7],
overhead_bytes[7]);
|
af8026 | 2013-02-07 | Henrik Grubbström (Grubba) | | if (alloced_bytes[7]) {
string_builder_sprintf(&s, "%4d\n",
|
ed0414 | 2015-09-27 | Per Hedbor | | (bytes_distinct_strings[7] +
overhead_bytes[7]) * 100 /
alloced_bytes[7]);
|
af8026 | 2013-02-07 | Henrik Grubbström (Grubba) | | } 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) | | {
|
33e873 | 2015-12-25 | Henrik Grubbström (Grubba) | | 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:
|
ed0414 | 2015-09-27 | Per Hedbor | | break;
|
abdf6b | 2005-04-02 | Martin Stjernholm | | case 1: {
|
ed0414 | 2015-09-27 | Per Hedbor | | 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");
|
abdf6b | 2005-04-02 | Martin Stjernholm | | }
case 2: {
|
ed0414 | 2015-09-27 | Per Hedbor | | ptrdiff_t i;
p_wchar2 *str = STR2 (s);
for (i = 0; i < s->len; i++)
if ((str[i] > 0xffff) || (str[i] < 0))
goto size_shift_check_done;
Pike_fatal ("Shared string is too wide.\n");
|
abdf6b | 2005-04-02 | Martin Stjernholm | | }
default:
|
ed0414 | 2015-09-27 | Per Hedbor | | Pike_fatal ("Invalid size shift %d.\n", s->size_shift);
|
abdf6b | 2005-04-02 | Martin Stjernholm | | }
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 | |
|
33e873 | 2015-12-25 | Henrik Grubbström (Grubba) | | 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;
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)) {
|
ed0414 | 2015-09-27 | Per Hedbor | | 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)
|
ed0414 | 2015-09-27 | Per Hedbor | | 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) | | {
|
ed0414 | 2015-09-27 | Per Hedbor | | locate_problem(has_zero_refs);
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) | | {
|
ed0414 | 2015-09-27 | Per Hedbor | | locate_problem(improper_zero_termination);
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) | | {
|
ed0414 | 2015-09-27 | Per Hedbor | | locate_problem(wrong_hash);
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) | | {
|
ed0414 | 2015-09-27 | Per Hedbor | | locate_problem(wrong_hash);
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)
{
|
ed0414 | 2015-09-27 | Per Hedbor | | struct pike_string *s2;
for(s2=s;s2;s2=s2->next)
if(s2 == s)
Pike_fatal("Shared string table is cyclic.\n");
h=0;
|
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) | | }
|
33e873 | 2015-12-25 | Henrik Grubbström (Grubba) | |
const struct pike_string *debug_findstring(const struct pike_string *s)
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | | {
|
2f782f | 2015-12-17 | Henrik Grubbström (Grubba) | | size_t h;
struct pike_string *p;
|
3ebcf2 | 2015-12-22 | Henrik Grubbström (Grubba) | | if(!base_table) return NULL;
h = HMODULO(s->hval);
|
2f782f | 2015-12-17 | Henrik Grubbström (Grubba) | | for(p=base_table[h];p;p=p->next)
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | | {
|
3ebcf2 | 2015-12-22 | Henrik Grubbström (Grubba) | | if(p==s)
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | {
|
3ebcf2 | 2015-12-22 | Henrik Grubbström (Grubba) | | return s;
}
}
return NULL;
}
int safe_debug_findstring(const struct pike_string *foo)
{
unsigned INT32 e;
if(!base_table) return 0;
for(e=0;e<htable_size;e++)
{
struct pike_string *p;
for(p=base_table[e];p;p=p->next)
{
if(p==foo)
{
return 1;
}
|
e1939c | 2001-03-30 | Fredrik Hübinette (Hubbe) | | }
|
62971d | 1998-01-19 | Fredrik Hübinette (Hubbe) | | }
return 0;
}
|
fa7ecb | 2014-12-08 | Martin Nilsson | | PMOD_EXPORT void debug_dump_pike_string(const 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",
|
ed0414 | 2015-09-27 | Per Hedbor | | s,
(long)s->refs,
|
bd6739 | 2015-10-14 | Martin Nilsson | | (long)s->len,
|
ed0414 | 2015-09-27 | Per Hedbor | | s->size_shift,
|
bd6739 | 2015-10-14 | Martin Nilsson | | (unsigned long)s->hval,
(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:
|
1a6b47 | 2017-01-10 | Martin Nilsson | | if(isprint(c))
|
ed0414 | 2015-09-27 | Per Hedbor | | {
putc(c,stderr);
max--;
}else{
fprintf(stderr,"\\%03o",c);
max-=4;
}
|
38d608 | 1998-02-07 | Fredrik Hübinette (Hubbe) | | }
}
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) | | {
|
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) | | }
|
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,
|
ed0414 | 2015-09-27 | Per Hedbor | | const char *b, ptrdiff_t blen)
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | {
int tmp;
if(alen > blen)
{
|
67074e | 2014-09-03 | Martin Nilsson | | tmp=memcmp(a, b, blen);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | if(tmp) return tmp;
return 1;
}else if(alen < blen){
|
67074e | 2014-09-03 | Martin Nilsson | | tmp=memcmp(a, b, alen);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | if(tmp) return tmp;
return -1;
}else{
|
67074e | 2014-09-03 | Martin Nilsson | | return memcmp(a, b, alen);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | }
}
|
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,
|
d8e02f | 2014-09-03 | Martin Nilsson | | ptrdiff_t alen, int asize,
const char *b,
ptrdiff_t blen, int bsize)
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | {
|
0f0bf9 | 2014-09-04 | Martin Nilsson | | ptrdiff_t pos;
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | if(!asize && !bsize)
|
d8e02f | 2014-09-03 | Martin Nilsson | | return low_quick_binary_strcmp(a, alen, b, blen);
for(pos=0;pos< MINIMUM(alen,blen) ;pos++)
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | {
|
d8e02f | 2014-09-03 | Martin Nilsson | | p_wchar2 ac=generic_extract(a,asize,pos);
p_wchar2 bc=generic_extract(b,bsize,pos);
if(ac != bc) {
if (ac < bc) return -1;
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | return 1;
}
}
|
d8e02f | 2014-09-03 | Martin Nilsson | | return alen-blen;
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | }
|
d7cc37 | 2006-03-10 | Henrik Grubbström (Grubba) | |
|
66d928 | 2011-05-01 | Per Hedbor | | ptrdiff_t generic_find_binary_prefix(const char *a,
|
fa7ecb | 2014-12-08 | Martin Nilsson | | ptrdiff_t alen, int asize,
const char *b,
ptrdiff_t blen, int bsize)
|
d7cc37 | 2006-03-10 | Henrik Grubbström (Grubba) | | {
ptrdiff_t pos;
ptrdiff_t len = MINIMUM(alen, blen);
switch(TWO_SIZES(asize, bsize)) {
|
ed0414 | 2015-09-27 | Per Hedbor | | #define CASE(AZ, BZ) \
case TWO_SIZES(AZ, BZ): { \
PIKE_CONCAT(p_wchar, AZ) *a_arr = \
(PIKE_CONCAT(p_wchar, AZ) *)a; \
PIKE_CONCAT(p_wchar, BZ) *b_arr = \
(PIKE_CONCAT(p_wchar, BZ) *)b; \
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; \
} \
|
d7cc37 | 2006-03-10 | Henrik Grubbström (Grubba) | | } 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;
}
|
fa7ecb | 2014-12-08 | Martin Nilsson | | PMOD_EXPORT int c_compare_string(const struct pike_string *s,
const char *foo, int len)
|
a5787d | 1999-03-03 | Fredrik Hübinette (Hubbe) | | {
|
67074e | 2014-09-03 | Martin Nilsson | | return s->len == len && s->size_shift == 0 && !memcmp(s->str,foo,len);
|
a5787d | 1999-03-03 | Fredrik Hübinette (Hubbe) | | }
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | |
|
fa7ecb | 2014-12-08 | Martin Nilsson | | PMOD_EXPORT ptrdiff_t my_quick_strcmp(const struct pike_string *a,
|
ed0414 | 2015-09-27 | Per Hedbor | | const 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,
|
ed0414 | 2015-09-27 | Per Hedbor | | b->str, b->len, b->size_shift);
|
af9321 | 1996-10-12 | Fredrik Hübinette (Hubbe) | | }
|
ed0414 | 2015-09-27 | Per Hedbor | |
|
5de269 | 2012-05-28 | Martin Stjernholm | | struct pike_string *realloc_unlinked_string(struct pike_string *a,
|
ed0414 | 2015-09-27 | Per Hedbor | | ptrdiff_t size)
|
8d28be | 1997-02-10 | Fredrik Hübinette (Hubbe) | | {
|
60e6cf | 2013-11-09 | Arne Goedeke | | char * s = NULL;
size_t nbytes = (size_t)(size+1) << a->size_shift;
|
b3ec73 | 2016-01-09 | Martin Nilsson | | size_t obytes = (size_t)a->len << a->size_shift;
|
4a5e3f | 2000-11-25 | Henrik Grubbström (Grubba) | |
|
ed0414 | 2015-09-27 | Per Hedbor | | if( size < a->len && size-a->len<(signed)sizeof(void*) )
goto done;
|
358724 | 2015-08-22 | Per Hedbor | |
|
ed0414 | 2015-09-27 | Per Hedbor | | if( nbytes < sizeof(struct pike_string) )
|
ced191 | 2015-08-18 | Per Hedbor | | {
|
ed0414 | 2015-09-27 | Per Hedbor | | if( a->alloc_type == STRING_ALLOC_BA )
|
60e6cf | 2013-11-09 | Arne Goedeke | | goto done;
|
ed0414 | 2015-09-27 | Per Hedbor | | s = ba_alloc(&string_allocator);
|
a5b961 | 2016-01-09 | Martin Nilsson | | memcpy(s, a->str, MINIMUM(nbytes,obytes));
|
ed0414 | 2015-09-27 | Per Hedbor | | free_string_content(a);
a->alloc_type = STRING_ALLOC_BA;
}
else if( a->alloc_type == STRING_ALLOC_MALLOC)
{
s = xrealloc(a->str,nbytes);
}
else
{
s = xalloc(nbytes);
memcpy(s,a->str,MINIMUM(nbytes,obytes));
free_string_content(a);
a->alloc_type = STRING_ALLOC_MALLOC;
|
8d28be | 1997-02-10 | Fredrik Hübinette (Hubbe) | | }
|
60e6cf | 2013-11-09 | Arne Goedeke | | a->str = s;
done:
a->len=size;
low_set_index(a,size,0);
|
ed0414 | 2015-09-27 | Per Hedbor | |
|
b3ec73 | 2016-01-09 | Martin Nilsson | | return a;
|
8d28be | 1997-02-10 | Fredrik Hübinette (Hubbe) | | }
|
ed0414 | 2015-09-27 | Per Hedbor | |
|
8d28be | 1997-02-10 | Fredrik Hübinette (Hubbe) | |
|
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) | | {
|
ed0414 | 2015-09-27 | Per Hedbor | | if(string_may_modify_len(a))
|
8d28be | 1997-02-10 | Fredrik Hübinette (Hubbe) | | {
unlink_pike_string(a);
return realloc_unlinked_string(a, size);
}else{
|
60e6cf | 2013-11-09 | Arne Goedeke | | struct pike_string *r=begin_wide_shared_string(size,a->size_shift);
|
f4ef46 | 2016-01-12 | Martin Nilsson | | memcpy(r->str, a->str, a->len<<a->size_shift);
|
119e1e | 2014-08-22 | Arne Goedeke | | r->flags |= a->flags & STRING_CHECKED_MASK;
|
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;
}
}
|
ed0414 | 2015-09-27 | Per Hedbor | | struct pike_string *new_realloc_shared_string(struct pike_string *a, INT32 size, enum size_shift 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);
|
119e1e | 2014-08-22 | Arne Goedeke | | r->flags |= (a->flags & STRING_CHECKED_MASK);
|
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) | | }
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
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;
|
700130 | 2014-09-29 | Martin Nilsson | | unsigned int size,tmp;
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
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;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | 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);
}
}
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
|
119e1e | 2014-08-22 | Arne Goedeke | | if(string_may_modify(a))
|
0d3ea5 | 1998-01-19 | Fredrik Hübinette (Hubbe) | | {
|
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);
|
60e6cf | 2013-11-09 | Arne Goedeke | | 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);
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(r->str, a->str, a->len << a->size_shift);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | low_set_index(r,index,c);
|
0d3ea5 | 1998-01-19 | Fredrik Hübinette (Hubbe) | | free_string(a);
return end_shared_string(r);
}
}
|
fa7ecb | 2014-12-08 | Martin Nilsson | | static void set_flags_for_add( struct pike_string *ret,
unsigned char aflags,
unsigned char amin,
unsigned char amax,
const struct pike_string *b)
|
992551 | 2013-05-31 | Per Hedbor | | {
if( !b->len ) {
|
e106dd | 2016-12-16 | Henrik Grubbström (Grubba) | | ret->flags |= aflags & STRING_CHECKED_MASK;
|
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 | | }
|
fa7ecb | 2014-12-08 | Martin Nilsson | | void update_flags_for_add( struct pike_string *a, const struct pike_string *b)
|
992551 | 2013-05-31 | Per Hedbor | | {
if( !b->len ) return;
if( a->flags & STRING_CONTENT_CHECKED )
{
if(b->flags & STRING_CONTENT_CHECKED)
{
|
9078a1 | 2016-12-16 | Henrik Grubbström (Grubba) | | if (a->len) {
if( b->min < a->min ) a->min = b->min;
if( b->max > a->max ) a->max = b->max;
} else {
a->min = b->min;
a->max = b->max;
}
|
992551 | 2013-05-31 | Per Hedbor | | }
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) | |
|
fa7ecb | 2014-12-08 | Martin Nilsson | | PMOD_EXPORT struct pike_string *add_shared_strings(const struct pike_string *a,
const 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 );
|
59fc9e | 2014-09-03 | Martin Nilsson | | memcpy(a->str+(alen<<a->size_shift),b->str,b->len<<b->size_shift);
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | | 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) | | }
|
ed0414 | 2015-09-27 | Per Hedbor | | static struct pike_string *make_shared_substring( struct pike_string *s,
ptrdiff_t start,
ptrdiff_t len,
enum size_shift shift)
|
358724 | 2015-08-22 | Per Hedbor | | {
struct pike_string *existing;
struct substring_pike_string *res;
|
ed0414 | 2015-09-27 | Per Hedbor | | void *strstart = s->str+(start<<shift);
size_t hval = low_do_hash(strstart,len,shift);
if( (existing =
internal_findstring(strstart, len, shift, hval)) )
|
358724 | 2015-08-22 | Per Hedbor | | {
add_ref(existing);
return existing;
}
res = ba_alloc(&substring_allocator);
res->parent = s;
add_ref(s);
existing = &res->str;
|
ed0414 | 2015-09-27 | Per Hedbor | | existing->flags = STRING_NOT_SHARED;
existing->size_shift = shift;
|
358724 | 2015-08-22 | Per Hedbor | | existing->alloc_type = STRING_ALLOC_SUBSTRING;
|
ed0414 | 2015-09-27 | Per Hedbor | | existing->struct_type = STRING_STRUCT_SUBSTRING;
existing->hval = hval;
existing->str = strstart;
|
358724 | 2015-08-22 | Per Hedbor | | existing->len = len;
#ifdef PIKE_DEBUG
if( existing->len + start != s->len )
Pike_fatal("Substrings must be terminated at end of string for now.\n");
#endif
existing->refs = 0;
add_ref(existing);
|
ed0414 | 2015-09-27 | Per Hedbor | | link_pike_string(existing,hval);
return existing;
|
358724 | 2015-08-22 | Per Hedbor | | }
|
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",
|
bd6739 | 2015-10-14 | Martin Nilsson | | (long)start, (long)len, (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;
}
|
358724 | 2015-08-22 | Per Hedbor | |
if( s->alloc_type == STRING_ALLOC_SUBSTRING )
{
|
ed0414 | 2015-09-27 | Per Hedbor | | struct pike_string *pr= substring_content_string(s);
|
a1db06 | 2016-06-07 | Henrik Grubbström (Grubba) | | start += (s->str-pr->str)>>s->size_shift;
|
ed0414 | 2015-09-27 | Per Hedbor | | s = pr;
|
358724 | 2015-08-22 | Per Hedbor | | }
|
ed0414 | 2015-09-27 | Per Hedbor | | if( (len+start == s->len)
&& start < (s->len>>1)
&& (!s->size_shift
|| (s->size_shift==1 &&
find_magnitude1(((p_wchar1*)s->str)+start,len)==1)
|| (s->size_shift==2 &&
find_magnitude2(((p_wchar2*)s->str)+start,len)==2)))
|
358724 | 2015-08-22 | Per Hedbor | | {
|
ed0414 | 2015-09-27 | Per Hedbor | |
return make_shared_substring( s, start, len, s->size_shift );
|
358724 | 2015-08-22 | Per Hedbor | | }
|
3e625c | 1998-10-11 | Fredrik Hübinette (Hubbe) | | 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);
}
|
759c42 | 2015-10-17 | Martin Nilsson | | UNREACHABLE(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,
|
fa7ecb | 2014-12-08 | Martin Nilsson | | 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;
|
ed0414 | 2015-09-27 | Per Hedbor | | enum size_shift 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;
}
|
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;
}
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) | | }
|
13670c | 2015-05-25 | Martin Nilsson | |
|
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) | | {
|
ddad7a | 2014-10-20 | Martin Nilsson | | SET_HSIZE(BEGIN_HASH_SIZE);
|
9c14f3 | 2014-04-27 | Martin Nilsson | | base_table=xcalloc(sizeof(struct pike_string *), htable_size);
|
4edb1a | 2002-09-11 | David Hedbor | | empty_pike_string = make_shared_string("");
|
c6cfc0 | 2014-11-12 | Per Hedbor | | empty_pike_string->flags |= STRING_IS_LOWERCASE | STRING_IS_UPPERCASE;
|
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) | | {
for(s=base_table[e];s;s=next)
{
next=s->next;
s->next=0;
}
base_table[e]=0;
}
|
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) | |
|
a206ac | 2014-08-24 | Arne Goedeke | | void count_string_types() {
unsigned INT32 e;
|
0ddc5d | 2015-11-14 | Martin Nilsson | | size_t num_static = 0, num_short = 0, num_substring = 0, num_malloc = 0;
|
a206ac | 2014-08-24 | Arne Goedeke | |
for (e = 0; e < htable_size; e++) {
struct pike_string * s;
for (s = base_table[e]; s; s = s->next)
|
358724 | 2015-08-22 | Per Hedbor | | switch (s->alloc_type) {
|
a206ac | 2014-08-24 | Arne Goedeke | | case STRING_ALLOC_BA:
num_short ++;
break;
case STRING_ALLOC_STATIC:
num_static ++;
break;
|
358724 | 2015-08-22 | Per Hedbor | | case STRING_ALLOC_SUBSTRING:
num_substring ++;
break;
|
0ddc5d | 2015-11-14 | Martin Nilsson | | case STRING_ALLOC_MALLOC:
num_malloc ++;
break;
|
a206ac | 2014-08-24 | Arne Goedeke | | }
}
|
358724 | 2015-08-22 | Per Hedbor | | push_static_text("num_short_strings");
|
a206ac | 2014-08-24 | Arne Goedeke | | push_ulongest(num_short);
|
358724 | 2015-08-22 | Per Hedbor | | push_static_text("num_static_strings");
|
a206ac | 2014-08-24 | Arne Goedeke | | push_ulongest(num_static);
|
358724 | 2015-08-22 | Per Hedbor | | push_static_text("num_substrings");
push_ulongest(num_substring);
|
0ddc5d | 2015-11-14 | Martin Nilsson | | push_static_text("num_malloced_strings");
push_ulongest(num_malloc);
|
3c0860 | 2008-05-02 | Martin Stjernholm | | }
|
a495ca | 2014-08-23 | Arne Goedeke | | size_t count_memory_in_string(const struct pike_string * s) {
size_t size = sizeof(struct pike_string);
|
60e6cf | 2013-11-09 | Arne Goedeke | |
|
358724 | 2015-08-22 | Per Hedbor | | switch (s->alloc_type) {
case STRING_ALLOC_SUBSTRING:
size += sizeof( struct pike_string *);
break;
|
a495ca | 2014-08-23 | Arne Goedeke | | case STRING_ALLOC_BA:
size += sizeof(struct pike_string);
break;
case STRING_ALLOC_MALLOC:
size += PIKE_ALIGNTO(((s->len + 1) << s->size_shift), 4);
break;
|
0ddc5d | 2015-11-14 | Martin Nilsson | | case STRING_ALLOC_STATIC:
break;
|
a495ca | 2014-08-23 | Arne Goedeke | | }
|
60e6cf | 2013-11-09 | Arne Goedeke | |
|
a495ca | 2014-08-23 | Arne Goedeke | | return size;
|
041a53 | 2012-03-08 | Henrik Grubbström (Grubba) | | }
|
a495ca | 2014-08-23 | Arne Goedeke | | 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;
|
a495ca | 2014-08-23 | Arne Goedeke | | size_t size = 0;
*num = num_strings;
size+=htable_size * sizeof(struct pike_string *);
for (e = 0; e < htable_size; e++) {
struct pike_string * s;
for (s = base_table[e]; s; s = s->next) {
size += count_memory_in_string(s);
}
|
c3c703 | 1996-12-04 | Fredrik Hübinette (Hubbe) | | }
|
a495ca | 2014-08-23 | Arne Goedeke | |
*_size = size;
|
c3c703 | 1996-12-04 | Fredrik Hübinette (Hubbe) | | }
|
936735 | 1997-01-27 | Fredrik Hübinette (Hubbe) | |
|
d05654 | 2014-06-17 | Henrik Grubbström (Grubba) | | PMOD_EXPORT void visit_string (struct pike_string *s, int action, void *extra)
|
ad8d05 | 2008-05-02 | Martin Stjernholm | | {
|
c42e09 | 2014-06-18 | Henrik Grubbström (Grubba) | | visit_enter(s, T_STRING, extra);
|
8775df | 2015-06-04 | Martin Karlgren | | switch (action & VISIT_MODE_MASK) {
|
5e8344 | 2008-05-11 | Martin Stjernholm | | #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:
|
a495ca | 2014-08-23 | Arne Goedeke | | mc_counted_bytes += count_memory_in_string (s);
|
5e8344 | 2008-05-11 | Martin Stjernholm | | break;
}
|
c42e09 | 2014-06-18 | Henrik Grubbström (Grubba) | | visit_leave(s, T_STRING, extra);
|
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) | |
|
48d159 | 2015-03-16 | Martin Nilsson | | PMOD_EXPORT struct pike_string *next_pike_string (const struct pike_string *s)
|
f7cfa8 | 2001-09-04 | Martin Stjernholm | | {
struct pike_string *next = s->next;
if (!next) {
size_t h = s->hval;
do {
h++;
|
e85df8 | 2001-09-06 | Fredrik Hübinette (Hubbe) | | h = HMODULO(h);
|
f7cfa8 | 2001-09-04 | Martin Stjernholm | | next = base_table[h];
} while (!next);
}
return next;
}
|
db4a40 | 1998-10-09 | Fredrik Hübinette (Hubbe) | |
|
fa7ecb | 2014-12-08 | Martin Nilsson | | PMOD_EXPORT PCHARP MEMCHR_PCHARP(const PCHARP ptr, int chr, ptrdiff_t len)
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | {
switch(ptr.shift)
{
|
98c030 | 2014-09-03 | Martin Nilsson | | 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) | | }
|
9282fd | 2015-09-27 | Martin Nilsson | | UNREACHABLE(MKPCHARP(0,0));
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | }
|
ddecab | 2017-01-11 | Martin Nilsson | | #define DIGIT(x) ( (x)<256 ? hexdecode[x] : 16 )
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | #define MBASE ('z' - 'a' + 1 + 10)
|
0c7382 | 2016-12-18 | Martin Nilsson | | PMOD_EXPORT long STRTOL_PCHARP(PCHARP str, PCHARP *ptr, int base)
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | {
|
ddecab | 2017-01-11 | Martin Nilsson | |
|
90784a | 2003-02-26 | Martin Stjernholm | |
unsigned long val, mul_limit;
int c;
|
0c7382 | 2016-12-18 | Martin Nilsson | | int xx, neg = 0, add_limit, overflow = 0;
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | |
if (ptr) *ptr = str;
|
0c7382 | 2016-12-18 | Martin Nilsson | | 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) | | {
|
c05454 | 2016-12-17 | Martin Nilsson | | 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;
}
|
ddecab | 2017-01-11 | Martin Nilsson | | if (DIGIT(c) >= base)
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | return 0;
|
ddecab | 2017-01-11 | Martin Nilsson | | if (base == 16 && c == '0' && DIGIT(INDEX_PCHARP(str,2))<16 &&
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | (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 | | }
|
0c7382 | 2016-12-18 | Martin Nilsson | | val=DIGIT(c);
|
0bc4cf | 1998-10-13 | Fredrik Hübinette (Hubbe) | | while(1)
{
INC_PCHARP(str,1);
c=EXTRACT_PCHARP(str);
|
ddecab | 2017-01-11 | Martin Nilsson | | if( (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 | | int wide_string_to_svalue_inumber(struct svalue *r,
|
3d3d72 | 2014-12-15 | Martin Nilsson | | void * str,
void *ptr,
int base,
ptrdiff_t maxlength,
|
ed0414 | 2015-09-27 | Per Hedbor | | enum size_shift 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,
|
ed0414 | 2015-09-27 | Per Hedbor | | enum size_shift shift)
|
15f63a | 2008-07-23 | Martin Stjernholm | |
{
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,
|
0c7382 | 2016-12-18 | Martin Nilsson | | int base,
|
8c37d1 | 2000-08-15 | Henrik Grubbström (Grubba) | | ptrdiff_t maxlength)
|
31ea27 | 1999-10-22 | Fredrik Noring | | {
|
ddecab | 2017-01-11 | Martin Nilsson | |
|
90784a | 2003-02-26 | Martin Stjernholm | |
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | PCHARP str_start;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
90784a | 2003-02-26 | Martin Stjernholm | | unsigned INT_TYPE val, mul_limit;
int c;
|
0c7382 | 2016-12-18 | Martin Nilsson | | 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;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
0c7382 | 2016-12-18 | Martin Nilsson | | if(base < 0 || MBASE < base)
|
31ea27 | 1999-10-22 | Fredrik Noring | | return 0;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
bbee34 | 2000-03-31 | Fredrik Hübinette (Hubbe) | | if(!WIDE_ISALNUM(c = EXTRACT_PCHARP(str)))
|
31ea27 | 1999-10-22 | Fredrik Noring | | {
|
c05454 | 2016-12-17 | Martin Nilsson | | while(wide_isspace(c))
|
011ad3 | 1999-10-22 | Fredrik Hübinette (Hubbe) | | {
INC_PCHARP(str,1);
c = EXTRACT_PCHARP(str);
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
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 | | }
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
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;
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
0c7382 | 2016-12-18 | Martin Nilsson | |
|
ddecab | 2017-01-11 | Martin Nilsson | | if(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'))) &&
|
ddecab | 2017-01-11 | Martin Nilsson | | DIGIT(INDEX_PCHARP(str,2))<16 )
|
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);
}
|
13670c | 2015-05-25 | Martin Nilsson | |
|
0c7382 | 2016-12-18 | Martin Nilsson | | 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 | | }
|
13670c | 2015-05-25 | Martin Nilsson | |
|
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();
|
13670c | 2015-05-25 | Martin Nilsson | |
|
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");
|
13670c | 2015-05-25 | Martin Nilsson | |
|
9b150a | 2002-05-11 | Martin Nilsson | | i=pcharp_to_svalue_inumber(&r, MKPCHARP_STR(Pike_sp[-1].u.string), 0, base, 0);
|
13670c | 2015-05-25 | Martin Nilsson | |
|
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) | |
|
3d3d72 | 2014-12-15 | Martin Nilsson | | PMOD_EXPORT double STRTOD_PCHARP(const PCHARP nptr, PCHARP *endptr)
|
f3ece8 | 1999-02-28 | Fredrik Hübinette (Hubbe) | | {
|
21b12a | 2014-09-03 | Martin Nilsson | |
|
71d7d5 | 2003-02-26 | Martin Stjernholm | |
|
636bc5 | 2014-11-01 | Martin Nilsson | | PCHARP s;
|
f3ece8 | 1999-02-28 | Fredrik Hübinette (Hubbe) | | short int sign;
double num;
int got_dot;
int got_digit;
long int exponent;
if (nptr.ptr == NULL)
{
errno = EINVAL;
goto noconv;
}
s = nptr;
|
a57723 | 2016-12-17 | Martin Nilsson | | while (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))
{
|
ddecab | 2017-01-11 | Martin Nilsson | | if (WIDE_ISDIGIT (EXTRACT_PCHARP(s)))
|
f3ece8 | 1999-02-28 | Fredrik Hübinette (Hubbe) | | {
got_digit = 1;
if (num > DBL_MAX * 0.1)
|
13670c | 2015-05-25 | Martin Nilsson | |
|
f3ece8 | 1999-02-28 | Fredrik Hübinette (Hubbe) | | We just need to record that there was another
digit so that we can multiply by 10 later. */
++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;
|
2b315b | 2017-01-11 | Martin Nilsson | | if (EXTRACT_PCHARP(s) == 'E' || EXTRACT_PCHARP(s) == 'e')
|
f3ece8 | 1999-02-28 | Fredrik Hübinette (Hubbe) | | {
int save = errno;
PCHARP end;
long int exp;
errno = 0;
INC_PCHARP(s,1);
exp = STRTOL_PCHARP(s, &end, 10);
if (errno == ERANGE)
{
|
2ae97e | 2014-09-03 | Martin Nilsson | | |
7ad412 | 2003-10-03 | Henrik Grubbström (Grubba) | | * We need to find the sign of the exponent by hand.
*/
p_wchar2 c;
|
c05454 | 2016-12-17 | Martin Nilsson | | while(wide_isspace(c = EXTRACT_PCHARP(s))) {
|
7ad412 | 2003-10-03 | Henrik Grubbström (Grubba) | | 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 | |
|
f3ece8 | 1999-02-28 | Fredrik Hübinette (Hubbe) | | errno = ERANGE;
return 0.0;
|
13670c | 2015-05-25 | Martin Nilsson | |
|
f3ece8 | 1999-02-28 | Fredrik Hübinette (Hubbe) | | noconv:
if (endptr != NULL)
*endptr = nptr;
return 0.0;
}
|
3d3d72 | 2014-12-15 | Martin Nilsson | | PMOD_EXPORT p_wchar0 *require_wstring0(const struct pike_string *s,
char **to_free)
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | {
switch(s->size_shift)
{
case 0:
*to_free=0;
return STR0(s);
case 1:
case 2:
return 0;
}
|
759c42 | 2015-10-17 | Martin Nilsson | | UNREACHABLE(return 0);
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | }
|
3d3d72 | 2014-12-15 | Martin Nilsson | | PMOD_EXPORT p_wchar1 *require_wstring1(const struct pike_string *s,
char **to_free)
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | {
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;
}
|
759c42 | 2015-10-17 | Martin Nilsson | | UNREACHABLE(return 0);
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | }
|
3d3d72 | 2014-12-15 | Martin Nilsson | | PMOD_EXPORT p_wchar2 *require_wstring2(const struct pike_string *s,
char **to_free)
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | {
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);
}
|
759c42 | 2015-10-17 | Martin Nilsson | | UNREACHABLE(return 0);
|
efae67 | 1998-10-21 | Fredrik Hübinette (Hubbe) | | }
|
c05454 | 2016-12-17 | Martin Nilsson | |
PMOD_EXPORT int wide_isspace(int c)
{
switch(c)
{
SPACECASE16;
return 1;
}
return 0;
}
|
48c4ef | 2016-12-17 | Martin Nilsson | |
PMOD_EXPORT int wide_isidchar(int c)
{
if(c<0) return 0;
|
5e6dc2 | 2017-01-10 | Martin Nilsson | | if(c<256) return isidchar(c);
|
48c4ef | 2016-12-17 | Martin Nilsson | | if(wide_isspace(c)) return 0;
return 1;
}
|
c77edb | 2017-01-25 | Arne Goedeke | |
#if defined(HAS___BUILTIN_POPCOUNTLL) && SIZEOF_CHARP == 8
# define poptype unsigned long long
# define POPCOUNT __builtin_popcountll
#elif defined(HAS___BUILTIN_POPCOUNTL)
# define poptype unsigned long
# define POPCOUNT __builtin_popcountl
#else
# if SIZEOF_CHARP == 8
# define poptype unsigned INT64
# else
# define poptype unsigned INT32
# endif
# define POPCOUNT popcount_fallback
const poptype m1 = (poptype)0x5555555555555555ULL;
const poptype m2 = (poptype)0x3333333333333333ULL;
const poptype m4 = (poptype)0x0f0f0f0f0f0f0f0fULL;
static unsigned int popcount_fallback(poptype x)
{
x -= (x >> 1) & m1;
x = (x & m2) + ((x >> 2) & m2);
x = (x + (x >> 4)) & m4;
x += x >> 8;
x += x >> 16;
# if SIZEOF_CHARP == 8
x += x >> 32;
# endif
return x & 0x7f;
}
#endif
static inline unsigned INT32 div5_8bit(unsigned INT32 x) {
return ((x * 0xCD) >> 8) >> 2;
}
PMOD_EXPORT size_t pike_string_utf8_length(const struct pike_string *s, INT32 args, int extended) {
size_t len = s->len;
size_t elen = s->len;
if (LIKELY(s->size_shift == eightbit)) {
static volatile poptype foo = (poptype)0x8080808080808080ULL;
const unsigned char *in;
const poptype mask = foo;
const poptype *in8 = (poptype*)STR0(s);
const poptype *end8 = in8 + (s->len / sizeof(poptype));
if (in8 < end8) {
const size_t tail = (size_t)(end8 - in8) % 4;
poptype a = 0, b = 0, c = 0, d = 0;
in8 += tail;
switch (tail) {
do {
case 0:
in8 += 4;
a = in8[-4];
case 3:
b = in8[-3];
case 2:
c = in8[-2];
case 1:
d = in8[-1];
a &= mask;
b &= mask;
c &= mask;
d &= mask;
b >>= 1;
c >>= 2;
d >>= 3;
elen += POPCOUNT(a | b | c | d);
} while (in8 < end8);
break;
default: UNREACHABLE(break);
}
}
in = (unsigned char*)end8;
switch ((size_t)s->len % sizeof(poptype)) {
case 7: elen += (*in++) >> 7;
case 6: elen += (*in++) >> 7;
case 5: elen += (*in++) >> 7;
case 4: elen += (*in++) >> 7;
case 3: elen += (*in++) >> 7;
case 2: elen += (*in++) >> 7;
case 1: elen += (*in++) >> 7;
case 0: break;
default: UNREACHABLE(break);
}
return elen;
#undef poptype
#undef POPCOUNT
} else {
unsigned INT32 c;
size_t i;
if (s->size_shift == sixteenbit) {
unsigned INT16 *in = (unsigned INT16*)STR1(s);
for (i = 0; i < len; i++) {
c = in[i];
if (c <= 0x7f) continue;
elen += div5_8bit(fls32(c) - 2);
if (extended) continue;
if (UNLIKELY(c >= 0xd800 && c <= 0xdfff)) goto surrogate_error;
}
} else {
unsigned INT32 *in = (unsigned INT32*)STR2(s);
for (i = 0; i < len; i++) {
c = in[i];
if (c <= 0x7f) continue;
elen += div5_8bit(fls32(c) - 2);
if (extended) continue;
if (UNLIKELY(c >= 0xd800 && c <= 0xdfff)) goto surrogate_error;
if (UNLIKELY(c > 0x10ffff)) goto extended_error;
}
}
return elen;
surrogate_error:
bad_arg_error ("string_to_utf8", Pike_sp - args, args, 1,
NULL, Pike_sp - args,
"Character 0x%08x at index %"PRINTPTRDIFFT"d is "
"in the surrogate range and therefore invalid.\n",
c, i);
extended_error:
bad_arg_error ("string_to_utf8", Pike_sp - args, args, 1,
NULL, Pike_sp - args,
"Character 0x%08x at index %"PRINTPTRDIFFT"d is "
"outside the allowed range.\n",
c, i);
}
UNREACHABLE(return 0);
}
PMOD_EXPORT unsigned char *pike_string_utf8_encode(unsigned char *dst, const struct pike_string *s) {
size_t len = s->len;
switch (s->size_shift) {
case eightbit:
{
const unsigned char *in = STR0(s);
for (size_t i = 0; i < len; i++) {
unsigned char c = *in++;
if (c & 0x80) {
*dst++ = 0xc0 | (c >> 6);
*dst++ = 0x80 | (c & 0x3f);
} else *dst++ = c;
}
break;
}
case sixteenbit:
{
const unsigned INT16 *in = STR1(s);
for (size_t i = 0; i < len; i++) {
unsigned INT16 c = *in++;
if (LIKELY(c <= 0x7f)) {
*dst++ = c;
continue;
}
if (c <= 0x7ff) {
*dst++ = 0xc0 | (c >> 6);
*dst++ = 0x80 | (c & 0x3f);
} else {
*dst++ = 0xe0 | (c >> 12);
*dst++ = 0x80 | ((c >> 6) & 0x3f);
*dst++ = 0x80 | (c & 0x3f);
}
}
break;
}
case thirtytwobit:
{
const unsigned INT32 *in = (unsigned INT32*)STR2(s);
for (size_t i = 0; i < len; i++) {
unsigned INT32 bytes, shift, first;
unsigned INT32 c = in[i];
if (c <= 0x7f) {
*dst++ = c;
continue;
}
bytes = 1 + div5_8bit(fls32(c) - 2);
shift = 6 * (bytes - 1);
first = -0x40 >> (bytes - 2);
if (UNLIKELY(bytes >= 7)) {
bytes = 7;
shift = 32;
}
*dst = first | (c >> shift);
dst += bytes;
bytes -= 2;
switch (bytes) {
case 5: dst[-6] = 0x80 | ((c >> 30) & 0x3f);
case 4: dst[-5] = 0x80 | ((c >> 24) & 0x3f);
case 3: dst[-4] = 0x80 | ((c >> 18) & 0x3f);
case 2: dst[-3] = 0x80 | ((c >> 12) & 0x3f);
case 1: dst[-2] = 0x80 | ((c >> 6) & 0x3f);
case 0: dst[-1] = 0x80 | (c & 0x3f); break;
default: UNREACHABLE(break);
}
}
break;
}
}
return dst;
}
|