summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin P. Fleming <kpfleming@digium.com>2006-01-06 19:19:17 +0000
committerKevin P. Fleming <kpfleming@digium.com>2006-01-06 19:19:17 +0000
commit1fe5108763b8a4bb9dede06afc33b5bd5266988a (patch)
tree1864ed197f7226117cb0d35e08b9dbd248135004
parentd44823b5b8bd40eaa25d3a78aa64768993a59bee (diff)
ensure that string field 'build' operation only evaluates arguments one time
fix some minor documentation errors return proper type from string field space allocator git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@7841 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--include/asterisk/stringfields.h31
-rw-r--r--utils.c25
2 files changed, 43 insertions, 13 deletions
diff --git a/include/asterisk/stringfields.h b/include/asterisk/stringfields.h
index 02811a611..5631682b2 100644
--- a/include/asterisk/stringfields.h
+++ b/include/asterisk/stringfields.h
@@ -143,8 +143,22 @@ int __ast_string_field_init(struct ast_string_field_pool *pool, size_t size,
and the existing fields stored there will be updated to point
into the new pool.
*/
-char *__ast_string_field_alloc_space(struct ast_string_field_pool *pool, size_t needed,
- ast_string_field *fields, int num_fields);
+ast_string_field __ast_string_field_alloc_space(struct ast_string_field_pool *pool, size_t needed,
+ ast_string_field *fields, int num_fields);
+
+/*!
+ \internal
+ \brief Set a field to a complex (built) value
+ \param pool Pointer to the pool structure
+ \param fields Pointer to the first entry of the field array
+ \param num_fields Number of fields in the array
+ \param index Index position of the field within the structure
+ \param format printf-style format string
+ \return nothing
+*/
+void __ast_string_field_index_build(struct ast_string_field_pool *pool,
+ ast_string_field *fields, int num_fields,
+ int index, const char *format, ...);
/*!
The default amount of storage to be allocated for a field pool.
@@ -216,23 +230,18 @@ char *__ast_string_field_alloc_space(struct ast_string_field_pool *pool, size_t
ast_string_field_index_set(x, ast_string_field_index(x, field), data)
/*!
- \brief Set a field to a simple complex (built) value
+ \brief Set a field to a complex (built) value
\param x Pointer to a structure containing fields
\param index Index position of the field within the structure
\param fmt printf-style format string
\param args Arguments for format string
\return nothing
*/
-#define ast_string_field_index_build(x, index, fmt, args...) do { \
- char s; \
- size_t needed; \
- needed = snprintf(&s, 1, fmt, args) + 1; \
- if ((x->__begin_field[index] = __ast_string_field_alloc_space(&x->__field_pool, needed, &x->__begin_field[0], ast_string_field_count(x)))) \
- sprintf((char *) x->__begin_field[index], fmt, args); \
- } while (0)
+#define ast_string_field_index_build(x, index, fmt, args...) \
+ __ast_string_field_index_build(&x->__field_pool, &x->__begin_field[0], ast_string_field_count(x), index, fmt, args)
/*!
- \brief Set a field to a simple complex (built) value
+ \brief Set a field to a complex (built) value
\param x Pointer to a structure containing fields
\param field Name of the field to set
\param fmt printf-style format string
diff --git a/utils.c b/utils.c
index df2e393eb..cc3510541 100644
--- a/utils.c
+++ b/utils.c
@@ -943,8 +943,8 @@ int __ast_string_field_init(struct ast_string_field_pool *pool, size_t size,
return pool->base ? 0 : -1;
}
-char *__ast_string_field_alloc_space(struct ast_string_field_pool *pool, size_t needed,
- ast_string_field *fields, int num_fields)
+ast_string_field __ast_string_field_alloc_space(struct ast_string_field_pool *pool, size_t needed,
+ ast_string_field *fields, int num_fields)
{
char *result = NULL;
@@ -974,3 +974,24 @@ char *__ast_string_field_alloc_space(struct ast_string_field_pool *pool, size_t
pool->space -= needed;
return result;
}
+
+void __ast_string_field_index_build(struct ast_string_field_pool *pool,
+ ast_string_field *fields, int num_fields,
+ int index, const char *format, ...)
+{
+ char s;
+ size_t needed;
+ va_list ap1, ap2;
+
+ va_start(ap1, format);
+ va_copy(ap2, ap1);
+
+ needed = vsnprintf(&s, 1, format, ap1) + 1;
+
+ va_end(ap1);
+
+ if ((fields[index] = __ast_string_field_alloc_space(pool, needed, fields, num_fields)))
+ vsprintf((char *) fields[index], format, ap2);
+
+ va_end(ap2);
+}