00001
00002
00003
00004
00005
00006
00007
00008 #ifndef STRALLOC_H
00009 #define STRALLOC_H
00010 #include "global.h"
00011
00012 #include <stdarg.h>
00013
00014 #include "pike_macros.h"
00015 #include "block_alloc_h.h"
00016
00017 #define STRINGS_ARE_SHARED
00018
00019 #ifndef STRUCT_PIKE_STRING_DECLARED
00020 #define STRUCT_PIKE_STRING_DECLARED
00021 #endif
00022
00023 #define PIKE_STRING_CONTENTS \
00024 INT32 refs; \
00025 INT32 size_shift; \
00026 ptrdiff_t len; \
00027 size_t hval; \
00028 struct pike_string *next
00029
00030 struct pike_string
00031 {
00032 PIKE_STRING_CONTENTS;
00033 char str[1];
00034 };
00035
00036 struct string_builder
00037 {
00038 struct pike_string *s;
00039 ptrdiff_t malloced;
00040 INT32 known_shift;
00041 };
00042
00043
00044 #define APPEND_SIGNED 1
00045
00046 #define APPEND_WIDTH_HALF 2
00047 #define APPEND_WIDTH_LONG 4
00048 #define APPEND_WIDTH_LONG_LONG 6
00049 #define APPEND_WIDTH_MASK 6
00050
00051 #define APPEND_POSITIVE 8
00052 #define APPEND_UPPER_CASE 16
00053 #define APPEND_ZERO_PAD 32
00054 #define APPEND_LEFT 64
00055
00056 #if SIZEOF_CHAR_P == SIZEOF_INT
00057 #define APPEND_WIDTH_PTR 0
00058 #elif SIZEOF_CHAR_P == SIZEOF_LONG
00059 #define APPEND_WIDTH_PTR APPEND_WIDTH_LONG
00060 #elif SIZEOF_CHAR_P == SIZEOF_LONG_LONG
00061 #define APPEND_WIDTH_PTR APPEND_WIDTH_LONG_LONG
00062 #else
00063 #error "Unknown way to read pointer-wide integers."
00064 #endif
00065
00066 #ifdef PIKE_DEBUG
00067 PMOD_EXPORT struct pike_string *debug_findstring(const struct pike_string *foo);
00068 #endif
00069
00070 #define free_string(s) do{ \
00071 struct pike_string *_=(s); \
00072 debug_malloc_touch(_); \
00073 if(sub_ref(_)<=0) \
00074 really_free_string(_); \
00075 } while(0)
00076
00077 #define my_hash_string(X) PTR_TO_INT(X)
00078 #define is_same_string(X,Y) ((X)==(Y))
00079
00080 #ifdef PIKE_DEBUG
00081 #define STR0(X) ((p_wchar0 *)debug_check_size_shift((X),0)->str)
00082 #define STR1(X) ((p_wchar1 *)debug_check_size_shift((X),1)->str)
00083 #define STR2(X) ((p_wchar2 *)debug_check_size_shift((X),2)->str)
00084 #else
00085 #define STR0(X) ((p_wchar0 *)(X)->str)
00086 #define STR1(X) ((p_wchar1 *)(X)->str)
00087 #define STR2(X) ((p_wchar2 *)(X)->str)
00088 #endif
00089
00090 #define INDEX_CHARP(PTR,IND,SHIFT) \
00091 ((SHIFT)==0?((p_wchar0 *)(PTR))[(IND)]:(SHIFT)==1?((p_wchar1 *)(PTR))[(IND)]:((p_wchar2 *)(PTR))[(IND)])
00092
00093 #define SET_INDEX_CHARP(PTR,IND,SHIFT,VAL) \
00094 ((SHIFT)==0?(((p_wchar0 *)(PTR))[(IND)]=(VAL)):(SHIFT)==1?(((p_wchar1 *)(PTR))[(IND)]=(VAL)):(((p_wchar2 *)(PTR))[(IND)]=(VAL)))
00095
00096
00097 #define EXTRACT_CHARP(PTR,SHIFT) INDEX_CHARP((PTR),0,(SHIFT))
00098 #define CHARP_ADD(PTR,X,SHIFT) (PTR)+=(X)<<(SHIFT)
00099
00100 #define INDEX_PCHARP(X,Y) INDEX_CHARP((X).ptr,(Y),(X).shift)
00101 #define SET_INDEX_PCHARP(X,Y,Z) SET_INDEX_CHARP((X).ptr,(Y),(X).shift,(Z))
00102 #define EXTRACT_PCHARP(X) INDEX_CHARP((X).ptr,(0),(X).shift)
00103 #define INC_PCHARP(X,Y) (((X).ptr)+=(Y) << (X).shift)
00104
00105 #define LOW_COMPARE_PCHARP(X,CMP,Y) (((char *)((X).ptr)) CMP ((char *)((Y).ptr)))
00106 #define LOW_SUBTRACT_PCHARP(X,Y) (LOW_COMPARE_PCHARP((X),-,(Y))>>(X).shift)
00107
00108 #ifdef PIKE_DEBUG
00109 #define SUBTRACT_PCHARP(X,Y) ((X).shift!=(Y).shift?(Pike_fatal("Subtracting different size charp!\n")),0:LOW_SUBTRACT_PCHARP((X),(Y)))
00110 #define COMPARE_PCHARP(X,CMP,Y) ((X).shift!=(Y).shift?(Pike_fatal("Comparing different size charp!\n")),0:LOW_COMPARE_PCHARP((X),CMP,(Y)))
00111 #else
00112 #define SUBTRACT_PCHARP(X,Y) LOW_SUBTRACT_PCHARP((X),(Y))
00113 #define COMPARE_PCHARP(X,CMP,Y) LOW_COMPARE_PCHARP((X),CMP,(Y))
00114 #endif
00115
00116
00117
00118 static INLINE PCHARP MKPCHARP(const void *ptr, int shift)
00119 {
00120 PCHARP tmp;
00121 tmp.ptr=(p_wchar0 *)ptr;
00122 tmp.shift=shift;
00123 return tmp;
00124 }
00125
00126 #define MKPCHARP_OFF(PTR,SHIFT,OFF) MKPCHARP( ((char *)(PTR)) + ((OFF)<<(SHIFT)), (SHIFT))
00127 #define MKPCHARP_STR(STR) MKPCHARP((STR)->str, (STR)->size_shift)
00128 #define MKPCHARP_STR_OFF(STR,OFF) \
00129 MKPCHARP((STR)->str + ((OFF)<<(STR)->size_shift), (STR)->size_shift)
00130 #define ADD_PCHARP(PTR,I) MKPCHARP_OFF((PTR).ptr,(PTR).shift,(I))
00131
00132 #define reference_shared_string(s) add_ref(s)
00133 #define copy_shared_string(to,s) add_ref((to)=(s))
00134
00135 #ifdef DO_PIKE_CLEANUP
00136
00137 struct shared_string_location
00138 {
00139 struct pike_string *s;
00140 struct shared_string_location *next;
00141 };
00142
00143 extern struct shared_string_location *all_shared_string_locations;
00144
00145 #define MAKE_CONST_STRING(var, text) do { \
00146 static struct shared_string_location str_; \
00147 if(!str_.s) { \
00148 str_.s=make_shared_binary_string((text),CONSTANT_STRLEN(text)); \
00149 str_.next=all_shared_string_locations; \
00150 all_shared_string_locations=&str_; \
00151 } \
00152 var = str_.s; \
00153 }while(0)
00154
00155 #define MAKE_CONST_STRING_CODE(var, code) do { \
00156 static struct shared_string_location str_; \
00157 if (!str_.s) { \
00158 {code;} \
00159 str_.s = var; \
00160 DO_IF_DEBUG ( \
00161 if (!str_.s) \
00162 Pike_fatal ("Code at " __FILE__ ":" DEFINETOSTR (__LINE__) \
00163 " failed to produce a string in " #var ".\n"); \
00164 ); \
00165 str_.next=all_shared_string_locations; \
00166 all_shared_string_locations=&str_; \
00167 } \
00168 else var = str_.s; \
00169 } while (0)
00170
00171 #else
00172
00173 #define MAKE_CONST_STRING(var, text) \
00174 do { static struct pike_string *str_; \
00175 if(!str_) str_=make_shared_binary_string((text),CONSTANT_STRLEN(text)); \
00176 var = str_; \
00177 }while(0)
00178
00179 #define MAKE_CONST_STRING_CODE(var, code) do { \
00180 static struct pike_string *str_; \
00181 if (!str_) { \
00182 {code;} \
00183 str_ = var; \
00184 DO_IF_DEBUG ( \
00185 if (!str_) \
00186 Pike_fatal ("Code at " __FILE__ ":" DEFINETOSTR (__LINE__) \
00187 " failed to produce a string in " #var ".\n"); \
00188 ); \
00189 } \
00190 else var = str_; \
00191 } while (0)
00192
00193 #endif
00194
00195 #define REF_MAKE_CONST_STRING(var, text) do { \
00196 MAKE_CONST_STRING(var, text); \
00197 reference_shared_string(var); \
00198 } while (0)
00199
00200 #define REF_MAKE_CONST_STRING_CODE(var, code) do { \
00201 MAKE_CONST_STRING_CODE(var, code); \
00202 reference_shared_string(var); \
00203 } while (0)
00204
00205
00206 #define MAKE_CONSTANT_SHARED_STRING(var, text) \
00207 REF_MAKE_CONST_STRING(var, text)
00208
00209 #define convert_0_to_0(X,Y,Z) MEMCPY((char *)(X),(char *)(Y),(Z))
00210 #define convert_1_to_1(X,Y,Z) MEMCPY((char *)(X),(char *)(Y),(Z)<<1)
00211 #define convert_2_to_2(X,Y,Z) MEMCPY((char *)(X),(char *)(Y),(Z)<<2)
00212
00213 #define compare_0_to_0(X,Y,Z) MEMCMP((char *)(X),(char *)(Y),(Z))
00214 #define compare_1_to_1(X,Y,Z) MEMCMP((char *)(X),(char *)(Y),(Z)<<1)
00215 #define compare_2_to_2(X,Y,Z) MEMCMP((char *)(X),(char *)(Y),(Z)<<2)
00216
00217 #define CONVERT(FROM,TO) \
00218 void PIKE_CONCAT4(convert_,FROM,_to_,TO)(PIKE_CONCAT(p_wchar,TO) *to, const PIKE_CONCAT(p_wchar,FROM) *from, ptrdiff_t len); \
00219 INT32 PIKE_CONCAT4(compare_,FROM,_to_,TO)(const PIKE_CONCAT(p_wchar,TO) *to, const PIKE_CONCAT(p_wchar,FROM) *from, ptrdiff_t len);
00220
00221 PMOD_EXPORT extern struct pike_string *empty_pike_string;
00222
00223
00224 PMOD_EXPORT unsigned INT32 index_shared_string(struct pike_string *s,
00225 ptrdiff_t pos);
00226 PMOD_EXPORT void low_set_index(struct pike_string *s, ptrdiff_t pos,
00227 int value);
00228 PMOD_EXPORT struct pike_string *debug_check_size_shift(struct pike_string *a,int shift);
00229 CONVERT(0,1)
00230 CONVERT(0,2)
00231 CONVERT(1,0)
00232 CONVERT(1,2)
00233 CONVERT(2,0)
00234 CONVERT(2,1)
00235 PMOD_EXPORT int generic_compare_strings(const void *a, ptrdiff_t alen, int asize,
00236 const void *b, ptrdiff_t blen, int bsize);
00237 PMOD_EXPORT void generic_memcpy(PCHARP to,
00238 PCHARP from,
00239 ptrdiff_t len);
00240 PMOD_EXPORT void pike_string_cpy(PCHARP to, struct pike_string *from);
00241 PMOD_EXPORT struct pike_string *binary_findstring(const char *foo, ptrdiff_t l);
00242 PMOD_EXPORT struct pike_string *findstring(const char *foo);
00243 struct short_pike_string0;
00244 struct short_pike_string1;
00245 struct short_pike_string2;
00246 BLOCK_ALLOC(short_pike_string0, SHORT_STRING_BLOCK);
00247 BLOCK_ALLOC(short_pike_string1, SHORT_STRING_BLOCK);
00248 BLOCK_ALLOC(short_pike_string2, SHORT_STRING_BLOCK);
00249
00250
00251
00252
00253 PMOD_EXPORT struct pike_string *debug_begin_shared_string(size_t len);
00254 PMOD_EXPORT struct pike_string *debug_begin_wide_shared_string(size_t len, int shift);
00255 PMOD_EXPORT struct pike_string *low_end_shared_string(struct pike_string *s);
00256 PMOD_EXPORT struct pike_string *end_shared_string(struct pike_string *s);
00257 PMOD_EXPORT struct pike_string *end_and_resize_shared_string(struct pike_string *str, ptrdiff_t len);
00258 PMOD_EXPORT struct pike_string * debug_make_shared_binary_string(const char *str,size_t len);
00259 PMOD_EXPORT struct pike_string * debug_make_shared_binary_pcharp(const PCHARP str,size_t len);
00260 PMOD_EXPORT struct pike_string * debug_make_shared_pcharp(const PCHARP str);
00261 PMOD_EXPORT struct pike_string * debug_make_shared_binary_string0(const p_wchar0 *str,size_t len);
00262 PMOD_EXPORT struct pike_string * debug_make_shared_binary_string1(const p_wchar1 *str,size_t len);
00263 PMOD_EXPORT struct pike_string * debug_make_shared_binary_string2(const p_wchar2 *str,size_t len);
00264 PMOD_EXPORT struct pike_string *debug_make_shared_string(const char *str);
00265 PMOD_EXPORT struct pike_string *debug_make_shared_string0(const p_wchar0 *str);
00266 PMOD_EXPORT struct pike_string *debug_make_shared_string1(const p_wchar1 *str);
00267 PMOD_EXPORT struct pike_string *debug_make_shared_string2(const p_wchar2 *str);
00268 PMOD_EXPORT void unlink_pike_string(struct pike_string *s);
00269 PMOD_EXPORT void do_free_string(struct pike_string *s);
00270 PMOD_EXPORT void do_really_free_string(struct pike_string *s);
00271 PMOD_EXPORT void do_really_free_pike_string(struct pike_string *s);
00272 PMOD_EXPORT void really_free_string(struct pike_string *s);
00273 PMOD_EXPORT void debug_free_string(struct pike_string *s);
00274 struct pike_string *add_string_status(int verbose);
00275 PMOD_EXPORT void check_string(struct pike_string *s);
00276 PMOD_EXPORT void verify_shared_strings_tables(void);
00277 PMOD_EXPORT int safe_debug_findstring(struct pike_string *foo);
00278 PMOD_EXPORT struct pike_string *debug_findstring(const struct pike_string *foo);
00279 PMOD_EXPORT void debug_dump_pike_string(struct pike_string *s, INT32 max);
00280 void dump_stralloc_strings(void);
00281 PMOD_EXPORT int low_quick_binary_strcmp(char *a, ptrdiff_t alen,
00282 char *b, ptrdiff_t blen);
00283 PMOD_EXPORT ptrdiff_t generic_quick_binary_strcmp(const char *a,
00284 ptrdiff_t alen, int asize,
00285 const char *b,
00286 ptrdiff_t blen, int bsize);
00287 PMOD_EXPORT int c_compare_string(struct pike_string *s, char *foo, int len);
00288 PMOD_EXPORT ptrdiff_t my_quick_strcmp(struct pike_string *a,
00289 struct pike_string *b);
00290 PMOD_EXPORT ptrdiff_t my_strcmp(struct pike_string *a,struct pike_string *b);
00291 PMOD_EXPORT struct pike_string *realloc_unlinked_string(struct pike_string *a,
00292 ptrdiff_t size);
00293 PMOD_EXPORT struct pike_string *realloc_shared_string(struct pike_string *a,
00294 ptrdiff_t size);
00295 PMOD_EXPORT struct pike_string *new_realloc_shared_string(struct pike_string *a, INT32 size, int shift);
00296 PMOD_EXPORT struct pike_string *modify_shared_string(struct pike_string *a,
00297 INT32 position,
00298 INT32 c);
00299 PMOD_EXPORT struct pike_string *add_shared_strings(struct pike_string *a,
00300 struct pike_string *b);
00301 PMOD_EXPORT struct pike_string *add_and_free_shared_strings(struct pike_string *a,
00302 struct pike_string *b);
00303 PMOD_EXPORT ptrdiff_t string_search(struct pike_string *haystack,
00304 struct pike_string *needle,
00305 ptrdiff_t start);
00306 PMOD_EXPORT struct pike_string *string_slice(struct pike_string *s,
00307 ptrdiff_t start,
00308 ptrdiff_t len);
00309 PMOD_EXPORT struct pike_string *string_replace(struct pike_string *str,
00310 struct pike_string *del,
00311 struct pike_string *to);
00312 void init_shared_string_table(void);
00313 void cleanup_shared_string_table(void);
00314 void count_memory_in_strings(INT32 *num, INT32 *size);
00315 unsigned gc_touch_all_strings(void);
00316 void gc_mark_all_strings(void);
00317 struct pike_string *next_pike_string (struct pike_string *s);
00318 PMOD_EXPORT void init_string_builder(struct string_builder *s, int mag);
00319 PMOD_EXPORT void init_string_builder_alloc(struct string_builder *s, ptrdiff_t length, int mag);
00320 PMOD_EXPORT void init_string_builder_copy(struct string_builder *to,
00321 struct string_builder *from);
00322 PMOD_EXPORT int init_string_builder_with_string (struct string_builder *s,
00323 struct pike_string *str);
00324 PMOD_EXPORT void string_build_mkspace(struct string_builder *s,
00325 ptrdiff_t chars, int mag);
00326 PMOD_EXPORT void *string_builder_allocate(struct string_builder *s, ptrdiff_t chars, int mag);
00327 PMOD_EXPORT void string_builder_putchar(struct string_builder *s, int ch);
00328 PMOD_EXPORT void string_builder_binary_strcat0(struct string_builder *s,
00329 const p_wchar0 *str, ptrdiff_t len);
00330 PMOD_EXPORT void string_builder_binary_strcat1(struct string_builder *s,
00331 const p_wchar1 *str, ptrdiff_t len);
00332 PMOD_EXPORT void string_builder_binary_strcat2(struct string_builder *s,
00333 const p_wchar2 *str, ptrdiff_t len);
00334 PMOD_EXPORT void string_builder_append(struct string_builder *s,
00335 PCHARP from,
00336 ptrdiff_t len);
00337 PMOD_EXPORT void string_builder_fill(struct string_builder *s,
00338 ptrdiff_t howmany,
00339 PCHARP from,
00340 ptrdiff_t len,
00341 ptrdiff_t offset);
00342 PMOD_EXPORT void string_builder_strcat(struct string_builder *s, char *str);
00343 PMOD_EXPORT void string_builder_shared_strcat(struct string_builder *s, struct pike_string *str);
00344 PMOD_EXPORT void string_builder_append_integer(struct string_builder *s,
00345 LONGEST val,
00346 unsigned int base,
00347 int flags,
00348 size_t min_width,
00349 size_t precision);
00350 PMOD_EXPORT void string_builder_vsprintf(struct string_builder *s,
00351 const char *fmt,
00352 va_list args);
00353 PMOD_EXPORT void string_builder_sprintf(struct string_builder *s,
00354 const char *fmt, ...);
00355 PMOD_EXPORT void reset_string_builder(struct string_builder *s);
00356 PMOD_EXPORT void free_string_builder(struct string_builder *s);
00357 PMOD_EXPORT struct pike_string *finish_string_builder(struct string_builder *s);
00358 PMOD_EXPORT PCHARP MEMCHR_PCHARP(PCHARP ptr, int chr, ptrdiff_t len);
00359 PMOD_EXPORT long STRTOL_PCHARP(PCHARP str, PCHARP *ptr, int base);
00360 PMOD_EXPORT int string_to_svalue_inumber(struct svalue *r,
00361 char * str,
00362 char **ptr,
00363 int base,
00364 int maxlength);
00365 PMOD_EXPORT int wide_string_to_svalue_inumber(struct svalue *r,
00366 void * str,
00367 void *ptr,
00368 int base,
00369 ptrdiff_t maxlength,
00370 int shift);
00371 PMOD_EXPORT int pcharp_to_svalue_inumber(struct svalue *r,
00372 PCHARP str,
00373 PCHARP *ptr,
00374 int base,
00375 ptrdiff_t maxlength);
00376 PMOD_EXPORT int convert_stack_top_string_to_inumber(int base);
00377 PMOD_EXPORT double STRTOD_PCHARP(PCHARP nptr, PCHARP *endptr);
00378 PMOD_EXPORT p_wchar0 *require_wstring0(struct pike_string *s,
00379 char **to_free);
00380 PMOD_EXPORT p_wchar1 *require_wstring1(struct pike_string *s,
00381 char **to_free);
00382 PMOD_EXPORT p_wchar2 *require_wstring2(struct pike_string *s,
00383 char **to_free);
00384
00385
00386 static INLINE void string_builder_binary_strcat(struct string_builder *s,
00387 const char *str, ptrdiff_t len)
00388 {
00389 string_builder_binary_strcat0 (s, (const p_wchar0 *) str, len);
00390 }
00391
00392 #define ISCONSTSTR(X,Y) c_compare_string((X),Y,sizeof(Y)-sizeof(""))
00393
00394 #ifdef DEBUG_MALLOC
00395 #define make_shared_string(X) \
00396 ((struct pike_string *)debug_malloc_pass(debug_make_shared_string(X)))
00397 #define make_shared_binary_string(X,Y) \
00398 ((struct pike_string *)debug_malloc_pass(debug_make_shared_binary_string((X),(Y))))
00399
00400 #define make_shared_string0(X) \
00401 ((struct pike_string *)debug_malloc_pass(debug_make_shared_string0(X)))
00402 #define make_shared_binary_string0(X,Y) \
00403 ((struct pike_string *)debug_malloc_pass(debug_make_shared_binary_string0((X),(Y))))
00404
00405 #define make_shared_string1(X) \
00406 ((struct pike_string *)debug_malloc_pass(debug_make_shared_string1(X)))
00407 #define make_shared_binary_string1(X,Y) \
00408 ((struct pike_string *)debug_malloc_pass(debug_make_shared_binary_string1((X),(Y))))
00409
00410 #define make_shared_string2(X) \
00411 ((struct pike_string *)debug_malloc_pass(debug_make_shared_string2(X)))
00412 #define make_shared_binary_string2(X,Y) \
00413 ((struct pike_string *)debug_malloc_pass(debug_make_shared_binary_string2((X),(Y))))
00414
00415 #define begin_shared_string(X) \
00416 ((struct pike_string *)debug_malloc_pass(debug_begin_shared_string(X)))
00417 #define begin_wide_shared_string(X,Y) \
00418 ((struct pike_string *)debug_malloc_pass(debug_begin_wide_shared_string((X),(Y))))
00419
00420 #define make_shared_pcharp(X) \
00421 ((struct pike_string *)debug_malloc_pass(debug_make_shared_pcharp(X)))
00422 #define make_shared_binary_pcharp(X,Y) \
00423 ((struct pike_string *)debug_malloc_pass(debug_make_shared_binary_pcharp((X),(Y))))
00424
00425 #else
00426 #define make_shared_string debug_make_shared_string
00427 #define make_shared_binary_string debug_make_shared_binary_string
00428
00429 #define make_shared_string0 debug_make_shared_string0
00430 #define make_shared_binary_string0 debug_make_shared_binary_string0
00431
00432 #define make_shared_string1 debug_make_shared_string1
00433 #define make_shared_binary_string1 debug_make_shared_binary_string1
00434
00435 #define make_shared_string2 debug_make_shared_string2
00436 #define make_shared_binary_string2 debug_make_shared_binary_string2
00437
00438 #define begin_shared_string debug_begin_shared_string
00439 #define begin_wide_shared_string debug_begin_wide_shared_string
00440
00441 #define make_shared_pcharp debug_make_shared_pcharp
00442 #define make_shared_binary_pcharp debug_make_shared_binary_pcharp
00443
00444 #endif
00445
00446 #undef CONVERT
00447
00448 PMOD_PROTO extern void f_sprintf(INT32 num_arg);
00449
00450 #endif