This commit folds in changes to both stringfields (some enhancements to the ...field_...
[asterisk/asterisk.git] / include / asterisk / stringfields.h
index 22e066d..9b5fbc6 100644 (file)
@@ -47,7 +47,7 @@
   
   sample = calloc(1, sizeof(*sample));
   if (sample) {
   
   sample = calloc(1, sizeof(*sample));
   if (sample) {
-         if (!ast_string_field_init(sample)) {
+         if (ast_string_field_init(sample, 256)) {
                  free(sample);
                  sample = NULL;
          }
                  free(sample);
                  sample = NULL;
          }
@@ -103,7 +103,7 @@ typedef const char * ast_string_field;
   \internal
   \brief A constant empty string used for fields that have no other value
 */
   \internal
   \brief A constant empty string used for fields that have no other value
 */
-extern const char *__ast_string_field_empty;
+extern const char __ast_string_field_empty[];
 
 /*!
   \internal
 
 /*!
   \internal
@@ -132,7 +132,7 @@ struct ast_string_field_mgr {
   \param size Amount of storage to allocate
   \param fields Pointer to the first entry of the field array
   \param num_fields Number of fields in the array
   \param size Amount of storage to allocate
   \param fields Pointer to the first entry of the field array
   \param num_fields Number of fields in the array
-  \return 0 on failure, non-zero on success
+  \return 0 on success, non-zero on failure
 */
 int __ast_string_field_init(struct ast_string_field_mgr *mgr, size_t size,
                            ast_string_field *fields, int num_fields);
 */
 int __ast_string_field_init(struct ast_string_field_mgr *mgr, size_t size,
                            ast_string_field *fields, int num_fields);
@@ -168,15 +168,10 @@ void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
                                    int index, const char *format, ...);
 
 /*!
                                    int index, const char *format, ...);
 
 /*!
-  The default amount of storage to be allocated for a field pool.
-*/
-#define AST_STRING_FIELD_DEFAULT_POOL 512
-
-/*!
   \brief Declare a string field
   \param name The field name
 */
   \brief Declare a string field
   \param name The field name
 */
-#define AST_STRING_FIELD(name) const ast_string_field name;
+#define AST_STRING_FIELD(name) const ast_string_field name
 
 /*!
   \brief Declare the fields needed in a structure
 
 /*!
   \brief Declare the fields needed in a structure
@@ -186,7 +181,7 @@ void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
        ast_string_field __begin_field[0]; \
        field_list \
        ast_string_field __end_field[0]; \
        ast_string_field __begin_field[0]; \
        field_list \
        ast_string_field __end_field[0]; \
-       struct ast_string_field_mgr __field_mgr;
+       struct ast_string_field_mgr __field_mgr
 
 /*!
   \brief Get the number of string fields in a structure
 
 /*!
   \brief Get the number of string fields in a structure
@@ -194,7 +189,7 @@ void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
   \return the number of fields in the structure's definition
 */
 #define ast_string_field_count(x) \
   \return the number of fields in the structure's definition
 */
 #define ast_string_field_count(x) \
-       (offsetof(typeof(*x), __end_field) - offsetof(typeof(*x), __begin_field)) / sizeof(ast_string_field)
+       (offsetof(typeof(*(x)), __end_field) - offsetof(typeof(*(x)), __begin_field)) / sizeof(ast_string_field)
 
 /*!
   \brief Get the index of a field in a structure
 
 /*!
   \brief Get the index of a field in a structure
@@ -209,10 +204,11 @@ void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
 /*!
   \brief Initialize a field pool and fields
   \param x Pointer to a structure containing fields
 /*!
   \brief Initialize a field pool and fields
   \param x Pointer to a structure containing fields
-  \return 0 on failure, non-zero on success
+  \param size Amount of storage to allocate
+  \return 0 on success, non-zero on failure
 */
 */
-#define ast_string_field_init(x) \
-       __ast_string_field_init(&x->__field_mgr, AST_STRING_FIELD_DEFAULT_POOL, &x->__begin_field[0], ast_string_field_count(x))
+#define ast_string_field_init(x, size) \
+       __ast_string_field_init(&(x)->__field_mgr, size, &(x)->__begin_field[0], ast_string_field_count(x))
 
 /*!
   \brief Set a field to a simple string value
 
 /*!
   \brief Set a field to a simple string value
@@ -222,10 +218,36 @@ void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
   \return nothing
 */
 #define ast_string_field_index_set(x, index, data) do { \
   \return nothing
 */
 #define ast_string_field_index_set(x, index, data) do { \
-       if ((x->__begin_field[index] = __ast_string_field_alloc_space(&x->__field_mgr, strlen(data) + 1, &x->__begin_field[0], ast_string_field_count(x)))) \
-               strcpy((char *) x->__begin_field[index], data); \
-       } while (0)
+    char *__zz__ = (char*)(x)->__begin_field[index]; \
+    int __dlen__ = strlen(data); \
+    if( __dlen__ == 0 ) { (x)->__begin_field[index] = __ast_string_field_empty; \
+    } else { \
+     if( __zz__[0] != 0 && __dlen__ <= strlen(__zz__) ) { \
+          strcpy(__zz__, data); \
+     } else { \
+       if (((x)->__begin_field[index] = __ast_string_field_alloc_space(&(x)->__field_mgr, __dlen__ + 1, &(x)->__begin_field[0], ast_string_field_count(x)))) \
+              strcpy((char*)(x)->__begin_field[index], data); \
+        } \
+       } \
+   } while (0)
 
 
+#ifdef FOR_TEST
+#define ast_string_field_index_logset(x, index, data, logstr) do { \
+    char *__zz__ = (char*)(x)->__begin_field[index]; \
+    int __dlen__ = strlen(data); \
+    if( __dlen__ == 0 ) { (x)->__begin_field[index] = __ast_string_field_empty; \
+    } else { \
+     if( __zz__[0] != 0 && __dlen__ <= strlen(__zz__) ) { \
+       ast_verbose("%s: ======replacing '%s' with '%s'\n", logstr, __zz__, data); \
+          strcpy(__zz__, data); \
+     } else { \
+       ast_verbose("%s: ++++++allocating room for '%s' to replace '%s'\n", logstr, data, __zz__); \
+       if (((x)->__begin_field[index] = __ast_string_field_alloc_space(&(x)->__field_mgr, __dlen__ + 1, &(x)->__begin_field[0], ast_string_field_count(x)))) \
+              strcpy((char*)(x)->__begin_field[index], data); \
+        } \
+       } \
+   } while (0)
+#endif
 /*!
   \brief Set a field to a simple string value
   \param x Pointer to a structure containing fields
 /*!
   \brief Set a field to a simple string value
   \param x Pointer to a structure containing fields
@@ -236,6 +258,10 @@ void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
 #define ast_string_field_set(x, field, data) \
        ast_string_field_index_set(x, ast_string_field_index(x, field), data)
 
 #define ast_string_field_set(x, field, data) \
        ast_string_field_index_set(x, ast_string_field_index(x, field), data)
 
+#ifdef FOR_TEST
+#define ast_string_field_logset(x, field, data, logstr) \
+       ast_string_field_index_logset(x, ast_string_field_index(x, field), data, logstr)
+#endif
 /*!
   \brief Set a field to a complex (built) value
   \param x Pointer to a structure containing fields
 /*!
   \brief Set a field to a complex (built) value
   \param x Pointer to a structure containing fields
@@ -245,7 +271,7 @@ void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
   \return nothing
 */
 #define ast_string_field_index_build(x, index, fmt, args...) \
   \return nothing
 */
 #define ast_string_field_index_build(x, index, fmt, args...) \
-       __ast_string_field_index_build(&x->__field_mgr, &x->__begin_field[0], ast_string_field_count(x), index, fmt, args)
+       __ast_string_field_index_build(&(x)->__field_mgr, &(x)->__begin_field[0], ast_string_field_count(x), index, fmt, args)
 
 /*!
   \brief Set a field to a complex (built) value
 
 /*!
   \brief Set a field to a complex (built) value
@@ -269,7 +295,7 @@ void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
   pointer is just changed to point to an empty string.
 */
 #define ast_string_field_index_free(x, index) do { \
   pointer is just changed to point to an empty string.
 */
 #define ast_string_field_index_free(x, index) do { \
-       x->__begin_field[index] = __ast_string_field_empty; \
+       (x)->__begin_field[index] = __ast_string_field_empty; \
        } while(0)
 
 /*!
        } while(0)
 
 /*!
@@ -299,7 +325,7 @@ void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
        struct ast_string_field_pool *this, *prev; \
        for (index = 0; index < ast_string_field_count(x); index ++) \
                ast_string_field_index_free(x, index); \
        struct ast_string_field_pool *this, *prev; \
        for (index = 0; index < ast_string_field_count(x); index ++) \
                ast_string_field_index_free(x, index); \
-       for (this = x->__field_mgr.pool; this; this = prev) { \
+       for (this = (x)->__field_mgr.pool; this; this = prev) { \
                prev = this->prev; \
                free(this); \
        } \
                prev = this->prev; \
                free(this); \
        } \