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
,...)
399 return vsscanf(mala_string_cstr (str
), fmt
, ap
);
403 mala_string_new_print (MalaStringBucket bucket
, const char* fmt
,...)
411 if (!(p
= malloc (size
)))
416 n
= vsnprintf (p
, size
, fmt
, ap
);
419 if (n
> -1 && n
< size
)
421 self
= string_cstr_ (p
);
425 mala_stringbucket_insert (bucket
, &self
);
435 if ((p
= realloc (p
, size
)) == NULL
)
441 mala_string_char_find (MalaString self
, const char c
)
448 pos
= strchr (self
->str
, c
);
450 return pos
?(size_t)(pos
-self
->str
):SIZE_MAX
;
454 mala_string_new_substr (MalaString self
, size_t start
, size_t end
)
458 if (start
> mala_string_length (self
))
461 if (end
> mala_string_length (self
))
462 end
= mala_string_length (self
);
464 nstr
= mala_string_new_n (self
->str
+start
, end
- start
, self
->bucket
);
470 mala_string_factory (MalaString_ref dest
, const char* src
, MalaStringBucket bucket
)
474 return *dest
= mala_string_new (src
, bucket
);
478 mala_string_free (*dest
);
494 #if 0 /*TODO below */
503 mala_string (MalaString
,)
505 mala_string (MalaString
,)
511 mala_string_tokenize_init (MalaString
,char**state
);
513 mala_string_tokenize (MalaString
,char**state
, MalaStringBucket dest
,char*breaks
)
519 mala_string (MalaString
,)
520 mala_string (MalaString
,)
521 mala_string (MalaString
,)
522 mala_string (MalaString
,)
524 regcomp (3) - POSIX regex functions
525 regerror (3) - POSIX regex functions
526 regex (3) - POSIX regex functions
527 regex (7) - POSIX
1003.2 regular expressions
528 regexec (3) - POSIX regex functions
529 regfree (3) - POSIX regex functions
532 mala_string (MalaString
,)
533 mala_string (MalaString
,)
535 /* Find the first occurrence of C in S. */
536 extern char *strchr (__const
char *__s
, int __c
) __THROW __attribute_pure__
;
537 /* Find the last occurrence of C in S. */
538 extern char *strrchr (__const
char *__s
, int __c
) __THROW __attribute_pure__
;
541 /* Return the length of the initial segment of S which
542 consists entirely of characters not in REJECT. */
543 extern size_t strcspn (__const
char *__s
, __const
char *__reject
)
544 __THROW __attribute_pure__
;
545 /* Return the length of the initial segment of S which
546 consists entirely of characters in ACCEPT. */
547 extern size_t strspn (__const
char *__s
, __const
char *__accept
)
548 __THROW __attribute_pure__
;
549 /* Find the first occurrence in S of any character in ACCEPT. */
550 extern char *strpbrk (__const
char *__s
, __const
char *__accept
)
551 __THROW __attribute_pure__
;
552 /* Find the first occurrence of NEEDLE in HAYSTACK. */
553 extern char *strstr (__const
char *__haystack
, __const
char *__needle
)
554 __THROW __attribute_pure__
;
557 /* Return the next DELM-delimited token from *STRINGP,
558 terminating it with a '\0', and update *STRINGP to point past it. */
559 extern char *strsep (char **__restrict __stringp
,
560 __const
char *__restrict __delim
) __THROW
;
571 // c-file-style: "gnu"
573 // arch-tag: 2f6ba215-7cf7-46ba-a09e-e20b4c889234