== AsteriskSource/AstMacro == * AST_DECLARE_APP_ARGS {{{ /*! \brief Declare a structure to hold the application's arguments. \param name The name of the structure \param arglist The list of arguments, defined using AST_APP_ARG This macro defines a structure intended to be used in a call to ast_app_separate_args(). The structure includes all the arguments specified, plus an argv array that overlays them and an argc argument counter. The arguments must be declared using AST_APP_ARG, and they will all be character pointers (strings). \note The structure is not initialized, as the call to ast_app_separate_args() will perform that function before parsing the arguments. */ #define AST_DECLARE_APP_ARGS(name, arglist) \ struct { \ unsigned int argc; \ char *argv[0]; \ arglist \ } name }}} * AST_NONSTANDARD_APP_ARGS {{{ /*! \brief Performs the 'nonstandard' argument separation process for an application. \param args An argument structure defined using AST_DECLARE_APP_ARGS \param parse A modifiable buffer containing the input to be parsed \param sep A nonstandard separator character This function will separate the input string using the nonstandard argument separator character and fill in the provided structure, including the argc argument counter field. */ #define AST_NONSTANDARD_APP_ARGS(args, parse, sep) \ args.argc = ast_app_separate_args(parse, sep, args.argv, ((sizeof(args) - offsetof(typeof(args), argv)) / sizeof(args.argv[0]))) }}} * ast_app_separate_args {{{ /*! \brief Separate a string into arguments in an array \param buf The string to be parsed (this must be a writable copy, as it will be modified) \param delim The character to be used to delimit arguments \param array An array of 'char *' to be filled in with pointers to the found arguments \param arraylen The number of elements in the array (i.e. the number of arguments you will accept) Note: if there are more arguments in the string than the array will hold, the last element of the array will contain the remaining arguments, not separated. The array will be completely zeroed by this function before it populates any entries. \return The number of arguments found, or zero if the function arguments are not valid. */ unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen); }}} * ao2_ref {{{ /*! * Reference/unreference an object and return the old refcount. * * \param o A pointer to the object * \param delta Value to add to the reference counter. * \return The value of the reference counter before the operation. * * Increase/decrease the reference counter according * the value of delta. * * If the refcount goes to zero, the object is destroyed. * * \note The object must not be locked by the caller of this function, as * it is invalid to try to unlock it after releasing the reference. * * \note if we know the pointer to an object, it is because we * have a reference count to it, so the only case when the object * can go away is when we release our reference, and it is * the last one in existence. */ int ao2_ref(void *o, int delta); }}} * ao2_link {{{ /*! * \brief Add an object to a container. * * \param c the container to operate on. * \param newobj the object to be added. * * \return NULL on errors, other values on success. * * This function inserts an object in a container according its key. * * \note Remember to set the key before calling this function. * * \note This function automatically increases the reference count to * account for the reference to the object that the container now holds. * * For Asterisk 1.4 only, there is a dirty hack here to ensure that chan_iax2 * can have objects linked in to the container at the head instead of tail * when it is just a linked list. This is to maintain some existing behavior * where the order must be maintained as it was before this conversion so that * matching behavior doesn't change. */ #define ao2_link(c, o) __ao2_link(c, o, 0) void *__ao2_link(struct ao2_container *c, void *newobj, int iax2_hack); }}} * ao2_iterator {{{ /*! * When we need to walk through a container, we use * ao2_iterator to keep track of the current position. * * Because the navigation is typically done without holding the * lock on the container across the loop, * objects can be inserted or deleted or moved * while we work. As a consequence, there is no guarantee that * the we manage to touch all the elements on the list, or it * is possible that we touch the same object multiple times. * However, within the current hash table container, the following is true: * - It is not possible to miss an object in the container while iterating * unless it gets added after the iteration begins and is added to a bucket * that is before the one the current object is in. In this case, even if * you locked the container around the entire iteration loop, you still would * not see this object, because it would still be waiting on the container * lock so that it can be added. * - It would be extremely rare to see an object twice. The only way this can * happen is if an object got unlinked from the container and added again * during the same iteration. Furthermore, when the object gets added back, * it has to be in the current or later bucket for it to be seen again. * * An iterator must be first initialized with ao2_iterator_init(), * then we can use o = ao2_iterator_next() to move from one * element to the next. Remember that the object returned by * ao2_iterator_next() has its refcount incremented, * and the reference must be explicitly released when done with it. * * Example: * struct ao2_container *c = ... // the container we want to iterate on * struct ao2_iterator i; * struct my_obj *o; * * i = ao2_iterator_init(c, flags); * * while ( (o = ao2_iterator_next(&i)) ) { * ... do something on o ... * ao2_ref(o, -1); * } }}} * AST_LIST_HEAD_STATIC {{{ /*! \brief Defines a structure to be used to hold a list of specified type, statically initialized. \param name This will be the name of the defined structure. \param type This is the type of each list entry. This macro creates a structure definition that can be used to hold a list of the entries of type \a type, and allocates an instance of it, initialized to be empty. Example usage: \code static AST_LIST_HEAD_STATIC(entry_list, entry); \endcode This would define \c struct \c entry_list, intended to hold a list of type \c struct \c entry. */ }}} * AST_LIST_TRAVERSE {{{ /*! \brief Loops over (traverses) the entries in a list. \param head This is a pointer to the list head structure \param var This is the name of the variable that will hold a pointer to the current list entry on each iteration. It must be declared before calling this macro. \param field This is the name of the field (declared using AST_LIST_ENTRY()) used to link entries of this list together. This macro is use to loop over (traverse) the entries in a list. It uses a \a for loop, and supplies the enclosed code with a pointer to each list entry as it loops. It is typically used as follows: \code static AST_LIST_HEAD(entry_list, list_entry) entries; ... struct list_entry { ... AST_LIST_ENTRY(list_entry) list; } ... struct list_entry *current; ... AST_LIST_TRAVERSE(&entries, current, list) { (do something with current here) } \endcode \warning If you modify the forward-link pointer contained in the \a current entry while inside the loop, the behavior will be unpredictable. At a minimum, the following macros will modify the forward-link pointer, and should not be used inside AST_LIST_TRAVERSE() against the entry pointed to by the \a current pointer without careful consideration of their consequences: \li AST_LIST_NEXT() (when used as an lvalue) \li AST_LIST_INSERT_AFTER() \li AST_LIST_INSERT_HEAD() \li AST_LIST_INSERT_TAIL() */ }}} * AST_LIST_ENTRY {{{ /*! \brief Inserts a list entry at the head of a list. \param head This is a pointer to the list head structure \param elm This is a pointer to the entry to be inserted. \param field This is the name of the field (declared using AST_LIST_ENTRY()) used to link entries of this list together. */ }}}