#ifndef GRAS_DATADESC_H
#define GRAS_DATADESC_H
-#include "xbt/misc.h" /* BEGIN_DECL */
+#include "xbt/misc.h" /* SG_BEGIN_DECL */
+#include "xbt/dynar.h" /* void_f_pvoid_t */
-BEGIN_DECL()
+SG_BEGIN_DECL()
-/** @defgroup GRAS_dd Data description
+/** @addtogroup GRAS_dd Data description
* @brief Describing data to be exchanged (Communication facility)
*
* @section Overview
*
* There is several possible interfaces for this, ranging from the really completely automatic parsing to
* completely manual. Let's study each of them from the simplest to the more advanced.
+ *
+ * \warning At least, I would like to present those sections in the right order, but doxygen prevents me
+ * from doing so. There is a weird bug I fail to circumvent here. The right order is naturally:
+ * -# basic operations
+ * -# Automatic parsing
+ * -# Simple manual definitions
+ * -# Callback Persistant State: Simple push/pop mechanism
+ * -# Callback Persistant State: Full featured mechanism
*/
-
-/** @name a) basic operations
- * @ingroup GRAS_dd
+/* @{*/
+
+/** @name 1. basic operations
*
* If you only want to send pre-existing types, simply retrieve the pre-defined description with
* the \ref gras_datadesc_by_name function. Existing types entail:
gras_datadesc_type_t uc = gras_datadesc_by_name("unsigned char");
gras_datadesc_type_t str = gras_datadesc_by_name("string");\endverbatim
*/
-/** @{ */
+/* @{ */
/** @brief Opaque type describing a type description. */
typedef struct s_gras_datadesc_type *gras_datadesc_type_t;
/** \brief Search a type description from its name */
gras_datadesc_type_t gras_datadesc_by_name(const char *name);
-
-/** @} */
-
-/** @fn gras_datadesc_type_t gras_datadesc_parse(const char *name, const char *C_statement)
- * @ingroup GRAS_dd_implem
- *
- * Helper function doing the crude job of type parsing.
- */
-
-/** @name b) Automatic parsing
- * @ingroup GRAS_dd
+/* @} */
+
+/** @name 2. Automatic parsing
*
* If you need to declare a new datatype, this is the simplest way to describe it to GRAS. Simply
* enclose its type definition into a \ref GRAS_DEFINE_TYPE macro call, and you're set. Here is
* It specifies that the structure s_array contains two fields, and that the size of the array pointed
* by \a data is the \a length field, and that the \a father field is a simple reference.
*
- * If you cannot express your datadescs with this mecanism, you'll have to use the more advanced
+ * If you cannot express your datadescs with this mechanism, you'll have to use the more advanced
* (and somehow complex) one described below.
*
* \warning Since GRAS_DEFINE_TYPE is a macro, you shouldn't put any comma in your type definition
* (comma separates macro args).
*
* For example, change \verbatim int a, b;\endverbatim to \verbatim int a;
- int b:\endverbatim
+ int b;\endverbatim
*/
/** @{ */
-/** @def GRAS_DEFINE_TYPE
+/** @brief Automatically parse C code
* @hideinitializer
- * @brief Automatically parse C code
*/
-
-
#define GRAS_DEFINE_TYPE(name,def) \
static const char * _gras_this_type_symbol_does_not_exist__##name=#def; def
*/
#define GRAS_ANNOTE(key,val)
-/*@}*/
+/* @} */
gras_datadesc_type_t
gras_datadesc_parse(const char *name, const char *C_statement);
-/** @name c) Simple manual definitions
- * @ingroup GRAS_dd
+/** @name 3. Simple manual definitions
*
* Here are the functions to use if you want to declare your description manually.
* The function names should be self-explanatory in most cases.
*
* If your types are dynamic, you'll need to add some extra callback. For example, there is a
* specific callback for the string type which is in charge of computing the length of the char
- * array. This is done with the cbps mecanism, explained in next section.
+ * array. This is done with the cbps mechanism, explained in next section.
*
* If your types may contain pointer cycle, you must specify it to GRAS using the @ref gras_datadesc_cycle_set.
*
[Use my_type to send pointers to mystruct data]\endverbatim
*/
-/*@{*/
+/* @{ */
/** \brief Opaque type describing a type description callback persistant state. */
/* callbacks prototypes */
/** \brief Prototype of type callbacks returning nothing. */
-typedef void (*gras_datadesc_type_cb_void_t)(gras_cbps_t vars, void *data);
+typedef void (*gras_datadesc_type_cb_void_t)(gras_datadesc_type_t typedesc, gras_cbps_t vars, void *data);
/** \brief Prototype of type callbacks returning an int. */
-typedef int (*gras_datadesc_type_cb_int_t)(gras_cbps_t vars, void *data);
+typedef int (*gras_datadesc_type_cb_int_t)(gras_datadesc_type_t typedesc, gras_cbps_t vars, void *data);
/** \brief Prototype of type callbacks selecting a type. */
-typedef gras_datadesc_type_t (*gras_datadesc_selector_t)(gras_cbps_t vars, void *data);
+typedef gras_datadesc_type_t (*gras_datadesc_selector_t)(gras_datadesc_type_t typedesc, gras_cbps_t vars, void *data);
/******************************************
**** Declare datadescription yourself ****
******************************************/
-/** \brief Declare a new structure description */
gras_datadesc_type_t gras_datadesc_struct(const char *name);
+void gras_datadesc_struct_append(gras_datadesc_type_t struct_type,
+ const char *name,
+ gras_datadesc_type_t field_type);
+void gras_datadesc_struct_close(gras_datadesc_type_t struct_type);
-/** \brief Append a new field to a structure description */
-void
- gras_datadesc_struct_append(gras_datadesc_type_t struct_type,
- const char *name,
- gras_datadesc_type_t field_type);
-/** \brief Close a structure description */
-void
- gras_datadesc_struct_close(gras_datadesc_type_t struct_type);
-/** \brief Declare a new union description */
-gras_datadesc_type_t
- gras_datadesc_union(const char *name,
- gras_datadesc_type_cb_int_t selector);
-/** \brief Append a new field to an union description */
-void
- gras_datadesc_union_append(gras_datadesc_type_t union_type,
- const char *name,
- gras_datadesc_type_t field_type);
-/** \brief Close an union description */
-void
- gras_datadesc_union_close(gras_datadesc_type_t union_type);
+gras_datadesc_type_t gras_datadesc_union(const char *name,
+ gras_datadesc_type_cb_int_t selector);
+void gras_datadesc_union_append(gras_datadesc_type_t union_type,
+ const char *name,
+ gras_datadesc_type_t field_type);
+void gras_datadesc_union_close(gras_datadesc_type_t union_type);
-/** \brief Declare a new type being a reference to the one passed in arg */
gras_datadesc_type_t
- gras_datadesc_ref(const char *name,
- gras_datadesc_type_t referenced_type);
-/** \brief Declare a new type being a generic reference. */
+ gras_datadesc_ref(const char *name,
+ gras_datadesc_type_t referenced_type);
gras_datadesc_type_t
- gras_datadesc_ref_generic(const char *name,
- gras_datadesc_selector_t selector);
+ gras_datadesc_ref_generic(const char *name,
+ gras_datadesc_selector_t selector);
-/** \brief Declare a new type being an array of fixed size and content */
gras_datadesc_type_t
- gras_datadesc_array_fixed(const char *name,
- gras_datadesc_type_t element_type,
- long int fixed_size);
-
-/** \brief Declare a new type being an array of fixed size, but accepting several content types. */
+ gras_datadesc_array_fixed(const char *name,
+ gras_datadesc_type_t element_type,
+ long int fixed_size);
gras_datadesc_type_t
gras_datadesc_array_dyn(const char *name,
gras_datadesc_type_t element_type,
gras_datadesc_type_cb_int_t dynamic_size);
-
-/** \brief Declare a new type being an array which size can be found with \ref gras_cbps_i_pop */
gras_datadesc_type_t
gras_datadesc_ref_pop_arr(gras_datadesc_type_t element_type);
+gras_datadesc_type_t
+ gras_datadesc_dynar(gras_datadesc_type_t elm_t,
+ void_f_pvoid_t *free_func);
+
/*********************************
* Change stuff within datadescs *
*********************************/
* Get stuff within datadescs *
******************************/
/** \brief Returns the name of a datadescription */
-char * gras_datadesc_get_name(gras_datadesc_type_t ddt);
+const char * gras_datadesc_get_name(gras_datadesc_type_t ddt);
/** \brief Returns the identifier of a datadescription */
int gras_datadesc_get_id(gras_datadesc_type_t ddt);
-/*@}*/
+/* @} */
-/** @name Callback Persistant State: Simple push/pop mecanism
- * @ingroup GRAS_dd
+/** @name 4. Callback Persistant State: Simple push/pop mechanism
*
* Sometimes, one of the callbacks need to leave information for the next ones. If this is a simple integer (such as
* an array size), you can use the functions described here. If not, you'll have to play with the complete cbps interface.
+ *
+ * Here is an example:\verbatim
+struct s_array {
+ int length;
+ int *data;
+}
+[...]
+my_type=gras_datadesc_struct("s_array");
+gras_datadesc_struct_append(my_type,"length", gras_datadesc_by_name("int"));
+gras_datadesc_cb_field_send (my_type, "length", gras_datadesc_cb_push_int);
+
+gras_datadesc_struct_append(my_type,"data",
+ gras_datadesc_array_dyn ("s_array::data",gras_datadesc_by_name("int"), gras_datadesc_cb_pop));
+gras_datadesc_struct_close(my_type);
+\endverbatim
+
*/
-/*@{*/
+/* @{ */
void
gras_cbps_i_push(gras_cbps_t ps, int val);
int
gras_cbps_i_pop(gras_cbps_t ps);
-int gras_datadesc_cb_pop(gras_cbps_t vars, void *data);
-void gras_datadesc_cb_push_int(gras_cbps_t vars, void *data);
-void gras_datadesc_cb_push_uint(gras_cbps_t vars, void *data);
-void gras_datadesc_cb_push_lint(gras_cbps_t vars, void *data);
-void gras_datadesc_cb_push_ulint(gras_cbps_t vars, void *data);
+int gras_datadesc_cb_pop(gras_datadesc_type_t typedesc, gras_cbps_t vars, void *data);
+void gras_datadesc_cb_push_int(gras_datadesc_type_t typedesc, gras_cbps_t vars, void *data);
+void gras_datadesc_cb_push_uint(gras_datadesc_type_t typedesc, gras_cbps_t vars, void *data);
+void gras_datadesc_cb_push_lint(gras_datadesc_type_t typedesc, gras_cbps_t vars, void *data);
+void gras_datadesc_cb_push_ulint(gras_datadesc_type_t typedesc, gras_cbps_t vars, void *data);
-/*@}*/
+/* @} */
-/** @name Callback Persistant State: Full featured mecanism
- * @ingroup GRAS_dd
+/** @name 5. Callback Persistant State: Full featured mechanism
*
- * Sometimes, one of the callbacks need to leave information for the next ones. If the simple push/pop mecanism
+ * Sometimes, one of the callbacks need to leave information for the next ones. If the simple push/pop mechanism
* introduced in previous section isn't enough, you can always use this full featured one.
*/
-/*@{*/
-
-xbt_error_t
- gras_cbps_v_pop (gras_cbps_t ps,
- const char *name,
- /* OUT */ gras_datadesc_type_t *ddt,
- /* OUT */ void **res);
-xbt_error_t
-gras_cbps_v_push(gras_cbps_t ps,
- const char *name,
- void *data,
- gras_datadesc_type_t ddt);
-void
-gras_cbps_v_set (gras_cbps_t ps,
- const char *name,
- void *data,
- gras_datadesc_type_t ddt);
+/* @{ */
-void *
-gras_cbps_v_get (gras_cbps_t ps,
- const char *name,
- /* OUT */ gras_datadesc_type_t *ddt);
+void gras_cbps_v_pop (gras_cbps_t ps,
+ const char *name,
+ /* OUT */ gras_datadesc_type_t *ddt,
+ /* OUT */ void **res);
+void gras_cbps_v_push(gras_cbps_t ps,
+ const char *name,
+ void *data,
+ gras_datadesc_type_t ddt);
+void gras_cbps_v_set (gras_cbps_t ps,
+ const char *name,
+ void *data,
+ gras_datadesc_type_t ddt);
-void
-gras_cbps_block_begin(gras_cbps_t ps);
-void
-gras_cbps_block_end(gras_cbps_t ps);
+void * gras_cbps_v_get (gras_cbps_t ps,
+ const char *name,
+ /* OUT */ gras_datadesc_type_t *ddt);
+
+void gras_cbps_block_begin(gras_cbps_t ps);
+void gras_cbps_block_end(gras_cbps_t ps);
/* @} */
+/* @} */
/*******************************
DataTypes;
#define SIMPLE_TYPE_COUNT 9
-/*! \brief Describe a collection of data.
+/** \brief Describe a collection of data.
*
-** A description of a collection of #type# data. #repetitions# is used only
-** for arrays; it contains the number of elements. #offset# is used only for
+** A description of a collection of \a type data. \a repetitions is used only
+** for arrays; it contains the number of elements. \a offset is used only for
** struct members in host format; it contains the offset of the member from the
** beginning of the struct, taking into account internal padding added by the
-** compiler for alignment purposes. #members#, #length#, and #tailPadding# are
-** used only for STRUCT_TYPE data; the #length#-long array #members# describes
-** the members of the nested struct, and #tailPadding# indicates how many
+** compiler for alignment purposes. \a members, \a length, and \a tailPadding are
+** used only for STRUCT_TYPE data; the \a length -long array \a members describes
+** the members of the nested struct, and \a tailPadding indicates how many
** padding bytes the compiler adds to the end of the structure.
*/
sizeof(structType) - offsetof(structType, lastMember) - \
sizeof(memberType) * repetitions
-xbt_error_t
+gras_datadesc_type_t
gras_datadesc_import_nws(const char *name,
const DataDescriptor *desc,
- unsigned long howmany,
- /* OUT */ gras_datadesc_type_t *dst);
+ unsigned long howmany);
-END_DECL()
+SG_END_DECL()
#endif /* GRAS_DATADESC_H */