SAF_Field *
_saf_find_parent_field(SAF_ParMode pmode,
SAF_Field *component_field, /* Field for which we are searching for a parent. */
SAF_Field *retval /* [OUT] Optional buffer in which to store the result. If this is NULL
* then a buffer will be allocated for the return value. */
)
{
SAF_ENTER(_saf_find_parent_field, SAF_ERROR_FIELD);
int nfound=0;
SAF_Field *fields=NULL, *component_fields;
int i, j, num_comps;
SAF_Db db;
SAF_REQUIRE(_saf_valid_pmode(pmode), SAF_LOW_CHK_COST, NULL,
_saf_errmsg("PMODE must be valid"));
if (!_saf_is_participating_proc(pmode)) SAF_RETURN(NULL);
/* Get the file to which the component_field belongs */
ss_pers_file((ss_pers_t*)component_field, &db);
if (SS_PERS_ISNULL(SS_FIELD_P(component_field,m.parent))) {
saf_find_fields(pmode, &db, NULL, NULL, NULL, NULL, NULL, NULL, NULL, SAF_ANY_RATIO, NULL, NULL, &nfound, &fields);
for(i=0; i<nfound; i++) {
component_fields=NULL;
num_comps=0;
{
/* JSJ - Check if this field is a STATE, and if so, skip the saf_describe_field. Calling saf_describe_field
* for a STATE field causes an error. This section should be removed when either saf_describe_field is fixed
* (if this is indeed an error) or when you can use saf_find_fields to find all-alg-types-except-fields, or ? */
SAF_FieldTmpl l_ftmpl;
SAF_Algebraic l_alg_type;
saf_describe_field(pmode, fields+i, &l_ftmpl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL);
saf_describe_field_tmpl(pmode, &l_ftmpl, NULL, &l_alg_type, NULL, NULL, NULL, NULL);
if (SAF_EQUIV(&l_alg_type,SAF_ALGTYPE_FIELD)) continue;
}
saf_describe_field(pmode, fields+i, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
&num_comps, &component_fields, NULL, NULL);
if (num_comps>1) {
SS_FIELD(fields+i)->m.parent = fields[i];
for (j=0; j<num_comps; j++) {
SS_FIELD(component_fields+j)->m.parent = fields[i];
}
}
component_fields = SS_FREE(component_fields);
}
}
if (!retval && NULL==(retval=malloc(sizeof *retval)))
SAF_ERROR(NULL, _saf_errmsg("unable to allocate return value"));
*retval = SS_FIELD(component_field)->m.parent;
SAF_LEAVE(retval);
}