int
saf_describe_set(SAF_ParMode pmode, /* The parallel mode. */
SAF_Set *set, /* The set to be described. */
char **name, /* [OUT] The returned name of the set. Pass NULL if you do not want this
* information returned (see Returned Strings). */
int *max_topo_dim, /* [OUT] The topological dimension of the set. A NULL pointer can be passed if the caller is
* not interested in obtaining this information. */
SAF_SilRole *role, /* [OUT] The subset inclusion lattice role of the set. A NULL pointer can be passed if the
* caller is not interested in obtaining this information. */
SAF_ExtendMode *extmode,/* [OUT] Whether the set is extendible or not. A NULL pointer can be passed if the
* caller is not interested in obtaining this information. */
SAF_TopMode *topmode, /* [OUT] Whether the set is a top-level set in the SIL or not */
int *num_colls, /* [OUT] The number of collections currently defined on the set. A NULL pointer can be
* passed if the caller is not interested in obtaining this information. */
SAF_Cat **cats /* [OUT] The list of collection categories of the collections defined on the set. A NULL
* pointer can be passed if the caller is not interested in obtaining this
* information. CATS should point to the NULL pointer if the client wants the library
* to allocate space, otherwise CATS should point to something allocated by the
* caller. In the latter case, the input value of NUM_COLLS indicates the number of
* handles the CATS argument can hold. */
)
{
SAF_ENTER(saf_describe_set, SAF_PRECONDITION_ERROR);
size_t n=0, i;
ss_collection_t *colls=NULL;
SAF_REQUIRE(_saf_valid_pmode(pmode), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("PMODE must be valid"));
if (!_saf_is_participating_proc(pmode)) SAF_RETURN(-1);
SAF_REQUIRE(SS_SET(set), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("SET must be a valid set handle"));
SAF_REQUIRE(!cats || num_colls, SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("NUM_COLLS must be returned if CATS is requested"));
/* Return what was requested by the client. */
n = ss_array_nelmts(SS_SET_P(set,colls));
if (_saf_setupReturned_string(name, ss_string_ptr(SS_SET_P(set,name))) != SAF_SUCCESS)
SAF_ERROR(SAF_MEMORY_ERROR,_saf_errmsg("unable to return set name for set %s\n", ss_string_ptr(SS_SET_P(set,name))));
if (max_topo_dim) *max_topo_dim = SS_SET(set)->tdim;
if (role) *role = SS_SET(set)->srole;
if (topmode) *topmode = (SAF_TopMode) SS_SET(set)->is_top;
if (extmode) *extmode = (SAF_ExtendMode) SS_SET(set)->is_extendible;
if (cats && n>0) {
/* If the collections categories are to be returned and any were found either allocated storage for them or verify that
* any client supplied storage is sufficient and fill the returned cat handles. */
if (!*cats) {
*cats = calloc(n, sizeof(**cats));
if (!*cats)
SAF_ERROR(SAF_MEMORY_ERROR,_saf_errmsg("unable allocate memory for categories"));
} else if (*num_colls<(int)n) {
SAF_ERROR(SAF_MEMORY_ERROR,_saf_errmsg("client allocated mem, %i, too small for returned cats, %i", *num_colls, n));
}
colls = malloc(n*sizeof(*colls));
ss_array_get(SS_SET_P(set,colls), ss_pers_tm, (size_t)0, n, colls);
for (i=0; i<n; i++) {
(*cats)[i] = SS_COLLECTION(colls+i)->cat;
}
colls = SS_FREE(colls);
}
if (num_colls) *num_colls = n;
SAF_LEAVE(SAF_SUCCESS);
}