2 strings.c - MaLa string handling
4 Copyright (C) 2004, Christian Thaeter <chth@gmx.net>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License version 2 as
8 published by the Free Software Foundation.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, contact me.
21 * TODO: handle empty strings
30 /* allocate a mala_string (will be used for pooling in future)*/
32 string_alloc_ (MalaStringBucket bucket
)
37 self
= malloc(sizeof(mala_string
));
42 self
->bucket
= bucket
;
48 /* free a mala_string (to a pool in future) */
50 string_free_ (MalaString self)
56 /* attach allocated cstr to new MalaString, call free(cstr) on error, return NULL on cstr==NULL */
58 string_cstr_ (const char* cstr
)
65 self
= string_alloc_ (NULL
);
80 mala_string_new_cstr_attach (char* cstr
, MalaStringBucket bucket
)
90 mala_string tmp
= MALA_STRING_AUTO (cstr
);
91 loc
= (MalaString
*) tsearch (&tmp
, &bucket
->bucket
, bucket
->cmpfn
);
97 /*not in bucket, allocate new string*/
98 self
= string_cstr_ (cstr
);
101 tdelete (&tmp
, &bucket
->bucket
, bucket
->cmpfn
);
105 self
->bucket
= bucket
;
106 self
->refcnt
+= 4; /*add a reference for the bucket itself*/
111 /*string already in bucket*/
119 /* bucket was NULL, create without bucket */
120 self
= string_cstr_ (cstr
);
128 mala_string_new (const char* cstr
, MalaStringBucket bucket
)
138 mala_string tmp
= MALA_STRING_AUTO (cstr
);
139 loc
= (MalaString
*) tsearch (&tmp
, &bucket
->bucket
, bucket
->cmpfn
);
145 /*not in bucket, allocate new string*/
146 self
= string_cstr_ (strdup(cstr
));
149 tdelete (&tmp
, &bucket
->bucket
, bucket
->cmpfn
);
153 self
->bucket
= bucket
;
154 self
->refcnt
+= 4; /*add a reference for the bucket itself*/
159 /*string already in bucket*/
166 /* bucket was NULL, create without bucket */
167 self
= string_cstr_ (strdup(cstr
));
175 mala_string_new_cat2 (const char* cstr1
, const char* cstr2
, MalaStringBucket bucket
)
181 mala_string tmp
= MALA_STRING_AUTO (NULL
);
186 cstr
= malloc ((len1
= strlen (cstr1
)) + strlen (cstr2
) + 1);
192 (void) strcpy (cstr
, cstr1
);
193 (void) strcpy (cstr
+ len1
, cstr2
);
198 loc
= (MalaString
*) tsearch (&tmp
, &bucket
->bucket
, bucket
->cmpfn
);
204 /*not in bucket, allocate new string*/
205 self
= string_cstr_ (cstr
);
209 self
->bucket
= bucket
;
210 self
->refcnt
+= 4; /*add a reference for the bucket itself*/
215 /*string already in bucket*/
223 /* bucket was NULL, create without bucket */
224 self
= string_cstr_ (cstr
);
231 tdelete (&tmp
, &bucket
->bucket
, bucket
->cmpfn
);
238 mala_string_new_n (const char* cstr
, const size_t n
, MalaStringBucket bucket
)
243 self
= string_cstr_ ((c
= strndup(cstr
, n
)));
247 mala_stringbucket_insert (bucket
, &self
);
251 /*should be stringbucket_find*/
253 mala_string_find (const char* cstr
, MalaStringBucket bucket
)
260 mala_string tmp
= MALA_STRING_AUTO (cstr
);
261 loc
= (MalaString
*) tfind (&tmp
, &bucket
->bucket
, bucket
->cmpfn
);
269 mala_string_free (MalaString self
)
274 MALA_ASSERT (self
->refcnt
< SIZE_MAX
>>1);
276 if (self
->refcnt
>= 4)
279 /* if this is the last used string */
280 if (self
->refcnt
< 4)
282 if (self
->user
&& self
->bucket
->freefn
)
284 self
->bucket
->freefn (self
->user
);
286 if (self
->bucket
&& !self
->bucket
->destroying
)
288 tdelete (self
, &self
->bucket
->bucket
, self
->bucket
->cmpfn
);
290 if (!(self
->refcnt
& 0x2))
291 free ((void*) self
->str
);
292 if (!(self
->refcnt
& 0x1))
298 mala_string_data_free (MalaString self
)
303 MALA_ASSERT(self
->str
);
304 MALA_ASSERT(self
->refcnt
>= 4);
308 && self
->bucket
->freefn
309 && self
->bucket
->destroying
)
311 self
->bucket
->freefn (self
->user
);
318 mala_string_copy_n (MalaString self
, const size_t n
)
322 if (mala_string_length (self
) <= n
)
328 return mala_string_new_n (self
->str
, n
, self
->bucket
);
332 mala_string_new_prefix (const char* prefix
, MalaString str
)
336 MalaStringBucket bucket
= str
->bucket
;
339 mala_string tmp
= MALA_STRING_AUTO (NULL
);
341 cstr
= malloc ((len1
= strlen (prefix
)) + mala_string_length (str
) + 1);
346 (void) strcpy (cstr
, prefix
);
347 (void) strcpy (cstr
+ len1
, str
->str
);
352 loc
= (MalaString_ref
) tsearch (&tmp
, &bucket
->bucket
, bucket
->cmpfn
);
358 /*not in bucket, allocate new string*/
359 self
= string_cstr_ (cstr
);
363 self
->bucket
= bucket
;
364 self
->refcnt
+= 4; /*add a reference for the bucket itself*/
369 /*string already in bucket*/
377 /* bucket was NULL, create without bucket */
378 self
= string_cstr_ (cstr
);
385 tdelete (&tmp
, &bucket
->bucket
, bucket
->cmpfn
);
393 mala_string_scan (const_MalaString str
,const char* fmt
,...)
398 return vsscanf(mala_string_cstr (str
), fmt
, ap
);
402 mala_string_new_print (MalaStringBucket bucket
, const char* fmt
,...)
410 if (!(p
= malloc (size
)))
415 n
= vsnprintf (p
, size
, fmt
, ap
);
418 if (n
> -1 && n
< size
)
420 self
= string_cstr_ (p
);
424 mala_stringbucket_insert (bucket
, &self
);
434 if ((p
= realloc (p
, size
)) == NULL
)
440 mala_string_char_find (MalaString self
, const char c
)
447 pos
= strchr (self
->str
, c
);
449 return pos
?(size_t)(pos
-self
->str
):SIZE_MAX
;
453 mala_string_new_substr (MalaString self
, size_t start
, size_t end
)
457 if (start
> mala_string_length (self
))
460 if (end
> mala_string_length (self
))
461 end
= mala_string_length (self
);
463 nstr
= mala_string_new_n (self
->str
+start
, end
- start
, self
->bucket
);
469 mala_string_factory (MalaString_ref dest
, const char* src
, MalaStringBucket bucket
)
473 return *dest
= mala_string_new (src
, bucket
);
477 mala_string_free (*dest
);
493 #if 0 /*TODO below */
502 mala_string (MalaString
,)
504 mala_string (MalaString
,)
510 mala_string_tokenize_init (MalaString
,char**state
);
512 mala_string_tokenize (MalaString
,char**state
, MalaStringBucket dest
,char*breaks
)
518 mala_string (MalaString
,)
519 mala_string (MalaString
,)
520 mala_string (MalaString
,)
521 mala_string (MalaString
,)
523 regcomp (3) - POSIX regex functions
524 regerror (3) - POSIX regex functions
525 regex (3) - POSIX regex functions
526 regex (7) - POSIX
1003.2 regular expressions
527 regexec (3) - POSIX regex functions
528 regfree (3) - POSIX regex functions
531 mala_string (MalaString
,)
532 mala_string (MalaString
,)
534 /* Find the first occurrence of C in S. */
535 extern char *strchr (__const
char *__s
, int __c
) __THROW __attribute_pure__
;
536 /* Find the last occurrence of C in S. */
537 extern char *strrchr (__const
char *__s
, int __c
) __THROW __attribute_pure__
;
540 /* Return the length of the initial segment of S which
541 consists entirely of characters not in REJECT. */
542 extern size_t strcspn (__const
char *__s
, __const
char *__reject
)
543 __THROW __attribute_pure__
;
544 /* Return the length of the initial segment of S which
545 consists entirely of characters in ACCEPT. */
546 extern size_t strspn (__const
char *__s
, __const
char *__accept
)
547 __THROW __attribute_pure__
;
548 /* Find the first occurrence in S of any character in ACCEPT. */
549 extern char *strpbrk (__const
char *__s
, __const
char *__accept
)
550 __THROW __attribute_pure__
;
551 /* Find the first occurrence of NEEDLE in HAYSTACK. */
552 extern char *strstr (__const
char *__haystack
, __const
char *__needle
)
553 __THROW __attribute_pure__
;
556 /* Return the next DELM-delimited token from *STRINGP,
557 terminating it with a '\0', and update *STRINGP to point past it. */
558 extern char *strsep (char **__restrict __stringp
,
559 __const
char *__restrict __delim
) __THROW
;
570 // c-file-style: "gnu"
572 // arch-tag: 2f6ba215-7cf7-46ba-a09e-e20b4c889234