~SelelemTemporaryValueAssigner() { if (sel_ != NULL) { _gmx_selvalue_setstore_alloc(&sel_->v, old_ptr_, old_nalloc_); } }
/*! * \param[in] data Data for the current frame. * \param[in] sel Selection element being evaluated. * \param[in] g Group for which \p sel should be evaluated. * \returns 0 for success. * * Sets the value pointers of the child and its child to point to the same * memory as the value pointer of this element to avoid copying, and then * evaluates evaluates the child. * * This function is used as \c t_selelem:evaluate for \ref SEL_SUBEXPRREF * elements for which the \ref SEL_SUBEXPR does not have other references. */ void _gmx_sel_evaluate_subexprref_simple(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g) { if (g) { _gmx_selvalue_setstore(&sel->child->v, sel->v.u.ptr); _gmx_selvalue_setstore_alloc(&sel->child->child->v, sel->v.u.ptr, sel->child->child->v.nalloc); sel->child->evaluate(data, sel->child, g); } sel->v.nr = sel->child->v.nr; if (sel->u.param) { sel->u.param->val.nr = sel->v.nr; if (sel->u.param->nvalptr) { *sel->u.param->nvalptr = sel->u.param->val.nr; } } }
/*! \brief * Parses the values for a parameter that takes integer or real ranges. * * \param[in] nval Number of values in \p values. * \param[in] values Pointer to the list of values. * \param param Parameter to parse. * \returns TRUE if the values were parsed successfully, FALSE otherwise. */ static gmx_bool parse_values_range(int nval, t_selexpr_value *values, gmx_ana_selparam_t *param) { t_selexpr_value *value; int *idata; real *rdata; int i, j, n; param->flags &= ~SPAR_DYNAMIC; if (param->val.type != INT_VALUE && param->val.type != REAL_VALUE) { gmx_bug("internal error"); return FALSE; } idata = NULL; rdata = NULL; if (param->val.type == INT_VALUE) { snew(idata, nval*2); } else { snew(rdata, nval*2); } value = values; i = 0; while (value) { if (value->bExpr) { _gmx_selparser_error("expressions not supported within range parameters"); return FALSE; } if (value->type != param->val.type) { gmx_bug("internal error"); return FALSE; } if (param->val.type == INT_VALUE) { /* Make sure the input range is in increasing order */ if (value->u.i.i1 > value->u.i.i2) { int tmp = value->u.i.i1; value->u.i.i1 = value->u.i.i2; value->u.i.i2 = tmp; } /* Check if the new range overlaps or extends the previous one */ if (i > 0 && value->u.i.i1 <= idata[i-1]+1 && value->u.i.i2 >= idata[i-2]-1) { idata[i-2] = min(idata[i-2], value->u.i.i1); idata[i-1] = max(idata[i-1], value->u.i.i2); } else { idata[i++] = value->u.i.i1; idata[i++] = value->u.i.i2; } } else { /* Make sure the input range is in increasing order */ if (value->u.r.r1 > value->u.r.r2) { real tmp = value->u.r.r1; value->u.r.r1 = value->u.r.r2; value->u.r.r2 = tmp; } /* Check if the new range overlaps or extends the previous one */ if (i > 0 && value->u.r.r1 <= rdata[i-1] && value->u.r.r2 >= rdata[i-2]) { rdata[i-2] = min(rdata[i-2], value->u.r.r1); rdata[i-1] = max(rdata[i-1], value->u.r.r2); } else { rdata[i++] = value->u.r.r1; rdata[i++] = value->u.r.r2; } } value = value->next; } n = i/2; /* Sort the ranges and merge consequent ones */ if (param->val.type == INT_VALUE) { qsort(idata, n, 2*sizeof(int), &cmp_int_range); for (i = j = 2; i < 2*n; i += 2) { if (idata[j-1]+1 >= idata[i]) { if (idata[i+1] > idata[j-1]) { idata[j-1] = idata[i+1]; } } else { idata[j] = idata[i]; idata[j+1] = idata[i+1]; j += 2; } } } else { qsort(rdata, n, 2*sizeof(real), &cmp_real_range); for (i = j = 2; i < 2*n; i += 2) { if (rdata[j-1]+1 >= rdata[i]) { if (rdata[i+1] > rdata[j-1]) { rdata[j-1] = rdata[i+1]; } } else { rdata[j] = rdata[i]; rdata[j+1] = rdata[i+1]; j += 2; } } } n = j/2; /* Store the values */ if (param->flags & SPAR_VARNUM) { param->val.nr = n; if (param->val.type == INT_VALUE) { srenew(idata, j); _gmx_selvalue_setstore_alloc(¶m->val, idata, j); } else { srenew(rdata, j); _gmx_selvalue_setstore_alloc(¶m->val, rdata, j); } } else { if (n != param->val.nr) { _gmx_selparser_error("the value of parameter '%s' should consist of exactly one range", param->name); sfree(idata); sfree(rdata); return FALSE; } if (param->val.type == INT_VALUE) { memcpy(param->val.u.i, idata, 2*n*sizeof(int)); sfree(idata); } else { memcpy(param->val.u.r, rdata, 2*n*sizeof(real)); sfree(rdata); } } if (param->nvalptr) { *param->nvalptr = param->val.nr; } param->nvalptr = NULL; return TRUE; }