23 #ifndef _ASTERISK_STRINGS_H
24 #define _ASTERISK_STRINGS_H
35 #if defined(DEBUG_OPAQUE)
36 #define __AST_STR_USED used2
37 #define __AST_STR_LEN len2
38 #define __AST_STR_STR str2
39 #define __AST_STR_TS ts2
41 #define __AST_STR_USED used
42 #define __AST_STR_LEN len
43 #define __AST_STR_STR str
44 #define __AST_STR_TS ts
49 #define AS_OR(a,b) (a && ast_str_strlen(a)) ? ast_str_buffer(a) : (b)
52 #define ast_strlen_zero(foo) _ast_strlen_zero(foo, __FILE__, __PRETTY_FUNCTION__, __LINE__)
53 static force_inline
int _ast_strlen_zero(
const char *s,
const char *file,
const char *
function,
int line)
55 if (!s || (*s ==
'\0')) {
58 if (!strcmp(s,
"(null)")) {
59 ast_log(__LOG_WARNING, file, line,
function,
"Possible programming error: \"(null)\" is not NULL!\n");
65 static force_inline
int attribute_pure ast_strlen_zero(
const char *s)
67 return (!s || (*s ==
'\0'));
72 #define ast_strlen_real(a) (a) ? strlen(a) : 0
73 #define ast_strlen_imaginary(a) ast_random()
80 #define S_OR(a, b) ({typeof(&((a)[0])) __x = (a); ast_strlen_zero(__x) ? (b) : __x;})
87 #define S_COR(a, b, c) ({typeof(&((b)[0])) __x = (b); (a) && !ast_strlen_zero(__x) ? (__x) : (c);})
97 static int force_inline attribute_pure
ast_begins_with(
const char *str,
const char *prefix)
99 ast_assert(str != NULL);
100 ast_assert(prefix != NULL);
101 while (*str == *prefix && *prefix !=
'\0') {
105 return *prefix ==
'\0';
116 static int force_inline attribute_pure
ast_ends_with(
const char *str,
const char *suffix)
121 ast_assert(str != NULL);
122 ast_assert(suffix != NULL);
123 str_len = strlen(str);
124 suffix_len = strlen(suffix);
126 if (suffix_len > str_len) {
130 return strcmp(str + str_len - suffix_len, suffix) == 0;
143 #define AST_YESNO(x) ((x) ? "Yes" : "No")
154 while (*str && ((
unsigned char) *str) < 33) {
174 work += strlen(work) - 1;
181 while ((work >= str) && ((
unsigned char) *work) < 33)
197 while (*str && ((
unsigned char) *str) > 32) {
249 char *
ast_strip_quoted(
char *s,
const char *beg_quotes,
const char *end_quotes);
310 char *
ast_strsep(
char **s,
const char sep, uint32_t flags);
328 char *
ast_strsep_quoted(
char **s,
const char sep,
const char quote, uint32_t flags);
358 char *
ast_escape(
char *dest,
const char *s,
size_t size,
const char *to_escape);
373 char *
ast_escape_c(
char *dest,
const char *s,
size_t size);
415 volatile size_t sz = size;
416 volatile char *sp = (
char *)src;
421 if (__builtin_expect(!sz, 0))
455 int ast_build_string(
char **buffer,
size_t *space,
const char *fmt, ...) __attribute__((format(printf, 3, 4)));
470 int ast_build_string_va(
char **buffer,
size_t *space, const
char *fmt, va_list ap) __attribute__((format(printf, 3, 0)));
492 int attribute_pure
ast_false(const
char *val);
508 unsigned int size,
char delim);
520 #define ast_join(s, len, w) ast_join_delim(s, len, w, -1, ' ')
546 #define ast_to_camel_case(s) ast_to_camel_case_delim(s, "_")
557 int ast_get_time_t(
const char *src, time_t *dst, time_t _default,
int *consumed);
568 int ast_get_timeval(
const char *src,
struct timeval *tv,
struct timeval _default,
int *consumed);
627 #define DS_MALLOC ((struct ast_threadstorage *)1)
628 #define DS_ALLOCA ((struct ast_threadstorage *)2)
629 #define DS_STATIC ((struct ast_threadstorage *)3)
659 #define ast_str_create(init_len) \
660 _ast_str_create(init_len, __FILE__, __LINE__, __PRETTY_FUNCTION__)
662 struct ast_str * attribute_malloc _ast_str_create(
size_t init_len,
663 const char *file,
int lineno,
const char *func),
667 buf = (
struct ast_str *)__ast_calloc(1,
sizeof(*buf) + init_len, file, lineno, func);
687 buf->__AST_STR_USED = 0;
688 if (buf->__AST_STR_LEN) {
689 buf->__AST_STR_STR[0] =
'\0';
701 buf->__AST_STR_USED = strlen(buf->__AST_STR_STR);
715 while (buf->__AST_STR_USED && ((
unsigned char) buf->__AST_STR_STR[buf->__AST_STR_USED - 1]) < 33) {
716 buf->__AST_STR_STR[--(buf->__AST_STR_USED)] =
'\0';
728 return buf->__AST_STR_USED;
740 return buf->__AST_STR_LEN;
756 if (__builtin_expect(buf->__AST_STR_LEN > 0, 1)) {
757 return (
char *) buf->__AST_STR_STR;
775 if ((typeof(buf->__AST_STR_USED)) -len >= buf->__AST_STR_USED) {
776 buf->__AST_STR_USED = 0;
778 buf->__AST_STR_USED += len;
781 buf->__AST_STR_USED = len;
783 buf->__AST_STR_STR[buf->__AST_STR_USED] =
'\0';
784 return buf->__AST_STR_STR;
796 #
if defined(DEBUG_THREADLOCALS)
808 struct ast_str *old_buf = *buf;
810 if (new_len <= (*buf)->__AST_STR_LEN)
812 if ((*buf)->__AST_STR_TS == DS_ALLOCA || (*buf)->__AST_STR_TS == DS_STATIC)
814 *buf = (
struct ast_str *)__ast_realloc(*buf, new_len +
sizeof(
struct ast_str), file, lineno,
function);
819 if ((*buf)->__AST_STR_TS != DS_MALLOC) {
820 pthread_setspecific((*buf)->__AST_STR_TS->key, *buf);
821 _DB1(__ast_threadstorage_object_replace(old_buf, *buf, new_len + sizeof(struct ast_str));)
828 #define ast_str_make_space(buf, new_len)
\
832 int ast_str_copy_string(struct
ast_str **dst, struct
ast_str *src),
836 if (src->__AST_STR_USED + 1 > (*dst)->__AST_STR_LEN) {
837 if (ast_str_make_space(dst, src->__AST_STR_USED + 1)) {
842 memcpy((*dst)->__AST_STR_STR, src->__AST_STR_STR, src->__AST_STR_USED + 1);
843 (*dst)->__AST_STR_USED = src->__AST_STR_USED;
848 #define ast_str_alloca(init_len) \
850 struct
ast_str *__ast_str_buf; \
851 __ast_str_buf =
ast_alloca(
sizeof(*__ast_str_buf) + init_len); \
852 __ast_str_buf->__AST_STR_LEN = init_len; \
853 __ast_str_buf->__AST_STR_USED = 0; \
854 __ast_str_buf->__AST_STR_TS = DS_ALLOCA; \
855 __ast_str_buf->__AST_STR_STR[0] =
'\0'; \
890 #
if !defined(DEBUG_THREADLOCALS)
913 size_t init_len,
const char *file,
const char *
function,
unsigned int line),
917 buf = (
struct ast_str *)__ast_threadstorage_get(ts,
sizeof(*buf) + init_len, file,
function, line);
931 #define
ast_str_thread_get(ts, init_len) __ast_str_thread_get(ts, init_len, __FILE__, __PRETTY_FUNCTION__, __LINE__)
974 ssize_t max_len,
int append, const
char *fmt, va_list ap,
975 const
char *file,
int lineno, const
char *func);
976 #define _ast_str_helper(buf, max_len, append, fmt, ap) \
977 __ast_str_helper(buf, max_len, append, fmt, ap, __FILE__, __LINE__, __PRETTY_FUNCTION__)
979 char *__ast_str_helper2(
struct ast_str **buf, ssize_t max_len,
980 const char *src,
size_t maxsrc,
int append,
int escapecommas);
1026 AST_INLINE_API(
int __attribute__((format(printf, 3, 0)))
ast_str_set_va(
struct ast_str **buf, ssize_t max_len,
const char *fmt, va_list ap),
1028 return _ast_str_helper(buf, max_len, 0, fmt, ap);
1044 AST_INLINE_API(
int __attribute__((format(printf, 3, 0)))
ast_str_append_va(struct
ast_str **buf, ssize_t max_len, const
char *fmt, va_list ap),
1046 return _ast_str_helper(buf, max_len, 1, fmt, ap);
1053 return __ast_str_helper2(buf, maxlen, src, maxsrc, 0, 0);
1060 return __ast_str_helper2(buf, maxlen, src, maxsrc, 1, 0);
1067 return __ast_str_helper2(buf, maxlen, src, maxsrc, 0, 1);
1074 return __ast_str_helper2(buf, maxlen, src, maxsrc, 1, 1);
1101 int __attribute__((format(printf, 3, 4)))
ast_str_set(
1102 struct
ast_str **buf, ssize_t max_len, const
char *fmt, ...),
1128 struct
ast_str **buf, ssize_t max_len, const
char *fmt, ...),
1193 ast_free(STR_TMP); \
1209 if (*arg < '0' || *arg >
'9') {
1227 if (!dev_str || !strchr(dev_str,
'/')) {
1231 for (pos = dev_str; *pos && *pos !=
'/'; pos++) {
1232 *pos = toupper(*pos);
1248 return (
int) (hash & (
unsigned int) INT_MAX);
1261 unsigned int hash = 5381;
1264 hash = hash * 33 ^ (
unsigned char) *str++;
1287 unsigned int hash = (
unsigned int) seed;
1290 hash = hash * 33 ^ (
unsigned char) *str++;
1305 unsigned int hash = 5381;
1308 hash = hash * 33 ^ (
unsigned char) tolower(*str++);
1323 char *str_orig = str;
1328 for (; *str; ++str) {
1329 *str = tolower(*str);
1344 char *str_orig = str;
1349 for (; *str; ++str) {
1350 *str = toupper(*str);
1365 #define ast_str_container_alloc(buckets) ast_str_container_alloc_options(AO2_ALLOC_OPT_LOCK_MUTEX, buckets)
void ast_join_delim(char *s, size_t len, const char *const w[], unsigned int size, char delim)
Join an array of strings into a single string.
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
size_t ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
static int force_inline attribute_pure ast_ends_with(const char *str, const char *suffix)
Checks whether a string ends with another.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
char * ast_escape(char *dest, const char *s, size_t size, const char *to_escape)
Escape the 'to_escape' characters in the given string.
data for a thread locally stored variable
int ast_str_set_va(struct ast_str **buf, ssize_t max_len, const char *fmt, va_list ap)
Set a dynamic string from a va_list.
char * ast_str_append_escapecommas(struct ast_str **buf, ssize_t maxlen, const char *src, size_t maxsrc)
Append a non-NULL terminated substring to the end of a dynamic string, with escaping of commas...
void ast_str_container_remove(struct ao2_container *str_container, const char *remove)
Removes a string from a string container allocated by ast_str_container_alloc.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
char * ast_escape_c(char *dest, const char *s, size_t size)
Escape standard 'C' sequences in the given string.
Definitions to aid in the use of thread local storage.
int ast_get_timeval(const char *src, struct timeval *tv, struct timeval _default, int *consumed)
Parse a time (float) string.
char * ast_skip_nonblanks(const char *str)
Gets a pointer to first whitespace character in a string.
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
#define ast_str_tmp(init_len, __expr)
Provides a temporary ast_str and returns a copy of its buffer.
int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
Parse a time (integer) string.
char * ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
Strip leading/trailing whitespace and quotes from a string.
int ast_build_string(char **buffer, size_t *space, const char *fmt,...)
Build a string in a buffer, designed to be called repeatedly.
struct ao2_container * ast_str_container_alloc_options(enum ao2_alloc_opts opts, int buckets)
Allocates a hash container for bare strings.
#define ast_strdupa(s)
duplicate a string in memory from the stack
char * ast_str_append_substr(struct ast_str **buf, ssize_t maxlen, const char *src, size_t maxsrc)
Append a non-NULL terminated substring to the end of a dynamic string.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
static force_inline char * ast_str_to_lower(char *str)
Convert a string to all lower-case.
char * ast_escape_alloc(const char *s, const char *to_escape)
Escape the 'to_escape' characters in the given string.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
static force_inline char * ast_str_to_upper(char *str)
Convert a string to all upper-case.
ao2_alloc_opts
Options available when allocating an ao2 object.
char * ast_tech_to_upper(char *dev_str)
Convert the tech portion of a device string to upper case.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Support for dynamic strings.
char * ast_generate_random_string(char *buf, size_t size)
Create a pseudo-random string of a fixed length.
int ast_strings_equal(const char *str1, const char *str2)
Compare strings for equality checking for NULL.
int _ast_str_make_space(struct ast_str **buf, size_t new_len, const char *file, int lineno, const char *function)
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
char * ast_trim_blanks(char *str)
Trims trailing whitespace characters from a string.
int ast_regex_string_to_regex_pattern(const char *regex_string, struct ast_str **regex_pattern)
Given a string regex_string in the form of "/regex/", convert it into the form of "regex"...
static force_inline int ast_str_hash_add(const char *str, int seed)
Compute a hash value on a string.
char * ast_strsep_quoted(char **s, const char sep, const char quote, uint32_t flags)
Like ast_strsep() except you can specify a specific quote character.
ast_strsep_flags
Flags for ast_strsep.
char * ast_escape_c_alloc(const char *s)
Escape standard 'C' sequences in the given string.
int ast_str_append_va(struct ast_str **buf, ssize_t max_len, const char *fmt, va_list ap)
Append to a dynamic string using a va_list.
int ast_build_string_va(char **buffer, size_t *space, const char *fmt, va_list ap)
Build a string in a buffer, designed to be called repeatedly.
int ast_check_digits(const char *arg)
Check if a string is only digits.
char * ast_unescape_semicolon(char *s)
Strip backslash for "escaped" semicolons, the string to be stripped (will be modified).
char * ast_str_set_escapecommas(struct ast_str **buf, ssize_t maxlen, const char *src, size_t maxsrc)
Set a dynamic string to a non-NULL terminated substring, with escaping of commas. ...
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
struct ast_threadstorage * __AST_STR_TS
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
static force_inline int attribute_pure ast_str_hash_restrict(unsigned int hash)
Restrict hash value range.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
void ast_str_update(struct ast_str *buf)
Update the length of the buffer, after using ast_str merely as a buffer.
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
int ast_in_delimited_string(const char *needle, const char *haystack, char delim)
Check if there is an exact match for 'needle' between delimiters in 'haystack'.
int __ast_str_helper(struct ast_str **buf, ssize_t max_len, int append, const char *fmt, va_list ap, const char *file, int lineno, const char *func)
Core functionality of ast_str_(set|append)_va.
char * ast_str_set_substr(struct ast_str **buf, ssize_t maxlen, const char *src, size_t maxsrc)
Set a dynamic string to a non-NULL terminated substring.
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
void ast_str_trim_blanks(struct ast_str *buf)
Trims trailing whitespace characters from an ast_str string.
char * ast_to_camel_case_delim(const char *s, const char *delim)
Attempts to convert the given string to camel case using the specified delimiter. ...
int ast_str_container_add(struct ao2_container *str_container, const char *add)
Adds a string to a string container allocated by ast_str_container_alloc.
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
int ast_strings_match(const char *left, const char *op, const char *right)
Compares 2 strings using realtime-style operators.
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
char * ast_unescape_c(char *s)
Convert some C escape sequences.
char * ast_read_line_from_buffer(char **buffer)
Read lines from a string buffer.