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 (const 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_ (strdup(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*/
118 /* bucket was NULL, create without bucket */
119 self
= string_cstr_ (strdup(cstr
));
127 mala_string_new_cat2 (const char* cstr1
, const char* cstr2
, MalaStringBucket bucket
)
133 mala_string tmp
= MALA_STRING_AUTO (NULL
);
138 cstr
= malloc ((len1
= strlen (cstr1
)) + strlen (cstr2
) + 1);
144 (void) strcpy (cstr
, cstr1
);
145 (void) strcpy (cstr
+ len1
, cstr2
);
150 loc
= (MalaString
*) tsearch (&tmp
, &bucket
->bucket
, bucket
->cmpfn
);
156 /*not in bucket, allocate new string*/
157 self
= string_cstr_ (cstr
);
161 self
->bucket
= bucket
;
162 self
->refcnt
+= 4; /*add a reference for the bucket itself*/
167 /*string already in bucket*/
175 /* bucket was NULL, create without bucket */
176 self
= string_cstr_ (cstr
);
183 tdelete (&tmp
, &bucket
->bucket
, bucket
->cmpfn
);
190 mala_string_new_n (const char* cstr
, const size_t n
, MalaStringBucket bucket
)
195 self
= string_cstr_ ((c
= strndup(cstr
, n
)));
199 mala_stringbucket_insert (bucket
, &self
);
203 /*should be stringbucket_find*/
205 mala_string_find (const char* cstr
, MalaStringBucket bucket
)
212 mala_string tmp
= MALA_STRING_AUTO (cstr
);
213 loc
= (MalaString
*) tfind (&tmp
, &bucket
->bucket
, bucket
->cmpfn
);
221 mala_string_free (MalaString self
)
226 MALA_ASSERT (self
->refcnt
< SIZE_MAX
>>1);
228 if (self
->refcnt
>= 4)
231 /* if this is the last used string */
232 if (self
->refcnt
< 4)
234 if (self
->user
&& self
->bucket
->freefn
)
236 self
->bucket
->freefn (self
->user
);
238 if (self
->bucket
&& !self
->bucket
->destroying
)
240 tdelete (self
, &self
->bucket
->bucket
, self
->bucket
->cmpfn
);
242 if (!(self
->refcnt
& 0x2))
243 free ((void*) self
->str
);
244 if (!(self
->refcnt
& 0x1))
250 mala_string_data_free (MalaString self
)
255 MALA_ASSERT(self
->str
);
256 MALA_ASSERT(self
->refcnt
>= 4);
260 && self
->bucket
->freefn
261 && self
->bucket
->destroying
)
263 self
->bucket
->freefn (self
->user
);
270 mala_string_copy_n (MalaString self
, const size_t n
)
274 if (mala_string_length (self
) <= n
)
280 return mala_string_new_n (self
->str
, n
, self
->bucket
);
284 mala_string_new_prefix (const char* prefix
, MalaString str
)
288 MalaStringBucket bucket
= str
->bucket
;
291 mala_string tmp
= MALA_STRING_AUTO (NULL
);
293 cstr
= malloc ((len1
= strlen (prefix
)) + mala_string_length (str
) + 1);
298 (void) strcpy (cstr
, prefix
);
299 (void) strcpy (cstr
+ len1
, str
->str
);
304 loc
= (MalaString_ref
) tsearch (&tmp
, &bucket
->bucket
, bucket
->cmpfn
);
310 /*not in bucket, allocate new string*/
311 self
= string_cstr_ (cstr
);
315 self
->bucket
= bucket
;
316 self
->refcnt
+= 4; /*add a reference for the bucket itself*/
321 /*string already in bucket*/
329 /* bucket was NULL, create without bucket */
330 self
= string_cstr_ (cstr
);
337 tdelete (&tmp
, &bucket
->bucket
, bucket
->cmpfn
);
345 mala_string_scan (const_MalaString str
,const char* fmt
,...)
350 return vsscanf(mala_string_cstr (str
), fmt
, ap
);
354 mala_string_new_print (MalaStringBucket bucket
, const char* fmt
,...)
362 if (!(p
= malloc (size
)))
367 n
= vsnprintf (p
, size
, fmt
, ap
);
370 if (n
> -1 && n
< size
)
372 self
= string_cstr_ (p
);
376 mala_stringbucket_insert (bucket
, &self
);
386 if ((p
= realloc (p
, size
)) == NULL
)
392 mala_string_char_find (MalaString self
, const char c
)
399 pos
= strchr (self
->str
, c
);
401 return pos
?(size_t)(pos
-self
->str
):SIZE_MAX
;
405 mala_string_new_substr (MalaString self
, size_t start
, size_t end
)
409 if (start
> mala_string_length (self
))
412 if (end
> mala_string_length (self
))
413 end
= mala_string_length (self
);
415 nstr
= mala_string_new_n (self
->str
+start
, end
- start
, self
->bucket
);
421 mala_string_factory (MalaString_ref dest
, const char* src
, MalaStringBucket bucket
)
425 return *dest
= mala_string_new (src
, bucket
);
429 mala_string_free (*dest
);
445 #if 0 /*TODO below */
454 mala_string (MalaString
,)
456 mala_string (MalaString
,)
462 mala_string_tokenize_init (MalaString
,char**state
);
464 mala_string_tokenize (MalaString
,char**state
, MalaStringBucket dest
,char*breaks
)
470 mala_string (MalaString
,)
471 mala_string (MalaString
,)
472 mala_string (MalaString
,)
473 mala_string (MalaString
,)
475 regcomp (3) - POSIX regex functions
476 regerror (3) - POSIX regex functions
477 regex (3) - POSIX regex functions
478 regex (7) - POSIX
1003.2 regular expressions
479 regexec (3) - POSIX regex functions
480 regfree (3) - POSIX regex functions
483 mala_string (MalaString
,)
484 mala_string (MalaString
,)
486 /* Find the first occurrence of C in S. */
487 extern char *strchr (__const
char *__s
, int __c
) __THROW __attribute_pure__
;
488 /* Find the last occurrence of C in S. */
489 extern char *strrchr (__const
char *__s
, int __c
) __THROW __attribute_pure__
;
492 /* Return the length of the initial segment of S which
493 consists entirely of characters not in REJECT. */
494 extern size_t strcspn (__const
char *__s
, __const
char *__reject
)
495 __THROW __attribute_pure__
;
496 /* Return the length of the initial segment of S which
497 consists entirely of characters in ACCEPT. */
498 extern size_t strspn (__const
char *__s
, __const
char *__accept
)
499 __THROW __attribute_pure__
;
500 /* Find the first occurrence in S of any character in ACCEPT. */
501 extern char *strpbrk (__const
char *__s
, __const
char *__accept
)
502 __THROW __attribute_pure__
;
503 /* Find the first occurrence of NEEDLE in HAYSTACK. */
504 extern char *strstr (__const
char *__haystack
, __const
char *__needle
)
505 __THROW __attribute_pure__
;
508 /* Return the next DELM-delimited token from *STRINGP,
509 terminating it with a '\0', and update *STRINGP to point past it. */
510 extern char *strsep (char **__restrict __stringp
,
511 __const
char *__restrict __delim
) __THROW
;
522 // c-file-style: "gnu"
524 // arch-tag: 2f6ba215-7cf7-46ba-a09e-e20b4c889234