56 int append,
const char *fmt, va_list ap,
57 const char *
file,
int lineno,
const char *
function)
62 int offset = (append && (*buf)->__AST_STR_LEN) ? (*buf)->__AST_STR_USED : 0;
66 max_len = (*buf)->__AST_STR_LEN;
71 res = vsnprintf((*buf)->__AST_STR_STR + offset, (*buf)->__AST_STR_LEN - offset, fmt, aq);
90 need = offset + added + 1;
91 if (need <= (*buf)->__AST_STR_LEN
92 || (max_len && max_len <= (*buf)->__AST_STR_LEN)) {
103 need += 16 + need / 4;
104 }
else if (max_len < need) {
111 (
int) (*buf)->__AST_STR_LEN, need);
119 (*buf)->__AST_STR_USED = ((*buf)->__AST_STR_LEN <= offset + added)
120 ? (*buf)->__AST_STR_LEN - 1
124 (*buf)->__AST_STR_STR[(*buf)->__AST_STR_USED] =
'\0';
132 char *ptr = append ? &((*buf)->__AST_STR_STR[(*buf)->__AST_STR_USED]) : (*buf)->__AST_STR_STR;
138 maxlen = (*buf)->__AST_STR_LEN;
141 while (*src && maxsrc && maxlen && (!escapecommas || (maxlen - 1))) {
142 if (escapecommas && (*src ==
'\\' || *src ==
',')) {
145 (*buf)->__AST_STR_USED++;
150 (*buf)->__AST_STR_USED++;
152 if ((ptr >= (*buf)->__AST_STR_STR + (*buf)->__AST_STR_LEN - 3) ||
153 (dynamic && (!maxlen || (escapecommas && !(maxlen - 1))))) {
154 char *oldbase = (*buf)->__AST_STR_STR;
155 size_t old = (*buf)->__AST_STR_LEN;
163 ptr += (*buf)->__AST_STR_STR - oldbase;
166 if (__builtin_expect(!maxlen, 0)) {
170 return (*buf)->__AST_STR_STR;
173 static int str_hash(
const void *obj,
const int flags)
178 static int str_sort(
const void *lhs,
const void *rhs,
int flags)
181 return strncmp(lhs, rhs, strlen(rhs));
183 return strcmp(lhs, rhs);
187 static int str_cmp(
void *lhs,
void *rhs,
int flags)
192 cmp = strncmp(lhs, rhs, strlen(rhs));
194 cmp = strcmp(lhs, rhs);
215 strcpy(ao2_add, add);
231 for (i = 0; i < size - 1; ++i) {
241 if (!str1 || !str2) {
245 return str1 == str2 || !strcmp(str1, str2);
250 char *internal_op = (
char *)op;
251 char *internal_right = (
char *)right;
254 int scan_numeric = 0;
256 if (!(left && right)) {
265 if (strlen(right) >= 2 && right[0] ==
'/' && right[strlen(right) - 1] ==
'/') {
266 internal_op =
"regex";
270 internal_right[strlen(internal_right) - 1] =
'\0';
278 if (!strcasecmp(op,
"like")) {
282 if (!strchr(right,
'%')) {
283 return !strcmp(left, right);
285 internal_op =
"regex";
287 tok =
strsep(&internal_right,
"%");
290 while ((tok =
strsep(&internal_right,
"%"))) {
301 if (!strcasecmp(internal_op,
"regex")) {
305 if (regcomp(&expression, internal_right, REG_EXTENDED | REG_NOSUB)) {
309 rc = regexec(&expression, left, 0,
NULL, 0);
310 regfree(&expression);
315 scan_numeric = (sscanf(left,
"%lf", &left_num) > 0 && sscanf(internal_right,
"%lf", &right_num) > 0);
317 if (internal_op[0] ==
'=') {
323 return (left_num == right_num);
325 return (!strcmp(left, internal_right));
329 if (internal_op[0] ==
'!' && internal_op[1] ==
'=') {
331 return (left_num != right_num);
333 return !!strcmp(left, internal_right);
337 if (internal_op[0] ==
'<') {
339 if (internal_op[1] ==
'=') {
340 return (left_num <= right_num);
342 return (left_num < right_num);
345 if (internal_op[1] ==
'=') {
346 return strcmp(left, internal_right) <= 0;
348 return strcmp(left, internal_right) < 0;
353 if (internal_op[0] ==
'>') {
355 if (internal_op[1] ==
'=') {
356 return (left_num >= right_num);
358 return (left_num > right_num);
361 if (internal_op[1] ==
'=') {
362 return strcmp(left, internal_right) >= 0;
364 return strcmp(left, internal_right) > 0;
374 char *start = *buffer;
376 if (!buffer || !*buffer || *(*buffer) ==
'\0') {
380 while (*(*buffer) && *(*buffer) !=
'\n' ) {
385 if (*(*buffer - 1) ==
'\r') {
386 *(*buffer - 1) =
'\0';
394 const char *
input,
const char *delim,
int flags,
395 int (*excludes_cmp)(
const char *s1,
const char *s2))
410 while ((cur =
strsep(&buf, delim))) {
int ast_strings_match(const char *left, const char *op, const char *right)
Compares 2 strings using realtime-style operators.
int ast_vector_string_split(struct ast_vector_string *dest, const char *input, const char *delim, int flags, int(*excludes_cmp)(const char *s1, const char *s2))
Append a string vector by splitting a string.
Asterisk main include file. File version handling, generic pbx functions.
String manipulation functions.
The arg parameter is a search key, but is not an object.
#define ast_str_make_space(buf, new_len)
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
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.
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
#define ao2_alloc_options(data_size, destructor_fn, options)
#define ast_str_alloca(init_len)
#define ast_strdup(str)
A wrapper for strdup()
struct ao2_container * ast_str_container_alloc_options(enum ao2_alloc_opts opts, int buckets)
Allocates a hash container for bare strings.
static int input(yyscan_t yyscanner)
#define ast_strlen_zero(foo)
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
#define ao2_ref(o, delta)
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.
long int ast_random(void)
#define ast_strdupa(s)
duplicate a string in memory from the stack
static int str_cmp(void *lhs, void *rhs, int flags)
Core PBX routines and definitions.
static int str_sort(const void *lhs, const void *rhs, int flags)
void ast_log_safe(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message with protection against recursion.
ao2_alloc_opts
Options available when allocating an ao2 object.
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
int _ast_str_make_space(struct ast_str **buf, size_t new_len, const char *file, int lineno, const char *function)
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Vector container support.
#define ao2_find(container, arg, flags)
#define AST_VECTOR_GET_CMP(vec, value, cmp)
Get an element from a vector that matches the given comparison.
char * ast_generate_random_string(char *buf, size_t size)
Create a pseudo-random string of a fixed length.
char * ast_read_line_from_buffer(char **buffer)
Read lines from a string buffer.
int ast_strings_equal(const char *str1, const char *str2)
Compare strings for equality checking for NULL.
char * strsep(char **str, const char *delims)
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 *function)
Core functionality of ast_str_(set|append)_va.
Search option field mask.
char * __ast_str_helper2(struct ast_str **buf, ssize_t maxlen, const char *src, size_t maxsrc, int append, int escapecommas)
static int str_hash(const void *obj, const int flags)
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
#define ao2_link(container, obj)