From 81fdb5e4188e6a3ee4dbaac3f22f2c872167c236 Mon Sep 17 00:00:00 2001 From: Teemu Murtola Date: Wed, 11 Nov 2009 19:44:22 +0100 Subject: [PATCH] Fixed segfaults with empty selections. Selections like 'com of none' used to segfault or cause other problems, but now they should cleanly return an empty selection. --- include/position.h | 7 +++++++ src/gmxlib/selection/compiler.c | 1 + src/gmxlib/selection/params.c | 1 + src/gmxlib/trajana/indexutil.c | 5 ++++- src/gmxlib/trajana/poscalc.c | 1 + src/gmxlib/trajana/position.c | 15 +++++++++++++-- 6 files changed, 27 insertions(+), 3 deletions(-) diff --git a/include/position.h b/include/position.h index af98e55aff..a169e821b2 100644 --- a/include/position.h +++ b/include/position.h @@ -66,6 +66,10 @@ typedef struct gmx_ana_pos_t * Pointer to the current evaluation group. */ gmx_ana_index_t *g; + /*! \brief + * Number of elements allocated for \c x. + */ + int nalloc_x; } gmx_ana_pos_t; /** Initializes an empty position structure. */ @@ -87,6 +91,9 @@ gmx_ana_pos_free(gmx_ana_pos_t *pos); extern void gmx_ana_pos_copy(gmx_ana_pos_t *dest, gmx_ana_pos_t *src, bool bFirst); +/** Sets the number of positions in a position structure. */ +extern void +gmx_ana_pos_set_nr(gmx_ana_pos_t *pos, int n); /** Sets the evaluation group of a position data structure. */ extern void gmx_ana_pos_set_evalgrp(gmx_ana_pos_t *pos, gmx_ana_index_t *g); diff --git a/src/gmxlib/selection/compiler.c b/src/gmxlib/selection/compiler.c index 4c7209f666..90615af25c 100644 --- a/src/gmxlib/selection/compiler.c +++ b/src/gmxlib/selection/compiler.c @@ -1640,6 +1640,7 @@ analyze_static(gmx_sel_evaluate_t *data, t_selelem *sel, gmx_ana_index_t *g) if (sel->v.type == POS_VALUE && !(sel->flags & SEL_OUTINIT)) { gmx_ana_indexmap_copy(&sel->v.u.p->m, &sel->child->child->v.u.p->m, TRUE); + gmx_ana_pos_set_nr(sel->v.u.p, sel->child->child->v.u.p->nr); sel->flags |= SEL_OUTINIT; } rc = sel->cdata->evaluate(data, sel, g); diff --git a/src/gmxlib/selection/params.c b/src/gmxlib/selection/params.c index 6276bc4f5e..9c40f0434e 100644 --- a/src/gmxlib/selection/params.c +++ b/src/gmxlib/selection/params.c @@ -457,6 +457,7 @@ parse_values_varnum(int nval, t_selexpr_value *values, gmx_ana_selparam_t *param if (param->val.type == POS_VALUE) { gmx_ana_pos_reserve(param->val.u.p, nval, 0); + gmx_ana_pos_set_nr(param->val.u.p, nval); gmx_ana_indexmap_init(¶m->val.u.p->m, NULL, NULL, INDEX_UNKNOWN); } else diff --git a/src/gmxlib/trajana/indexutil.c b/src/gmxlib/trajana/indexutil.c index 95351f4fb6..5b43d6616d 100644 --- a/src/gmxlib/trajana/indexutil.c +++ b/src/gmxlib/trajana/indexutil.c @@ -1293,7 +1293,10 @@ gmx_ana_indexmap_update(gmx_ana_indexmap_t *m, gmx_ana_index_t *g, } if (m->type == INDEX_ALL) { - m->mapb.index[1] = g->isize; + if (m->b.nr > 0) + { + m->mapb.index[1] = g->isize; + } return; } /* Reset the reference IDs and mapping if necessary */ diff --git a/src/gmxlib/trajana/poscalc.c b/src/gmxlib/trajana/poscalc.c index 02aa7f289b..02788b68a0 100644 --- a/src/gmxlib/trajana/poscalc.c +++ b/src/gmxlib/trajana/poscalc.c @@ -1094,6 +1094,7 @@ gmx_ana_poscalc_init_pos(gmx_ana_poscalc_t *pc, gmx_ana_pos_t *p) { gmx_ana_indexmap_init(&p->m, &pc->gmax, pc->coll->top, pc->itype); gmx_ana_pos_reserve(p, p->m.nr, 0); + gmx_ana_pos_set_nr(p, p->m.nr); p->g = &pc->gmax; } diff --git a/src/gmxlib/trajana/position.c b/src/gmxlib/trajana/position.c index a17b476766..e407e712e0 100644 --- a/src/gmxlib/trajana/position.c +++ b/src/gmxlib/trajana/position.c @@ -56,6 +56,7 @@ gmx_ana_pos_clear(gmx_ana_pos_t *pos) pos->x = NULL; gmx_ana_indexmap_clear(&pos->m); pos->g = NULL; + pos->nalloc_x = 0; } /*! @@ -69,9 +70,9 @@ gmx_ana_pos_clear(gmx_ana_pos_t *pos) void gmx_ana_pos_reserve(gmx_ana_pos_t *pos, int n, int isize) { - if (pos->nr < n) + if (pos->nalloc_x < n) { - pos->nr = n; + pos->nalloc_x = n; srenew(pos->x, n); } if (isize > 0) @@ -149,6 +150,16 @@ gmx_ana_pos_copy(gmx_ana_pos_t *dest, gmx_ana_pos_t *src, bool bFirst) /*! * \param[in,out] pos Position data structure. + * \param[in] nr Number of positions. + */ +void +gmx_ana_pos_set_nr(gmx_ana_pos_t *pos, int nr) +{ + pos->nr = nr; +} + +/*! + * \param[in,out] pos Position data structure. * \param g Evaluation group. * * The old group, if any, is discarded. -- 2.11.4.GIT