libslack(str) - string module
#include <slack/std.h> #include <slack/str.h> typedef struct String String; typedef struct StringTR StringTR; enum StringAlignment { ALIGN_LEFT = '<', ALIGN_RIGHT = '>', ALIGN_CENTRE = '|', ALIGN_CENTER = '|', ALIGN_FULL = '=' }; enum StringTROption { TR_COMPLEMENT = 1, TR_DELETE = 2, TR_SQUASH = 4 }; typedef enum StringAlignment StringAlignment; typedef enum StringTROption StringTROption; String *str_create(const char *format, ...); String *str_create_with_locker(Locker *locker, const char *format, ...); String *str_vcreate(const char *format, va_list args); String *str_vcreate_with_locker(Locker *locker, const char *format, va_list args); String *str_create_sized(size_t size, const char *format, ...); String *str_create_with_locker_sized(Locker *locker, size_t size, const char *format, ...); String *str_vcreate_sized(size_t size, const char *format, va_list args); String *str_vcreate_with_locker_sized(Locker *locker, size_t size, const char *format, va_list args); String *str_copy(const String *str); String *str_copy_unlocked(const String *str); String *str_copy_with_locker(Locker *locker, const String *str); String *str_copy_with_locker_unlocked(Locker *locker, const String *str); String *str_fgetline(FILE *stream); String *str_fgetline_with_locker(Locker *locker, FILE *stream); void str_release(String *str); void *str_destroy(String **str); int str_rdlock(const String *str); int str_wrlock(const String *str); int str_unlock(const String *str); int str_empty(const String *str); int str_empty_unlocked(const String *str); ssize_t str_length(const String *str); ssize_t str_length_unlocked(const String *str); char *cstr(const String *str); ssize_t str_set_length(String *str, size_t length); ssize_t str_set_length_unlocked(String *str, size_t length); ssize_t str_recalc_length(String *str); ssize_t str_recalc_length_unlocked(String *str); String *str_clear(String *str); String *str_clear_unlocked(String *str); String *str_remove(String *str, ssize_t index); String *str_remove_unlocked(String *str, ssize_t index); String *str_remove_range(String *str, ssize_t index, ssize_t range); String *str_remove_range_unlocked(String *str, ssize_t index, ssize_t range); String *str_insert(String *str, ssize_t index, const char *format, ...); String *str_insert_unlocked(String *str, ssize_t index, const char *format, ...); String *str_vinsert(String *str, ssize_t index, const char *format, va_list args); String *str_vinsert_unlocked(String *str, ssize_t index, const char *format, va_list args); String *str_insert_str(String *str, ssize_t index, const String *src); String *str_insert_str_unlocked(String *str, ssize_t index, const String *src); String *str_append(String *str, const char *format, ...); String *str_append_unlocked(String *str, const char *format, ...); String *str_vappend(String *str, const char *format, va_list args); String *str_vappend_unlocked(String *str, const char *format, va_list args); String *str_append_str(String *str, const String *src); String *str_append_str_unlocked(String *str, const String *src); String *str_prepend(String *str, const char *format, ...); String *str_prepend_unlocked(String *str, const char *format, ...); String *str_vprepend(String *str, const char *format, va_list args); String *str_vprepend_unlocked(String *str, const char *format, va_list args); String *str_prepend_str(String *str, const String *src); String *str_prepend_str_unlocked(String *str, const String *src); String *str_replace(String *str, ssize_t index, ssize_t range, const char *format, ...); String *str_replace_unlocked(String *str, ssize_t index, ssize_t range, const char *format, ...); String *str_vreplace(String *str, ssize_t index, ssize_t range, const char *format, va_list args); String *str_vreplace_unlocked(String *str, ssize_t index, ssize_t range, const char *format, va_list args); String *str_replace_str(String *str, ssize_t index, ssize_t range, const String *src); String *str_replace_str_unlocked(String *str, ssize_t index, ssize_t range, const String *src); String *str_substr(const String *str, ssize_t index, ssize_t range); String *str_substr_unlocked(const String *str, ssize_t index, ssize_t range); String *str_substr_with_locker(Locker *locker, const String *str, ssize_t index, ssize_t range); String *str_substr_with_locker_unlocked(Locker *locker, const String *str, ssize_t index, ssize_t range); String *substr(const char *str, ssize_t index, ssize_t range); String *substr_with_locker(Locker *locker, const char *str, ssize_t index, ssize_t range); String *str_splice(String *str, ssize_t index, ssize_t range); String *str_splice_unlocked(String *str, ssize_t index, ssize_t range); String *str_splice_with_locker(Locker *locker, String *str, ssize_t index, ssize_t range); String *str_splice_with_locker_unlocked(Locker *locker, String *str, ssize_t index, ssize_t range); String *str_repeat(size_t count, const char *format, ...); String *str_repeat_with_locker(Locker *locker, size_t count, const char *format, ...); String *str_vrepeat(size_t count, const char *format, va_list args); String *str_vrepeat_with_locker(Locker *locker, size_t count, const char *format, va_list args); int str_tr(String *str, const char *from, const char *to, int option); int str_tr_unlocked(String *str, const char *from, const char *to, int option); int str_tr_str(String *str, const String *from, const String *to, int option); int str_tr_str_unlocked(String *str, const String *from, const String *to, int option); int tr(char *str, const char *from, const char *to, int option); StringTR *tr_compile(const char *from, const char *to, int option); StringTR *tr_compile_with_locker(Locker *locker, const char *from, const char *to, int option); StringTR *str_tr_compile(const String *from, const String *to, int option); StringTR *str_tr_compile_unlocked(const String *from, const String *to, int option); StringTR *str_tr_compile_with_locker(Locker *locker, const String *from, const String *to, int option); StringTR *str_tr_compile_with_locker_unlocked(Locker *locker, const String *from, const String *to, int option); void tr_release(StringTR *table); void *tr_destroy(StringTR **table); int str_tr_compiled(String *str, StringTR *table); int str_tr_compiled_unlocked(String *str, StringTR *table); int tr_compiled(char *str, StringTR *table); List *str_regexpr(const char *pattern, const String *text, int cflags, int eflags); List *str_regexpr_unlocked(const char *pattern, const String *text, int cflags, int eflags); List *str_regexpr_with_locker(Locker *locker, const char *pattern, const String *text, int cflags, int eflags); List *str_regexpr_with_locker_unlocked(Locker *locker, const char *pattern, const String *text, int cflags, int eflags); List *regexpr(const char *pattern, const char *text, int cflags, int eflags); List *regexpr_with_locker(Locker *locker, const char *pattern, const char *text, int cflags, int eflags); int regexpr_compile(regex_t *compiled, const char *pattern, int cflags); void regexpr_release(regex_t *compiled); List *str_regexpr_compiled(const regex_t *compiled, const String *text, int eflags); List *str_regexpr_compiled_unlocked(const regex_t *compiled, const String *text, int eflags); List *str_regexpr_compiled_with_locker(Locker *locker, const regex_t *compiled, const String *text, int eflags); List *str_regexpr_compiled_with_locker_unlocked(Locker *locker, const regex_t *compiled, const String *text, int eflags); List *regexpr_compiled(const regex_t *compiled, const char *text, int eflags); List *regexpr_compiled_with_locker(Locker *locker, const regex_t *compiled, const char *text, int eflags); String *str_regsub(const char *pattern, const char *replacement, String *text, int cflags, int eflags, int all); String *str_regsub_unlocked(const char *pattern, const char *replacement, String *text, int cflags, int eflags, int all); String *str_regsub_compiled(const regex_t *compiled, const char *replacement, String *text, int eflags, int all); String *str_regsub_compiled_unlocked(const regex_t *compiled, const char *replacement, String *text, int eflags, int all); List *str_fmt(const String *str, size_t line_width, StringAlignment alignment); List *str_fmt_unlocked(const String *str, size_t line_width, StringAlignment alignment); List *str_fmt_with_locker(Locker *locker, const String *str, size_t line_width, StringAlignment alignment); List *str_fmt_with_locker_unlocked(Locker *locker, const String *str, size_t line_width, StringAlignment alignment); List *fmt(const char *str, size_t line_width, StringAlignment alignment); List *fmt_with_locker(Locker *locker, const char *str, size_t line_width, StringAlignment alignment); List *str_split(const String *str, const char *delim); List *str_split_unlocked(const String *str, const char *delim); List *str_split_with_locker(Locker *locker, const String *str, const char *delim); List *str_split_with_locker_unlocked(Locker *locker, const String *str, const char *delim); List *split(const char *str, const char *delim); List *split_with_locker(Locker *locker, const char *str, const char *delim); List *str_regexpr_split(const String *str, const char *delim, int cflags, int eflags); List *str_regexpr_split_unlocked(const String *str, const char *delim, int cflags, int eflags); List *str_regexpr_split_with_locker(Locker *locker, const String *str, const char *delim, int cflags, int eflags); List *str_regexpr_split_with_locker_unlocked(Locker *locker, const String *str, const char *delim, int cflags, int eflags); List *regexpr_split(const char *str, const char *delim, int cflags, int eflags); List *regexpr_split_with_locker(Locker *locker, const char *str, const char *delim, int cflags, int eflags); String *str_join(const List *list, const char *delim); String *str_join_unlocked(const List *list, const char *delim); String *str_join_with_locker(Locker *locker, const List *list, const char *delim); String *str_join_with_locker_unlocked(Locker *locker, const List *list, const char *delim); String *join(const List *list, const char *delim); String *join_with_locker(Locker *locker, const List *list, const char *delim); int str_soundex(const String *str); int str_soundex_unlocked(const String *str); int soundex(const char *str); String *str_trim(String *str); String *str_trim_unlocked(String *str); char *trim(char *str); String *str_trim_left(String *str); String *str_trim_left_unlocked(String *str); char *trim_left(char *str); String *str_trim_right(String *str); String *str_trim_right_unlocked(String *str); char *trim_right(char *str); String *str_squeeze(String *str); String *str_squeeze_unlocked(String *str); char *squeeze(char *str); String *str_quote(const String *str, const char *quotable, char quote_char); String *str_quote_unlocked(const String *str, const char *quotable, char quote_char); String *str_quote_with_locker(Locker *locker, const String *str, const char *quotable, char quote_char); String *str_quote_with_locker_unlocked(Locker *locker, const String *str, const char *quotable, char quote_char); String *quote(const char *str, const char *quotable, char quote_char); String *quote_with_locker(Locker *locker, const char *str, const char *quotable, char quote_char); String *str_unquote(const String *str, const char *quotable, char quote_char); String *str_unquote_unlocked(const String *str, const char *quotable, char quote_char); String *str_unquote_with_locker(Locker *locker, const String *str, const char *quotable, char quote_char); String *str_unquote_with_locker_unlocked(Locker *locker, const String *str, const char *quotable, char quote_char); String *unquote(const char *str, const char *quotable, char quote_char); String *unquote_with_locker(Locker *locker, const char *str, const char *quotable, char quote_char); String *str_encode(const String *str, const char *uncoded, const char *coded, char quote_char, int printable); String *str_encode_unlocked(const String *str, const char *uncoded, const char *coded, char quote_char, int printable); String *str_encode_with_locker(Locker *locker, const String *str, const char *uncoded, const char *coded, char quote_char, int printable); String *str_encode_with_locker_unlocked(Locker *locker, const String *str, const char *uncoded, const char *coded, char quote_char, int printable); String *str_decode(const String *str, const char *uncoded, const char *coded, char quote_char, int printable); String *str_decode_unlocked(const String *str, const char *uncoded, const char *coded, char quote_char, int printable); String *str_decode_with_locker(Locker *locker, const String *str, const char *uncoded, const char *coded, char quote_char, int printable); String *str_decode_with_locker_unlocked(Locker *locker, const String *str, const char *uncoded, const char *coded, char quote_char, int printable); String *encode(const char *str, const char *uncoded, const char *coded, char quote_char, int printable); String *encode_with_locker(Locker *locker, const char *str, const char *uncoded, const char *coded, char quote_char, int printable); String *decode(const char *str, const char *uncoded, const char *coded, char quote_char, int printable); String *decode_with_locker(Locker *locker, const char *str, const char *uncoded, const char *coded, char quote_char, int printable); String *str_lc(String *str); String *str_lc_unlocked(String *str); char *lc(char *str); String *str_lcfirst(String *str); String *str_lcfirst_unlocked(String *str); char *lcfirst(char *str); String *str_uc(String *str); String *str_uc_unlocked(String *str); char *uc(char *str); String *str_ucfirst(String *str); String *str_ucfirst_unlocked(String *str); char *ucfirst(char *str); int str_chop(String *str); int str_chop_unlocked(String *str); int chop(char *str); int str_chomp(String *str); int str_chomp_unlocked(String *str); int chomp(char *str); int str_bin(const String *str); int str_bin_unlocked(const String *str); int bin(const char *str); int str_hex(const String *str); int str_hex_unlocked(const String *str); int hex(const char *str); int str_oct(const String *str); int str_oct_unlocked(const String *str); int oct(const char *str); int strcasecmp(const char *s1, const char *s2); int strncasecmp(const char *s1, const char *s2, size_t n); size_t strlcpy(char *dst, const char *src, size_t size); size_t strlcat(char *dst, const char *src, size_t size); char *cstrcpy(char *dst, const char *src); char *cstrcat(char *dst, const char *src); char *cstrchr(const char *str, int c); char *cstrpbrk(const char *str, const char *brk); char *cstrrchr(const char *str, int c); char *cstrstr(const char *str, const char *srch); int asprintf(char **str, const char *format, ...); int vasprintf(char **str, const char *format, va_list args);
This module provides text strings that grow and shrink automatically and functions for manipulating them. Some of the functions were modelled on the list(3) module. Others were modelled on the string functions and operators in perlfunc(1) and perlop(1). Others came from OpenBSD.
String *str_create(const char *format, ...)
Creates a String specified by format
and the following arguments as in
sprintf(3). On success, returns the new string. It is the caller's
responsibility to deallocate the new string with str_release(3) or
str_destroy(3). On error, returns null
with errno
set
appropriately.
Warning: Do not under any circumstances ever pass a non-literal string as the format argument unless you know exactly how many conversions will take place. Being careless with this is a very good way to build potential security holes into your programs. The same is true for all functions that take a printf()-like format string as an argument.
String *str = str_create(buf); // EVIL String *str = str_create("%s", buf); // GOOD
String *str_create_with_locker(Locker *locker, const char *format, ...)
Equivalent to str_create(3) except that multiple threads accessing the
new string will be synchronized by locker
.
String *str_vcreate(const char *format, va_list args)
Equivalent to str_create(3) with the variable argument list specified directly as for vprintf(3).
String *str_vcreate_with_locker(Locker *locker, const char *format, va_list args)
Equivalent to str_vcreate(3) except that multiple threads accessing the
new string will be synchronized by locker
.
String *str_create_sized(size_t size, const char *format, ...)
Creates a String specified by format
and the following arguments as in
sprintf(3). The initial allocation for the string data is at least
size
bytes. On success, returns the new string. It is the caller's
responsibility to deallocate the new string with str_release(3) or
str_destroy(3). On error, returns null
with errno
set
appropriately.
String *str_create_with_locker_sized(Locker *locker, size_t size, const char *format, ...)
Equivalent to str_create_sized(3) except that multiple threads accessing
the new string will be synchronised by locker
.
String *str_vcreate_sized(size_t size, const char *format, va_list args)
Equivalent to str_create_sized(3) with the variable argument list specified directly as for vprintf(3).
String *str_vcreate_with_locker_sized(Locker *locker, size_t size, const char *format, va_list args)
Equivalent to str_vcreate_sized(3) except that multiple threads accessing
the new string will be synchronised by locker
.
String *str_copy(const String *str)
Creates a copy of str
. On success, returns the copy. It is the caller's
responsibility to deallocate the new string with str_release(3) or
str_destroy(3). On error, returns null
with errno
set
appropriately.
String *str_copy_unlocked(const String *str)
Equivalent to str_copy(3) except that str
is not read locked.
String *str_copy_with_locker(Locker *locker, const String *str)
Equivalent to str_copy(3) except that multiple threads accessing the new
string will be synchronised by locker
.
String *str_copy_with_locker_unlocked(Locker *locker, const String *str)
Equivalent to str_copy_with_locker(3) except that str
is not read
locked.
String *str_fgetline(FILE *stream)
Similar to fgets(3) except that it recognises UNIX ("\n"
), DOS
("\r\n"
) and Macintosh ("\r"
) line endings (even different line
endings in the same file) and it can read a line of any size into the
String that it returns. Reading stops after the EOF
or the end of the
line is reached. Line endings are always stored as a single "\n"
character. A nul
is placed after the last character in the buffer. On
success, returns a new String. It is the caller's responsibility to
deallocate the new string with str_release(3) or str_destroy(3). On
error, or when the end of file occurs while no characters have been read,
returns null
. Calls to this function can be mixed with calls to other
input functions from the stdio library on the same input stream.
String *str_fgetline_with_locker(Locker *locker, FILE *stream)
Equivalent to str_fgetline(3) except that multiple threads accessing the
new string will be synchronised by locker
.
void str_release(String *str)
Releases (deallocates) str
.
void *str_destroy(String **str)
Destroys (deallocates and sets to null
) *str
. Returns null
.
Note: strings shared by multiple threads must not be destroyed until
after all threads have finished with it.
int str_rdlock(const String *str)
Claims a read lock on str
(if str
was created with a Locker).
Clients must call this before calling cstr(3) (for the purpose of reading
the raw string data) on a string that was created with a Locker. It is
the client's responsibility to call str_unlock(3) when finished with the
raw string data. It is also needed when multiple read only str(3) module
functions need to be called atomically. It is the caller's responsibility to
call str_unlock(3) after the atomic operation. The only functions that
may be called on str
between calls to str_rdlock(3) and
str_unlock(3) are cstr(3) and any read only str(3) module functions
whose name ends with _unlocked
. On success, returns 0
. On error,
returns an error code.
int str_wrlock(const String *str)
Claims a write lock on str
(if str
was created with a Locker).
Clients need to call this before calling cstr(3) (for the purpose of
modifying the raw string data) on a string that was created with a
Locker. It is the client's responsibility to call str_unlock(3) when
finished with the raw string data. It is also needed when multiple
read/write str(3) module functions need to be called atomically. It is
the caller's responsibility to call str_unlock(3) after the atomic
operation. The only functions that may be called on str
between calls to
str_wrlock(3) and str_unlock(3) are cstr(3) and any str(3)
module functions whose name ends with _unlocked
. On success, returns
0
. On error, returns an error code.
int str_unlock(const String *str)
Unlocks a read or write lock on str
obtained with str_rdlock(3) or
str_wrlock(3) (if str
was created with a Locker). On success,
returns 0
. On error, returns an error code.
int str_empty(const String *str)
Returns whether or not str
is the empty string. On error, returns -1
with errno
set appropriately.
int str_empty_unlocked(const String *str)
Equivalent to str_empty(3) except that str
is not read locked.
ssize_t str_length(const String *str)
Returns the length of str
. On error, returns -1
with errno
set
appropriately.
ssize_t str_length_unlocked(const String *str)
Equivalent to str_length(3) except that str
is not read locked.
char *cstr(const String *str)
Returns the raw C string in str
. Do not use this pointer to extend the
length of the string. It's ok to use it to reduce the length of the string
provided you call str_set_length_unlocked(3) or
str_recalc_length_unlocked(3) immediately afterwards. When used on a
string that is shared by multiple threads, cstr(3) must appear between
calls to str_rdlock(3) or str_wrlock(3) and str_unlock(3).
ssize_t str_set_length(String *str, size_t length)
Sets the length of str
to length
. Only needed after the raw C string
returned by cstr(3) has been used to shorten a string. On success,
returns the length of str
. On error, returns -1
with errno
set
appropriately.
ssize_t str_set_length_unlocked(String *str, size_t length)
Equivalent to str_set_length(3) except that str
is not write locked.
ssize_t str_recalc_length(String *str)
Calculates and stores the length of str
. Only needed after the raw C
string returned by cstr(3) has been used to shorten a string. Note:
Treats str
as a nul
-terminated string and should be avoided. Use
str_set_length(3) instead. On success, returns the length of str
. On
error, returns -1
with errno
set appropriately.
ssize_t str_recalc_length_unlocked(String *str)
Equivalent to str_recalc_length(3) except that str
is not write
locked.
String *str_clear(String *str)
Makes str
the empty string. On success, returns str
. On error, returns
null
with errno
set appropriately.
String *str_clear_unlocked(String *str)
Equivalent to str_clear(3) except that str
is not write locked.
String *str_remove(String *str, ssize_t index)
Removes the index
'th character from str
. If index
is negative, it
refers to a character position relative to the end of the string (-1
is
the position after the last character, -2
is the position of the last
character and so on). On success, returns str
. On error, returns null
with errno
set appropriately.
String *str_remove_unlocked(String *str, ssize_t index)
Equivalent to str_remove(3) except that str
is not write locked.
String *str_remove_range(String *str, ssize_t index, ssize_t range)
Removes range
characters from str
starting at index
. If index
or
range
are negative, they refer to character positions relative to the end
of the string (-1
is the position after the last character, -2
is the
position of the last character and so on). On success, returns str
. On
error, returns null
with errno
set appropriately.
String *str_remove_range_unlocked(String *str, ssize_t index, ssize_t range)
Equivalent to str_remove_range(3) except that str
is not write locked.
String *str_insert(String *str, ssize_t index, const char *format, ...)
Adds the string specified by format
to str
at position index
. If
index
is negative, it refers to a character position relative to the end
of the string (-1
is the position after the last character, -2
is the
position of the last character and so on). On success, returns str
. On
error, returns null
with errno
set appropriately.
String *str_insert_unlocked(String *str, ssize_t index, const char *format, ...)
Equivalent to str_insert(3) except that str
is not write locked.
String *str_vinsert(String *str, ssize_t index, const char *format, va_list args)
Equivalent to str_insert(3) with the variable argument list specified directly as for vprintf(3).
String *str_vinsert_unlocked(String *str, ssize_t index, const char *format, va_list args)
Equivalent to str_vinsert(3) except that str
is not write locked.
String *str_insert_str(String *str, ssize_t index, const String *src)
Inserts src
into str
, starting at position index
. If index
is
negative, it refers to a character position relative to the end of the
string (-1
is the position after the last character, -2
is the
position of the last character and so on). On success, returns str
. On
error, returns null
with errno
set appropriately.
String *str_insert_str_unlocked(String *str, ssize_t index, const String *src)
Equivalent to str_insert_str(3) except that str
is not write locked
and src
is not read locked. Note: If src
needs to be read locked, it
is the caller's responsibility to lock and unlock it explicitly with
str_rdlock(3) and str_unlock(3).
String *str_append(String *str, const char *format, ...)
Appends the string specified by format
to str
. On success, returns
str
. On error, returns null
with errno
set appropriately.
String *str_append_unlocked(String *str, const char *format, ...)
Equivalent to str_append(3) except that str
is not write locked.
String *str_vappend(String *str, const char *format, va_list args)
Equivalent to str_append(3) with the variable argument list specified directly as for vprintf(3).
String *str_vappend_unlocked(String *str, const char *format, va_list args)
Equivalent to str_vappend(3) except that str
is not write locked.
String *str_append_str(String *str, const String *src)
Appends src
to str
. On success, returns str
. On error, returns
null
with errno
set appropriately.
String *str_append_str_unlocked(String *str, const String *src)
Equivalent to str_append_str(3) except that str
is not write locked
and src
is not read locked. Note: If src
needs to be read locked, it
is the caller's responsibility to lock and unlock it explicitly with
str_rdlock(3) and str_unlock(3).
String *str_prepend(String *str, const char *format, ...)
Prepends the string specified by format
to str
. On success, returns
str
. On error, returns null
with errno
set appropriately.
String *str_prepend_unlocked(String *str, const char *format, ...)
Equivalent to str_prepend(3) except that str
is not write locked.
String *str_vprepend(String *str, const char *format, va_list args)
Equivalent to str_prepend(3) with the variable argument list specified directly as for vprintf(3).
String *str_vprepend_unlocked(String *str, const char *format, va_list args)
Equivalent to str_vprepend(3) except that str
is not write locked.
String *str_prepend_str(String *str, const String *src)
Prepends src
to str
. On success, returns str
. On error, returns
null
with errno
set appropriately.
String *str_prepend_str_unlocked(String *str, const String *src)
Equivalent to str_prepend_str(3) except that str
is not write locked
and src
is not read locked. Note: If src
needs to be read locked, it
is the caller's responsibility to lock and unlock it explicitly with
str_rdlock(3) and str_unlock(3).
String *str_replace(String *str, ssize_t index, ssize_t range, const char *format, ...)
Replaces range
characters in str
, starting at index
, with the
string specified by format
. If index
or range
are negative, they
refer to character positions relative to the end of the string (-1
is the
position after the last character, -2
is the position of the last
character and so on). On success, returns str
. On error, returns null
with errno
set appropriately.
String *str_replace_unlocked(String *str, ssize_t index, ssize_t range, const char *format, ...)
Equivalent to str_replace(3) except that str
is not write locked.
String *str_vreplace(String *str, ssize_t index, ssize_t range, const char *format, va_list args)
Equivalent to str_replace(3) with the variable argument list specified directly as for vprintf(3).
String *str_vreplace_unlocked(String *str, ssize_t index, ssize_t range, const char *format, va_list args)
Equivalent to str_vreplace(3) except that str
is not write locked.
String *str_replace_str(String *str, ssize_t index, ssize_t range, const String *src)
Replaces range
characters in str
, starting at index
, with src
.
If index
or range
are negative, they refer to character positions
relative to the end of the string (-1
is the position after the last
character, -2
is the position of the last character and so on). On
success, return str
. On error, returns null
with errno
set
appropriately.
String *str_replace_str_unlocked(String *str, ssize_t index, ssize_t range, const String *src)
Equivalent to str_replace_str(3) except that str
is not write locked
and src
is not read locked. Note: If src
needs to be read locked, it
is the caller's responsibility to lock and unlock it explicitly with
str_rdlock(3) and str_unlock(3).
String *str_substr(const String *str, ssize_t index, ssize_t range)
Creates a new String object consisting of range
characters from
str
, starting at index
. If index
or range
are negative, they
refer to character positions relative to the end of the string (-1
is the
position after the last character, -2
is the position of the last
character and so on). On success, returns the new string. It is the caller's
responsibility to deallocate the new string with str_release(3) or
str_destroy(3). On error, returns null
with errno
set
appropriately.
String *str_substr_unlocked(const String *str, ssize_t index, ssize_t range)
Equivalent to str_substr(3) except that str
is not read locked.
String *str_substr_with_locker(Locker *locker, const String *str, ssize_t index, ssize_t range)
Equivalent to str_substr(3) except that multiple threads accessing the
new substring will be synchronised by locker
.
String *str_substr_with_locker_unlocked(Locker *locker, const String *str, ssize_t index, ssize_t range)
Equivalent to str_substr_with_locker(3) except that str
is not read
locked.
String *substr(const char *str, ssize_t index, ssize_t range)
Equivalent to str_substr(3) but works on an ordinary C string.
String *substr_with_locker(Locker *locker, const char *str, ssize_t index, ssize_t range)
Equivalent to substr(3) except that multiple threads accessing the new
substring will be synchronised by locker
. Note that no locking is
performed on str
as it is a raw C string.
String *str_splice(String *str, ssize_t index, ssize_t range)
Removes a substring from str
starting at index
of length range
characters. If index
or range
are negative, they refer to character
positions relative to the end of the string (-1
is the position after the
last character, -2
is the position of the last character and so on). On
success, returns the substring. It is the caller's responsibility to
deallocate the new substring with str_release(3) or str_destroy(3). On
error, returns null
with errno
set appropriately.
String *str_splice_unlocked(String *str, ssize_t index, ssize_t range)
Equivalent to str_splice(3) except that str
is not write locked.
String *str_splice_with_locker(Locker *locker, String *str, ssize_t index, ssize_t range)
Equivalent to str_splice(3) except that multiple threads accessing the
new string will be synchronised by locker
.
String *str_splice_with_locker_unlocked(Locker *locker, String *str, ssize_t index, ssize_t range)
Equivalent to str_splice_with_locker(3) except that str
is not write
locked.
String *str_repeat(size_t count, const char *format, ...)
Creates a new String containing the string determined by format
repeated count
times. On success, return the new string. It is the
caller's responsibility to deallocate the new string with str_release(3)
or str_destroy(3). On error, returns null
with errno
set
appropriately.
String *str_repeat_with_locker(Locker *locker, size_t count, const char *format, ...)
Equivalent to str_repeat(3) except that multiple threads accessing the
new string will be synchronised by locker
.
String *str_vrepeat(size_t count, const char *format, va_list args)
Equivalent to str_repeat(3) with the variable argument list specified directly as for vprintf(3).
String *str_vrepeat_with_locker(Locker *locker, size_t count, const char *format, va_list args)
Equivalent to str_vrepeat(3) except that multiple threads accessing the
new string will be synchronised by locker
.
int str_tr(String *str, const char *from, const char *to, int option)
This is just like the perl(1) tr operator. The following documentation was taken from perlop(1).
Transliterates all occurrences of the characters in from
with the
corresponding character in to
. On success, returns the number of
characters replaced or deleted. On error, returns -1
with errno
set
appropriately.
A character range may be specified with a hyphen, so str_tr(str, "A-J",
"0-9")
does the same replacement as str_tr(str, "ACEGIBDFHJ",
"0246813579")
.
Note also that the whole range idea is rather unportable between character sets - and even within character sets they may cause results you probably didn't expect. A sound principle is to use only ranges that begin from and end at either alphabets of equal case (a-e, A-E), or digits (0-4). Anything else is unsafe. If in doubt, spell out the character sets in full.
Options:
TR_COMPLEMENT Complement from. TR_DELETE Delete found but unreplaced characters. TR_SQUASH Squash duplicate replaced characters.
If TR_COMPLEMENT is specified, from
is complemented. If TR_DELETE is
specified, any characters specified by from
not found in to
are
deleted. (Note that this is slightly more flexible than the behavior of some
tr programs, which delete anything they find in from
.) If TR_SQUASH is
specified, sequences of characters that were transliterated to the same
character are squashed down to a single instance of the character.
If TR_DELETE is used, to
is always interpreted exactly as specified.
Otherwise, if to
is shorter than from
, the final character is
replicated till it is long enough. If to
is empty or null
, from
is
replicated. This latter is useful for counting characters in a class or for
squashing character sequences in a class.
Examples:
str_tr(s, "A-Z", "a-z", 0); // canonicalize to lower case str_tr(s, "a-z", "A-Z", 0); // canonicalize to upper case str_tr(s, "a-zA-Z", "A-Za-z", 0); // swap upper and lower case str_tr(s, "*", "*", 0); // count the stars in str str_tr(s, "0-9", "", 0); // count the digits in $_ str_tr(s, "a-zA-Z", "", TR_SQUASH); // bookkeeper -> bokeper str_tr(s, "a-zA-Z", " ", TR_COMPLEMENT | TR_SQUASH); // change non-alphas to single space str_tr(c, "a-zA-Z", "n-za-mN-ZA-M", 0); // Rot13 from = str_create("\200-\377"); to = str_create("%c-\177", '\000'); str_tr_str(s, from, to, 0); // clear 8th bit
If multiple transliterations are given for a character, only the first one is used:
str_tr(str, "AAA", "XYZ", 0);
will transliterate any A to X.
int str_tr_unlocked(String *str, const char *from, const char *to, int option)
Equivalent to str_tr(3) except that str
is not write locked.
int str_tr_str(String *str, const String *from, const String *to, int option)
Equivalent to str_tr(3) except that from
and to
are String
objects. This is needed when from
or to
need to contain nul
characters.
int str_tr_str_unlocked(String *str, const String *from, const String *to, int option)
Equivalent to str_tr_str(3) except that str
is not write locked and
from
and to
are not read locked. Note: If to
and from
need to be
read locked, it is the caller's responsibility to lock and unlock them
explicitly with str_rdlock(3) and str_unlock(3).
int tr(char *str, const char *from, const char *to, int option)
Equivalent to str_tr(3) but works on an ordinary C string.
StringTR *tr_compile(const char *from, const char *to, int option)
Compiles from
, to
and option
into a translation table to be passed
to str_tr_compiled(3) or tr_compiled(3). On success, returns the new
translation table. It is the caller's responsibility to deallocate the
translation table with tr_release(3) or tr_destroy(3). On error,
returns null
with errno
set appropriately.
StringTR *tr_compile_with_locker(Locker *locker, const char *from, const char *to, int option)
Equivalent to tr_compile(3) except that multiple threads accessing the new
translation table will be synchronised by locker
.
StringTR *str_tr_compile(const String *from, const String *to, int option)
Equivalent to tr_compile(3) except that from
and to
are String
objects. This is needed when from
or to
need to contain nul
characters.
StringTR *str_tr_compile_unlocked(const String *from, const String *to, int option)
Equivalent to str_tr_compile(3) except that from
and to
are not
read locked.
StringTR *str_tr_compile_with_locker(Locker *locker, const String *from, const String *to, int option)
Equivalent to str_tr_compile(3) except that multiple threads accessing
the new translation table will be synchronised by locker
.
StringTR *str_tr_compile_with_locker_unlocked(Locker *locker, const String *from, const String *to, int option)
Equivalent to str_tr_compile_with_locker(3) except that from
and to
are not read locked. Note: If to
and from
need to be read locked, it
is the caller's responsibility to lock and unlock them explicitly with
str_rdlock(3) and str_unlock(3).
void tr_release(StringTR *table)
Releases (deallocates) table
.
void *tr_destroy(StringTR **table)
Destroys (deallocates and sets to null
) *table
. Returns null
.
Note: translation tables shared by multiple threads must not be destroyed
until after all threads have finished with it.
int str_tr_compiled(String *str, StringTR *table)
Performs the character translation specified by table
(as created by
tr_compile(3) or equivalent) on str
. Use this whenever the same
translation will be performed multiple times. On success, returns the number
of characters replaced or deleted. On error, returns -1
with errno
set
appropriately.
int str_tr_compiled_unlocked(String *str, StringTR *table)
Equivalent to str_tr_compiled(3) except that str
is not write locked.
int tr_compiled(char *str, StringTR *table)
Equivalent to str_tr_compiled(3) but works on an ordinary C string.
List *str_regexpr(const char *pattern, const String *text, int cflags, int eflags)
str_regexpr(3) is an interface to POSIX 1003.2 compliant regular
expression matching. pattern
is a regular expression. text
is the
string to be searched for matches. cflags
is passed to regcomp(3)
along with REG_EXTENDED
. eflags
is passed to regexec(3). On
success, returns a List of (at most 33) Strings containing the
matching substring followed by the matching substrings of any parenthesised
subexpressions. It is the caller's responsibility to deallocate the list
with list_release(3) or list_destroy(3). On error (including no
match), returns null
with errno
set appropriately. Only use this
function when the regular expression will be used only once. Otherwise, use
regexpr_compile(3) or regcomp(3) and str_regexpr_compiled(3) or
regexpr_compiled(3) or regexec(3).
Note: If you require perl pattern matching, you could use Philip Hazel's
PCRE package, ftp://ftp.cus.cam.ac.uk/pub/software/programs/pcre/
or
link against the perl library itself.
List *str_regexpr_unlocked(const char *pattern, const String *text, int cflags, int eflags)
Equivalent to str_regexpr(3) except that text
is not read locked.
List *str_regexpr_with_locker(Locker *locker, const char *pattern, const String *text, int cflags, int eflags)
Equivalent to str_regexpr(3) except that multiple threads accessing the
new list will be synchronised by locker
.
List *str_regexpr_with_locker_unlocked(Locker *locker, const char *pattern, const String *text, int cflags, int eflags)
Equivalent to str_regexpr_with_locker(3) except that text
is not read
locked.
List *regexpr(const char *pattern, const char *text, int cflags, int eflags)
Equivalent to str_regexpr(3) but works on an ordinary C string.
List *regexpr_with_locker(Locker *locker, const char *pattern, const char *text, int cflags, int eflags)
Equivalent to regexpr(3) except that multiple threads accessing the new
list will be synchronised by locker
.
int regexpr_compile(regex_t *compiled, const char *pattern, int cflags)
Compiles a POSIX 1003.2 compliant regular expression. compiled
is the
location in which to compile the expression. pattern
is the regular
expression. cflags
is passed to regcomp(3) along with REG_EXTENDED
.
Call this, followed by re_compiled(3) when the regular expression will be
used multiple times. On success, returns 0
. On error, returns an error
code.
void regexpr_release(regex_t *compiled)
Just another name for regfree(3).
List *str_regexpr_compiled(const regex_t *compiled, const String *text, int eflags)
regexpr_compiled(3) is an interface to the POSIX 1003.2 regular
expression function, regexec(3). compiled
is the compiled regular
expression prepared by regexpr_compile(3) or regcomp(3). text
is
the string to be searched for a match. eflags
is passed to regexec(3).
On success, returns a List of (at most 33) Strings containing the
matching substring followed by the matching substrings of any parenthesised
subexpressions. It is the caller's responsibility to deallocate the list
with list_release(3) or list_destroy(3). On error (including no
match), returns null
with errno
set appropriately.
List *str_regexpr_compiled_unlocked(const regex_t *compiled, const String *text, int eflags)
Equivalent to str_regexpr_compiled(3) except that text
is not write
locked.
List *str_regexpr_compiled_with_locker(Locker *locker, const regex_t *compiled, const String *text, int eflags)
Equivalent to str_regexpr_compiled(3) except that multiple threads
accessing the new list will be synchronised by locker
.
List *str_regexpr_compiled_with_locker_unlocked(Locker *locker, const regex_t *compiled, const String *text, int eflags)
Equivalent to str_regexpr_compiled_with_locker(3) except that text
is
not read locked.
List *regexpr_compiled(const regex_t *compiled, const char *text, int eflags)
Equivalent to str_regexpr_compiled(3) but works on an ordinary C string.
List *regexpr_compiled_with_locker(Locker *locker, const regex_t *compiled, const char *text, int eflags)
Equivalent to regexpr_compiled(3) except that multiple threads accessing
the new list will be synchronised by locker
.
String *str_regsub(const char *pattern, const char *replacement, String *text, int cflags, int eflags, int all)
str_regsub(3) is an interface to POSIX 1003.2 compliant regular
expression matching and substitution. pattern
is a regular expression.
text
is the string to be searched for matches. cflags
is passed to
regcomp(3) along with REG_EXTENDED
. eflags
is passed to
regexec(3). all
specifies whether to substitute the first match (if
zero) or all matches (if non-zero). replacement
specifies the string that
replaces each match. If replacement
contains "$#"
or "${##}"
(where
"#"
is a decimal digit), the substring that matches the corresponding
subexpression is interpolated in its place. Up to 32 subexpressions are
supported. If replacement
contains "$$"
, then "$"
is interpolated
in its place. The following perl(1) quote escape sequences are also
understood:
\l lowercase next character \u uppercase next character \L lowercase until matching \E \U uppercase until matching \E \Q backslash non-alphanumeric characters until matching \E \E end case/quotemeta modification
Note that these sequences don't behave exactly like in perl(1). Namely,
an \l
appearing between a \U
and an \E
does lowercase the next
character and a \E
sequence without a matching \L
, \U
or \Q
is
an error. Also note that only 32 levels of nesting are supported.
On success, returns text
. On error (including no match), returns null
with errno
set appropriately. Only use this function when the regular
expression will be used only once. Otherwise, use regexpr_compile(3) or
regcomp(3) and str_regsub_compiled(3).
String *str_regsub_unlocked(const char *pattern, const char *replacement, String *text, int cflags, int eflags, int all)
Equivalent to str_regsub(3) except that text
is not write locked.
String *str_regsub_compiled(const regex_t *compiled, const char *replacement, String *text, int eflags, int all)
Equivalent to str_regsub(3) but works on an already compiled regex_t,
compiled
.
String *str_regsub_compiled_unlocked(const regex_t *compiled, const char *replacement, String *text, int eflags, int all)
Equivalent to str_regsub_compiled(3) except that text
is not write
locked.
List *str_fmt(const String *str, size_t line_width, StringAlignment alignment)
Formats str
into a List of String objects with length no greater
than line_width
(unless there are individual words longer than
line_width
) with the alignment specified by alignment
:
ALIGN_LEFT
('<'
)The lines will be left justified (with one space between words).
ALIGN_RIGHT
('>')The lines will be right justified (with one space between words).
ALIGN_CENTRE
or ALIGN_CENTER
('|'
)str
will be split into lines at each newline character ('\n'
). The
lines will then be centred (with one space between words) padded with spaces
to the left.
ALIGN_FULL
('='
)The lines will be fully justified (possibly with multiple spaces between words).
On success, returns a new List of String objects. It is the caller's
responsibility to deallocate the list with list_release(3) or
list_destroy(3). On error, returns null
with errno
set
appropriately. Note that str
is interpreted as a nul
-terminated
string.
Note: str_fmt(3) provides straightforward formatting completely
lacking in any aesthetic sensibilities. If you need awesome paragraph
formatting, pipe text through par(1) instead (available from
http://www.cs.berkeley.edu/~amc/Par/
).
List *str_fmt_unlocked(const String *str, size_t line_width, StringAlignment alignment)
Equivalent to str_fmt(3) except that str
is not read locked.
List *str_fmt_with_locker(Locker *locker, const String *str, size_t line_width, StringAlignment alignment)
Equivalent to str_fmt(3) except that multiple threads accessing the new
list will be synchronised by locker
.
List *str_fmt_with_locker_unlocked(Locker *locker, const String *str, size_t line_width, StringAlignment alignment)
Equivalent to str_fmt_with_locker(3) except that str
is not read
locked.
List *fmt(const char *str, size_t line_width, StringAlignment alignment)
Equivalent to str_fmt(3) but works on an ordinary C string.
List *fmt_with_locker(Locker *locker, const char *str, size_t line_width, StringAlignment alignment)
Equivalent to fmt(3) except that multiple threads accessing the new list
will be synchronised by locker
.
List *str_split(const String *str, const char *delim)
Splits str
into tokens separated by sequences of characters occurring in
delim
. On success, returns a new List of String objects. It is the
caller's responsibility to deallocate the list with list_release(3) or
list_destroy(3). On error, returns null
with errno
set
appropriately.
List *str_split_unlocked(const String *str, const char *delim)
Equivalent to str_split(3) except that str
is not read locked.
List *str_split_with_locker(Locker *locker, const String *str, const char *delim)
Equivalent to str_split(3) except that multiple threads accessing the new
list will be synchronised by locker
.
List *str_split_with_locker_unlocked(Locker *locker, const String *str, const char *delim)
Equivalent to str_split_with_locker(3) except that str
is not read
locked.
List *split(const char *str, const char *delim)
Equivalent to str_split(3) but works on an ordinary C string.
List *split_with_locker(Locker *locker, const char *str, const char *delim)
Equivalent to split(3) except that multiple threads accessing the new
list will be synchronised by locker
.
List *str_regexpr_split(const String *str, const char *delim, int cflags, int eflags)
Splits str
into tokens separated by occurrences of the regular
expression, delim
. str
is interpreted as a nul
-terminated C string.
cflags
is passed to regcomp(3) along with REG_EXTENDED
and
eflags
is passed to regexec(3). On success, returns a new List of
String objects. It is the caller's responsibility to deallocate the list
with list_release(3) or list_destroy(3). On error, returns null
with errno
set appropriately.
List *str_regexpr_split_unlocked(const String *str, const char *delim, int cflags, int eflags)
Equivalent to str_regexpr_split(3) except that str
is not read locked.
List *str_regexpr_split_with_locker(Locker *locker, const String *str, const char *delim, int cflags, int eflags)
Equivalent to str_regexpr_split(3) except that multiple threads accessing
the new list will be synchronised by locker
.
List *str_regexpr_split_with_locker_unlocked(Locker *locker, const String *str, const char *delim, int cflags, int eflags)
Equivalent to str_regexpr_split_with_locker(3) except that str
is not
read locked.
List *regexpr_split(const char *str, const char *delim, int cflags, int eflags)
Equivalent to str_regexpr_split(3) but works on an ordinary C string.
List *regexpr_split_with_locker(Locker *locker, const char *str, const char *delim, int cflags, int eflags)
Equivalent to regexpr_split(3) except that multiple threads accessing the
new list will be synchronised by locker
.
String *str_join(const List *list, const char *delim)
Joins the String objects in list
with delim
inserted between each
one. On success, returns the resulting String. It is the caller's
responsibility to deallocate the string with str_release(3) or
str_destroy(3). On error, returns null
with errno
set
appropriately.
String *str_join_unlocked(const List *list, const char *delim)
Equivalent to str_join(3) except that list
is not read locked.
String *str_join_with_locker(Locker *locker, const List *list, const char *delim)
Equivalent to str_join(3) except that multiple threads accessing the new
string will be synchronised by locker
.
String *str_join_with_locker_unlocked(Locker *locker, const List *list, const char *delim)
Equivalent to str_join_with_locker(3) except that list
is not read
locked.
String *join(const List *list, const char *delim)
Equivalent to str_join(3) but works on a list of ordinary C strings.
String *join_with_locker(Locker *locker, const List *list, const char *delim)
Equivalent to join(3) except that multiple threads accessing the new
string will be synchronised by locker
.
int str_soundex(const String *str)
Returns the soundex code of str
as an integer. On error, returns -1
with errno
set appropriately.
int str_soundex_unlocked(const String *str)
Equivalent to str_soundex(3) except that str
is not read locked.
int soundex(const char *str)
Equivalent to str_soundex(3) but works on an ordinary C string.
String *str_trim(String *str)
Trims leading and trailing whitespace from str
. On success, returns
str
. On error, returns null
with errno
set appropriately.
String *str_trim_unlocked(String *str)
Equivalent to str_trim(3) except that str
is not write locked.
char *trim(char *str)
Equivalent to str_trim(3) but works on an ordinary C string.
String *str_trim_left(String *str)
Trims leading whitespace from str
. On success, returns str
. On error,
returns null
with errno
set appropriately.
String *str_trim_left_unlocked(String *str)
Equivalent to str_trim_left(3) except that str
is not write locked.
char *trim_left(char *str)
Equivalent to str_trim_left(3) but works on an ordinary C string.
String *str_trim_right(String *str)
Trims trailing whitespace from str
. On success, returns str
. On error,
returns null
with errno
set appropriately.
String *str_trim_right_unlocked(String *str)
Equivalent to str_trim_right(3) except that str
is not write locked.
char *trim_right(char *str)
Equivalent to str_trim_right(3) but works on an ordinary C string.
String *str_squeeze(String *str)
Trims leading and trailing whitespace from str
and replaces all other
sequences of whitespace with a single space. On success, returns str
. On
error, returns null
with errno
set appropriately.
String *str_squeeze_unlocked(String *str)
Equivalent to str_squeeze(3) except that str
is not write locked.
char *squeeze(char *str)
Equivalent to str_squeeze(3) but works on an ordinary C string.
String *str_quote(const String *str, const char *quotable, char quote_char)
Creates a new String containing str
with every occurrence of any
character in quotable
preceded by quote_char
. On success, returns the
new string. It is the caller's responsibility to deallocate the new string
with str_release(3) or str_destroy(3). On error, returns null
with
errno
set appropriately.
String *str_quote_unlocked(const String *str, const char *quotable, char quote_char)
Equivalent to str_quote(3) except that str
is not read locked.
String *str_quote_with_locker(Locker *locker, const String *str, const char *quotable, char quote_char)
Equivalent to str_quote(3) except that multiple threads accessing the new
string will be synchronised by locker
.
String *str_quote_with_locker_unlocked(Locker *locker, const String *str, const char *quotable, char quote_char)
Equivalent to str_quote_with_locker(3) except that str
is not read locked.
String *quote(const char *str, const char *quotable, char quote_char)
Equivalent to str_quote(3) but works on an ordinary C string.
String *quote_with_locker(Locker *locker, const char *str, const char *quotable, char quote_char)
Equivalent to quote(3) except that multiple threads accessing the new
string will be synchronised by locker
.
String *str_unquote(const String *str, const char *quotable, char quote_char)
Creates a new string containing str
with every occurrence of
quote_char
that is followed by any character in quotable
removed. On
success, returns the new String. It is the caller's responsibility to
deallocate the new string with str_release(3) or str_destroy(3). On
error, returns null
with errno
set appropriately.
String *str_unquote_unlocked(const String *str, const char *quotable, char quote_char)
Equivalent to str_unquote(3) except that str
is not read locked.
String *str_unquote_with_locker(Locker *locker, const String *str, const char *quotable, char quote_char)
Equivalent to str_unquote(3) except that multiple threads accessing the
new string will be synchronised by locker
.
String *str_unquote_with_locker_unlocked(Locker *locker, const String *str, const char *quotable, char quote_char)
Equivalent to str_unquote_with_locker(3) except that str
is not read
locked.
String *unquote(const char *str, const char *quotable, char quote_char)
Equivalent to str_unquote(3) but works on an ordinary C string.
String *unquote_with_locker(Locker *locker, const char *str, const char *quotable, char quote_char)
Equivalent to unquote(3) except that multiple threads accessing the new
string will be synchronised by locker
.
String *str_encode(const String *str, const char *uncoded, const char *coded, char quote_char, int printable)
Returns a copy of str
with every occurrence in str
of characters in
uncoded
replaced with quote_char
followed by the corresponding (by
position) character in coded
. If printable
is non-zero, other
non-printable characters are replaced with their ASCII codes in hexadecimal.
It is the caller's responsibility to deallocate the new string with
str_release(3) or str_destroy(3). On error, returns null
with
errno
set appropriately.
Example:
// Encode a string into a C string literal str_encode(str, "\a\b\t\n\v\f\r\\", "abtnvfr\\", '\\', 1);
// Decode a C string literal str_decode(str, "\a\b\t\n\v\f\r\\", "abtnvfr\\", '\\', 1);
String *str_encode_unlocked(const String *str, const char *uncoded, const char *coded, char quote_char, int printable)
Equivalent to str_encode(3) except that str
is not read locked.
String *str_encode_with_locker(Locker *locker, const String *str, const char *uncoded, const char *coded, char quote_char, int printable)
Equivalent to str_encode(3) except that multiple threads accessing the new
string will be synchronised by locker
.
String *str_encode_with_locker_unlocked(Locker *locker, const String *str, const char *uncoded, const char *coded, char quote_char, int printable)
Equivalent to str_encode_with_locker(3) except that str
is not read
locked.
String *str_decode(const String *str, const char *uncoded, const char *coded, char quote_char, int printable)
Returns a copy of str
with every occurrence in str
of quote_char
followed by a character in coded
replaced with the corresponding (by
position) character in uncoded
. If printable
is non-zero, every
occurrence in str
of an ASCII code in octal or hexadecimal (i.e. "\ooo"
or "\xhh") is replaced with the corresponding ASCII character. It is the
caller's responsibility to deallocate the new string with str_release(3)
or str_destroy(3). On error, returns null
with errno
set
appropriately.
String *str_decode_unlocked(const String *str, const char *uncoded, const char *coded, char quote_char, int printable)
Equivalent to str_decode(3) except that str
is not read locked.
String *str_decode_with_locker(Locker *locker, const String *str, const char *uncoded, const char *coded, char quote_char, int printable)
Equivalent to str_decode(3) except that multiple threads accessing the
new string will be synchronised by locker
.
String *str_decode_with_locker_unlocked(Locker *locker, const String *str, const char *uncoded, const char *coded, char quote_char, int printable)
Equivalent to str_decode_with_locker(3) except that str
is not read
locked.
String *encode(const char *str, const char *uncoded, const char *coded, char quote_char, int printable)
Equivalent to str_encode(3) but works on an ordinary C string.
String *encode_with_locker(Locker *locker, const char *str, const char *uncoded, const char *coded, char quote_char, int printable)
Equivalent to encode(3) except that multiple threads accessing the new
string will be synchronised by locker
.
String *decode(const char *str, const char *uncoded, const char *coded, char quote_char, int printable)
Equivalent to str_decode(3) but works on an ordinary C string.
String *decode_with_locker(Locker *locker, const char *str, const char *uncoded, const char *coded, char quote_char, int printable)
Equivalent to decode(3) except that multiple threads accessing the new
string will be synchronised by locker
.
String *str_lc(String *str)
Converts str
into lower case. On success, returns str
. On error,
returns null
with errno
set appropriately.
String *str_lc_unlocked(String *str)
Equivalent to str_lc(3) except that str
is not write locked.
char *lc(char *str)
Converts str
into lower case. On success, returns str
. On error,
returns null
with errno
set appropriately.
String *str_lcfirst(String *str)
Converts the first character in str
into lower case. On success, returns
str
. On error, returns null
with errno
set appropriately.
String *str_lcfirst_unlocked(String *str)
Equivalent to str_lcfirst(3) except that str
is not write locked.
char *lcfirst(char *str)
Converts the first character in str
into lower case. On success, returns
str
. On error, returns null
with errno
set appropriately.
String *str_uc(String *str)
Converts str
into upper case. On success, returns str
. On error,
returns null
with errno
set appropriately.
String *str_uc_unlocked(String *str)
Equivalent to str_uc(3) except that str
is not write locked.
char *uc(char *str)
Converts str
into upper case. On success, returns str
. On error,
returns null
with errno
set appropriately.
String *str_ucfirst(String *str)
Converts the first character in str
into upper case. On success, returns
str
. On error, returns null
with errno
set appropriately.
String *str_ucfirst_unlocked(String *str)
Equivalent to str_ucfirst(3) except that str
is not write locked.
char *ucfirst(char *str)
Converts the first character in str
into upper case. On success, returns
str
. On error, returns null
with errno
set appropriately.
int str_chop(String *str)
Chops a character off the end of str
. On success, returns the character
chopped. On error, returns -1
with errno
set appropriately.
int str_chop_unlocked(String *str)
Equivalent to str_chop(3) except that str
is not write locked.
int chop(char *str)
Chops a character off the end of str
. On success, returns the character
chopped. On error, returns -1
with errno
set appropriately.
int str_chomp(String *str)
Chops line ending characters (i.e. '\n'
and '\r'
) off the end of
str
. On success, returns the number of characters chomped. On error,
returns -1
with errno
set appropriately.
int str_chomp_unlocked(String *str)
Equivalent to str_chomp(3) except that str
is not write locked.
int chomp(char *str)
Chops line ending characters (i.e. '\n'
and '\r'
) off the end of
str
. On success, returns the number of characters chomped. On error,
returns -1
with errno
set appropriately.
int str_bin(const String *str)
Returns the integer specified by the binary string, str
. str
may
either be a string of [0-1]
or "0b"
followed by a string of [0-1]
.
On error, returns -1
with errno
set appropriately.
int str_bin_unlocked(const String *str)
Equivalent to str_bin(3) except that str
is not read locked.
int bin(const char *str)
Returns the integer specified by the binary string, str
. str
may
either be a string of [0-1]
or "0b"
followed by a string of [0-1]
.
On error, returns -1
with errno
set appropriately.
int str_hex(const String *str)
Returns the integer specified by the hexadecimal string, str
. str
may
either be a string of [0-9a-fA-F]
or "0x"
followed by a string of
[0-9a-fA-f]
. On error, returns -1
with errno
set appropriately.
int str_hex_unlocked(const String *str)
Equivalent to str_hex(3) except that str
is not read locked.
int hex(const char *str)
Returns the integer specified by the hexadecimal string, str
. str
may
either be a string of [0-9a-fA-F]
or "0x"
followed by a string of
[0-9a-fA-f]
. On error, returns -1
with errno
set appropriately.
int str_oct(const String *str)
Returns the integer specified by the binary, octal or hexadecimal string,
str
. str
may either be "0x"
followed by a string of [0-9a-fA-F]
(hexadecimal), "0b"
followed by a string of [0-1]
(binary) or "0"
followed by a a string of [0-7]
(octal). On error, returns -1
with
errno
set appropriately.
int str_oct_unlocked(const String *str)
Equivalent to str_oct(3) except that str
is not read locked.
int oct(const char *str)
Returns the integer specified by the binary, octal or hexadecimal string,
str
. str
may either be "0x"
followed by a string of [0-9a-fA-F]
(hexadecimal), "0b"
followed by a string of [0-1]
(binary) or "0"
followed by a a string of [0-7]
(octal). On error, returns -1
with
errno
set appropriately.
Compares two strings, s1
and s2
, ignoring the case of the characters.
It returns an integer less than, equal to, or greater than zero if s1
is
found to be less than, equal to, or greater than s2
, respectively.
Equivalent to strcasecmp(3) except that it only compares the first n
characters.
Copies src
into dst
(which is size
bytes long). The result, dst
,
will be no longer than size - 1
bytes and will be nul
terminated
(unless size
is zero). This is similar to strncpy(3) except that it
always terminates the string with a nul
byte (so it's safer) and it
doesn't fill the remainder of the buffer with nul
bytes (so it's faster).
Returns the length of src
(If this is >= size
, truncation occurred).
Use this rather than strcpy(3) or strncpy(3).
Appends src
to dst
(which is size
bytes long). The result, dst
,
will be no longer than size - 1
bytes and will be nul
terminated
(unless size
is zero). This is similar to strncat(3) except that the
last argument is the size of the buffer, not the amount of space available.
(so it's more intuitive and hence safer). Returns the sum of the lengths of
src
and dst
(If this is >= size
, truncation occurred). Use this
rather than strcat(3) or strncat(3).
char *cstrcpy(char *dst, const char *src)
Copies the string pointed to by src
(including the terminating nul
character) to the array pointed to by dst
. The memory areas may not
overlap. The array dst
must be large enough to store the copy. Unless
you know that this is the case, use strlcpy() instead. This is just like
strcpy(3) except that instead of returning dst
(which you already
know), this function returns the address of the terminating nul
character
(dst + strlen(src)
).
char *cstrcat(char *dst, const char *src)
Appends the string src
to the string dst
The strings may not overlap.
The string dst
must be large enough to store the appended copy of
src
. Unless you know that this is the case, use strlcat() instead. This
is just like strcat(3) except that instead of returning dst
(which you
already know), this function returns the address of the terminating nul
character (dst + strlen(dst) + strlen(src)
).
char *cstrchr(const char *str, int c)
Scans the string str
looking for the character c
. Returns a pointer to
the first occurrence of the character c
in the string str
. This is
just like strchr(3) except that instead of returning null
when c
does not appear in str
, this function returns the address of the
terminating nul
character (str + strlen(str)
).
char *cstrpbrk(const char *str, const char *brk)
Scans the string str
looking for any of the characters in brk
. Returns
a pointer to the first occurrence of any character in brk
in the string
str
. This is just like strpbrk(3) except that instead of returning
null
when no match is found in str
, this function returns the address
of the terminating nul
character (str + strlen(str)
).
char *cstrrchr(const char *str, int c)
Scans the string str
looking for the character c
. Returns a pointer to
the last occurrence of the character c
in the string str
. This is just
like strrchr(3) except that instead of returning null
when c
does
not appear in str
, this function returns the address of the terminating
nul
character (str + strlen(str)
).
char *cstrstr(const char *str, const char *srch)
Scans the string str
looking for the string srch
. Returns a pointer to
the first occurrence of the string srch
in the string str
. This is
just like strstr(3) except that instead of returning null
when srch
does not appear in str
, this function returns the address of the
terminating nul
character (str + strlen(str)
).
Equivalent to sprintf(3) except that instead of formatting format
and
subsequent arguments into a buffer supplied by the caller, they are
formatted into a buffer that is internally allocated and stored in *str
.
On success, returns the number of bytes stored in *str
excluding the
terminating nul
character. On error, returns -1
and stores null
in
*str
.
Equivalent to asprintf(3) with the variable argument list specified directly as for vprintf(3).
On error, errno
is set either by an underlying function, or as follows:
EINVAL
When arguments to any of the functions are invalid.
MT-Disciplined
By default, Strings are not MT-Safe because most programs are single threaded and synchronisation doesn't come for free. Even in multi threaded programs, not all Strings are necessarily shared between multiple threads.
When a String is shared between multiple threads which need to be synchronised, the method of synchronisation must be carefully selected by the client code. There are tradeoffs between concurrency and overhead. The greater the concurrency, the greater the overhead. More locks give greater concurrency but have greater overhead. Readers/Writer locks can give greater concurrency than Mutex locks but have greater overhead. One lock for each String may be required, or one lock for all (or a set of) Strings may be more appropriate.
Generally, the best synchronisation strategy for a given application can only be determined by testing/benchmarking the written application. It is important to be able to experiment with the synchronisation strategy at this stage of development without pain.
To facilitate this, Strings can be created with string_create_with_locker(3) which takes a Locker argument. The Locker specifies a lock and a set of functions for manipulating the lock. Each String can have it's own lock by creating a separate Locker for each String. Multiple Strings can share the same lock by sharing the same Locker. Only the application developer can determine what is appropriate for each application on a string by string basis.
MT-Disciplined means that the application developer has a mechanism for specifying the synchronisation requirements to be applied to library code.
MT-Safe - str_fgetline(3)
Mac OS X doesn't have flockfile(3), funlockfile(3) or getc_unlocked(3). fgetline(3) is not MT-Safe on such platforms. You must guard all stdio calls with explicit synchronisation variables.
Create and manipulate strings:
#include <slack/std.h> #include <slack/str.h> int main() { String *str1 = str_create("%s %d", "string", 1); String *str2 = str_copy(str1); String *str3; String *str4; String *str5; String *str6; str_remove(str1, 6); str_remove_range(str2, 6, 2); str_clear(str1); str_insert(str1, 0, "%d", 123); str_insert_str(str1, 1, str2); str_append(str2, "abc"); str_append_str(str2, str1); str_prepend(str1, "abc"); str_prepend_str(str1, str2); str_replace(str1, 1, -2, "abc"); str_replace_str(str2, 1, 2, str1); str3 = str_substr(str1, 1, 3); str4 = substr("abc", 1, 1); str5 = str_splice(str3, 1, 1); str6 = str_repeat(3, "%c", ' '); *cstr(str5) = '\0'; str_set_length(str5, 0); str_recalc_length(str5); printf("str1 = '%s' %d\n", cstr(str1), str_length(str1)); printf("str2 = '%s' %d\n", cstr(str2), str_length(str2)); printf("str3 = '%s' %d\n", cstr(str3), str_length(str3)); printf("str4 = '%s' %d\n", cstr(str4), str_length(str4)); printf("str5 = '%s' %d\n", cstr(str5), str_length(str5)); printf("str6 = '%s' %d\n", cstr(str6), str_length(str6)); str_destroy(&str1); str_destroy(&str2); str_destroy(&str3); str_destroy(&str4); str_destroy(&str5); str_destroy(&str6); return EXIT_SUCCESS; }
Convert a text file from any system into the local text file format:
#include <slack/std.h> #include <slack/str.h> int main() { String *line; while (line = str_fgetline(stdin)) { printf("%s", cstr(line)); str_destroy(&line); } return EXIT_SUCCESS; }
Perform character translation with a pre-compiled translation table to rot13 the input:
#include <slack/std.h> #include <slack/str.h> int main() { StringTR *trtable = tr_compile("a-zA-Z", "n-za-mN-ZA-M", 0); String *line; while (line = str_fgetline(stdin)) { str_tr_compiled(line, trtable); printf("%s", cstr(line)); str_destroy(&line); } tr_destroy(&trtable); return EXIT_SUCCESS; }
The same as above but using ordinary C strings:
#include <slack/std.h> #include <slack/str.h> int main() { StringTR *trtable = tr_compile("a-zA-Z", "n-za-mN-ZA-M", 0); char line[BUFSIZ]; while (fgets(line, BUFSIZ, stdin)) { int count = tr_compiled(line, trtable); printf("%s", line); } tr_destroy(&trtable); return EXIT_SUCCESS; }
Perform regular expression matching and substitution:
#include <slack/std.h> #include <slack/str.h> int main() { // Find matches in a String object String *str = str_create("abcabcabc"); List *list = str_regexpr("a((.*)a(.*))a", str, 0, 0); regex_t compiled[1]; while (list_has_next(list)) printf("%s\n", cstr(list_next(list))); str_destroy(&str); list_destroy(&list); // Find matches in an ordinary C string list = regexpr("a((.*)a(.*))a", "abcabcabc", 0, 0); while (list_has_next(list) == 1) printf("%s\n", cstr(list_next(list))); list_destroy(&list); // Use str = str_create("abcabcabc"); if (!regexpr_compile(compiled, "a((.*)a(.*))a", 0)) { list = str_regexpr_compiled(compiled, str, 0); regexpr_release(compiled); } while (list_has_next(list) == 1) printf("%s\n", cstr(list_next(list))); str_destroy(&str); list_destroy(&list); // Use if (!regexpr_compile(compiled, "a((.*)a(.*))a", 0)) { list = regexpr_compiled(compiled, "abcabcabc", 0); regexpr_release(compiled); } while (list_has_next(list) == 1) printf("%s\n", cstr(list_next(list))); list_destroy(&list); // Perform regular expression substitution on a String object str = str_create("abcabcabc"); str_regsub("a", "z", str, 0, 0, 1); printf("%s\n", cstr(str)); str_destroy(&str); // Perform regular expression substitution with str = str_create("abcabcabc"); if (!regexpr_compile(compiled, "a", 0)) { str_regsub_compiled(compiled, "z", str, 0, 1); printf("%s\n", cstr(str)); regexpr_release(compiled); } str_destroy(&str); return EXIT_SUCCESS; }
Format some text in a String object in several different ways:
#include <slack/std.h> #include <slack/str.h> int main() { String *text = str_create("This is a string with\na few little words"); List *left = str_fmt(text, 20, ALIGN_LEFT); // or '<' List *right = str_fmt(text, 20, ALIGN_RIGHT); // or '>' List *centre = str_fmt(text, 20, ALIGN_CENTRE); // or '|' or ALIGN_CENTER List *full = str_fmt(text, 20, ALIGN_FULL); // or '=' printf("Left:\n"); while (list_has_next(left)) printf("%s\n", cstr(list_next(left))); printf("Right:\n"); while (list_has_next(right)) printf("%s\n", cstr(list_next(right))); printf("Centre:\n"); while (list_has_next(centre)) printf("%s\n", cstr(list_next(centre))); printf("Full:\n"); while (list_has_next(full)) printf("%s\n", cstr(list_next(full))); str_destroy(&text); list_destroy(&left); list_destroy(&right); list_destroy(¢re); list_destroy(&full); return EXIT_SUCCESS; }
Perform the same formatting but on an ordinary C string:
#include <slack/std.h> #include <slack/str.h> int main() { char *text = "This is a string with\na few little words"; List *left = fmt(text, 20, ALIGN_LEFT); // or '<' List *right = fmt(text, 20, ALIGN_RIGHT); // or '>' List *centre = fmt(text, 20, ALIGN_CENTRE); // or '|' or ALIGN_CENTER List *full = fmt(text, 20, ALIGN_FULL); // or '=' printf("Left:\n"); while (list_has_next(left)) printf("%s\n", cstr(list_next(left))); printf("Right:\n"); while (list_has_next(right)) printf("%s\n", cstr(list_next(right))); printf("Centre:\n"); while (list_has_next(centre)) printf("%s\n", cstr(list_next(centre))); printf("Full:\n"); while (list_has_next(full)) printf("%s\n", cstr(list_next(full))); list_destroy(&left); list_destroy(&right); list_destroy(¢re); list_destroy(&full); return EXIT_SUCCESS; }
Split and join a String object without using regular expressions:
#include <slack/std.h> #include <slack/str.h> int main() { String *text = str_create("line1\nline2\nline3\n"); List *lines = str_split(text, "\n"); String *copy; while (list_has_next(lines)) printf("%s\n", cstr(list_next(lines))); copy = str_join(lines, "\n"); printf("%s\n", cstr(copy)); str_destroy(&text); str_destroy(©); list_destroy(&lines); return EXIT_SUCCESS; }
Split an ordinary C string without using regular expressions:
#include <slack/std.h> #include <slack/str.h> int main() { char *text = "line1\nline2\nline3\n"; List *lines = split(text, "\n"); while (list_has_next(lines)) printf("%s\n", cstr(list_next(lines))); list_destroy(&lines); return EXIT_SUCCESS; }
Split a String object using regular expressions:
#include <slack/std.h> #include <slack/str.h> int main() { String *text = str_create("line1\rline2\r\nline3\n"); List *lines = str_regexpr_split(text, "(\n|\r|\r\n)", 0, 0); while (list_has_next(lines)) printf("%s\n", cstr(list_next(lines))); str_destroy(&text); list_destroy(&lines); return EXIT_SUCCESS; }
Split an ordinary C string using regular expressions:
#include <slack/std.h> #include <slack/str.h> int main() { char *text = "line1\rline2\r\nline3\n"; List *lines = regexpr_split(text, "(\n|\r|\r\n)", 0, 0); while (list_has_next(lines)) printf("%s\n", cstr(list_next(lines))); list_destroy(&lines); return EXIT_SUCCESS; }
Trim and squeeze String objects:
#include <slack/std.h> #include <slack/str.h> int main() { String *str1 = str_create(" a b c "); String *str2 = str_create(" a b c "); String *str3 = str_create(" a b c "); String *str4 = str_create(" a b c "); str_trim(str1); str_trim_left(str2); str_trim_right(str3); str_squeeze(str4); printf("'%s'\n", cstr(str1)); printf("'%s'\n", cstr(str2)); printf("'%s'\n", cstr(str3)); printf("'%s'\n", cstr(str4)); str_destroy(&str1); str_destroy(&str2); str_destroy(&str3); str_destroy(&str4); return EXIT_SUCCESS; }
Trim and squeeze ordinary C strings:
#include <slack/std.h> #include <slack/str.h> int main() { char *str1 = strdup(" a b c "); char *str2 = strdup(" a b c "); char *str3 = strdup(" a b c "); char *str4 = strdup(" a b c "); trim(str1); trim_left(str2); trim_right(str3); squeeze(str4); printf("'%s'\n", str1); printf("'%s'\n", str2); printf("'%s'\n", str3); printf("'%s'\n", str4); free(str1); free(str2); free(str3); free(str4); return EXIT_SUCCESS; }
Quote whitespace in a String object:
#include <slack/std.h> #include <slack/str.h> int main() { String *str = str_create("this is\ta\nstring with whitespaces"); String *quoted = str_quote(str, " \t\n", '\\'); String *unquoted = str_unquote(quoted, " \t\n", '\\'); printf("'%s'\n", cstr(str)); printf("'%s'\n", cstr(quoted)); printf("'%s'\n", cstr(unquoted)); str_destroy(&str); str_destroy("ed); str_destroy(&unquoted); return EXIT_SUCCESS; }
Quote whitespace in an ordinary C string:
#include <slack/std.h> #include <slack/str.h> int main() { char *str = "this is\ta\nstring with whitespaces"; String *quoted = quote(str, " \t\n", '\\'); String *unquoted = unquote(cstr(quoted), " \t\n", '\\'); printf("'%s'\n", str); printf("'%s'\n", cstr(quoted)); printf("'%s'\n", cstr(unquoted)); str_destroy("ed); str_destroy(&unquoted); return EXIT_SUCCESS; }
Apply C string literal encoding and decoded to a String object:
#include <slack/std.h> #include <slack/str.h> int main() { String *str = str_create("\a\b\t\n\v\f\rabc123\x16\034"); String *encoded = str_encode(str, "\a\b\t\n\v\f\r", "abtnvfr", '\\', 1); String *decoded = str_decode(str, "\a\b\t\n\v\f\r", "abtnvfr", '\\', 1); printf("'%s'\n", cstr(str)); printf("'%s'\n", cstr(encoded)); printf("'%s'\n", cstr(decoded)); str_destroy(&str); str_destroy(&encoded); str_destroy(&decoded); return EXIT_SUCCESS; }
Apply C string literal encoding and decoded to an ordinary C string:
#include <slack/std.h> #include <slack/str.h> int main() { char *str = "\a\b\t\n\v\f\rabc123\x16\034"; String *encoded = encode(str, "\a\b\t\n\v\f\r", "abtnvfr", '\\', 1); String *decoded = decode(str, "\a\b\t\n\v\f\r", "abtnvfr", '\\', 1); printf("'%s'\n", str); printf("'%s'\n", cstr(encoded)); printf("'%s'\n", cstr(decoded)); str_destroy(&encoded); str_destroy(&decoded); return EXIT_SUCCESS; }
Get the soundex code of a String object:
#include <slack/std.h> #include <slack/str.h> int main() { String *smith = str_create("Smith"); printf("%s %d\n", cstr(smith), str_soundex(smith)); str_destroy(&smith); return EXIT_SUCCESS; }
Get the soundex code of an ordinary C string:
#include <slack/std.h> #include <slack/str.h> int main() { char *smith = "Smith"; printf("%s %d\n", smith, soundex(smith)); return EXIT_SUCCESS; }
Convert between upper and lower case in a String object:
#include <slack/std.h> #include <slack/str.h> int main() { String *str = str_create("smith"); printf("%s\n", cstr(str)); str_ucfirst(str); printf("%s\n", cstr(str)); str_uc(str); printf("%s\n", cstr(str)); str_lcfirst(str); printf("%s\n", cstr(str)); str_lc(str); printf("%s\n", cstr(str)); str_destroy(&str); return EXIT_SUCCESS; }
Convert between upper and lower case in an ordinary C string:
#include <slack/std.h> #include <slack/str.h> int main() { char *str = strdup("smith"); printf("%s\n", str); ucfirst(str); printf("%s\n", str); uc(str); printf("%s\n", str); lcfirst(str); printf("%s\n", str); lc(str); printf("%s\n", str); free(str); return EXIT_SUCCESS; }
Chomp line ending characters off the end of a String object and chop a character of a String object:
#include <slack/std.h> #include <slack/str.h> int main() { String *str = str_create("aaa\r\n"); int bytes = str_chomp(str); printf("'%s' %d\n", cstr(str), bytes); bytes = str_chop(str); printf("'%s' '%c'\n", cstr(str), bytes); str_destroy(&str); return EXIT_SUCCESS; }
Chomp line ending characters off the end of an ordinary C string and chop a character of an ordinary C string:
#include <slack/std.h> #include <slack/str.h> int main() { char *str = strdup("aaa\r\n"); int bytes = chomp(str); printf("'%s' %d\n", str, bytes); bytes = chop(str); printf("'%s' '%c'\n", str, bytes); free(str); return EXIT_SUCCESS; }
Parse binary, octal and hexadecimal integers in String objects:
#include <slack/std.h> #include <slack/str.h> int main() { String *b = str_create("0b1010"); String *h = str_create("0x0a1b2c3d"); String *o = str_create("0177"); printf("%d\n", str_bin(b)); printf("%d\n", str_hex(h)); printf("%d\n", str_oct(o)); printf("%d\n", str_oct(h)); printf("%d\n", str_oct(b)); str_destroy(&b); str_destroy(&h); str_destroy(&o); return EXIT_SUCCESS; }
Parse binary, octal and hexadecimal integers in ordinary C strings:
#include <slack/std.h> #include <slack/str.h> int main() { char *b = "0b1010"; char *h = "0x0a1b2c3d"; char *o = "0177"; printf("%d\n", bin(b)); printf("%d\n", hex(h)); printf("%d\n", oct(o)); printf("%d\n", oct(h)); printf("%d\n", oct(b)); return EXIT_SUCCESS; }
Examples of versions of some standard string functions with more informative interfaces:
#include <slack/std.h> #include <slack/str.h> int main() { char *src = "text"; char dst[BUFSIZ]; char *pos; char *eos = cstrcpy(dst, src); printf("length '%s' = %d\n", dst, eos - dst); eos = cstrcat(dst, src); printf("length '%s' = %d\n", dst, eos - dst); eos = cstrchr(dst, 'z'); printf("length '%s' = %d\n", dst, eos - dst); for (pos = dst; *(pos = cstrpbrk(pos, "xyz")); ++pos) printf("x|y|z at pos %d in %s\n", pos - dst, dst); if (*(pos = cstrrchr(dst, 'x'))) printf("last x in %s at pos %d\n", dst, pos - dst); else printf("there is no x in %s\n", dst); for (pos = dst; *(pos = cstrstr(pos, "text")); ++pos) printf("text at pos %d in %s\n", pos - dst, dst); return EXIT_SUCCESS; }
Example of string functions that are supplied if they are not already present on the local system.
#include <slack/std.h> #include <slack/str.h> int main() { char *str1 = "smith, john"; char *str2 = "Smith, Mary"; char *str3 = NULL; char buf[16]; size_t len; printf("%d\n", strcasecmp(str1, str2)); printf("%d\n", strncasecmp(str1, str2, 5)); printf("%d\n", strncasecmp(str1, str2, 8)); if (strlcpy(buf, str1, 16) >= 16) printf("truncation occurred\n"); printf("%s\n", buf); if (strlcat(buf, str2, 16) >= 16) printf("truncation occurred\n"); printf("%s\n", buf); if (strlcpy(buf, str1, 1) >= 1) printf("truncation occurred\n"); printf("%s\n", buf); len = strlcpy(NULL, str1, 0); printf("%d\n", len); len = asprintf(&str3, "test"); printf("%s %d\n", str3, len); free(str3); return EXIT_SUCCESS; }
The delim
parameter to the split(3) and join(3) functions is an
ordinary C string so it can't contain nul
characters.
The quotable
parameter to the quote(3) and unquote(3) functions is
an ordinary C string so it can't contain nul
characters.
The uncoded
and coded
parameters to the str_encode(3) and
str_decode(3) functions are ordinary C strings so they can't contain
nul
characters.
Doesn't support multibyte/widechar strings, UTF8, UNICODE or ISO 10646 but support can probably be layered over the top of String.
Uses malloc(3). The type of memory used and the allocation strategy need to be decoupled from this code.
libslack(3), locker(3), string(3), regcomp(3), regexec(3), regerror(3), regfree(3), perlfunc(1), perlop(1)
20100612 raf <raf@raf.org>