Merge remote-tracking branch 'origin/release-4-6' into HEAD
[alexxy/gromacs.git] / src / gromacs / selection / params.cpp
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11  * Copyright (c) 2001-2009, The GROMACS development team,
12  * check out http://www.gromacs.org for more information.
13
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * If you want to redistribute modifications, please consider that
20  * scientific software is very special. Version control is crucial -
21  * bugs must be traceable. We will be happy to consider code for
22  * inclusion in the official distribution, but derived work must not
23  * be called official GROMACS. Details are found in the README & COPYING
24  * files - if they are missing, get the official version at www.gromacs.org.
25  *
26  * To help us fund GROMACS development, we humbly ask that you cite
27  * the papers on the package - you can find them in the top README file.
28  *
29  * For more info, check our website at http://www.gromacs.org
30  */
31 /*! \internal \file
32  * \brief
33  * Implements functions in selparam.h.
34  *
35  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36  * \ingroup module_selection
37  */
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42 #include <algorithm>
43
44 #include "smalloc.h"
45 #include "string2.h"
46 #include "vec.h"
47
48 #include "gromacs/selection/position.h"
49 #include "gromacs/selection/selmethod.h"
50 #include "gromacs/selection/selparam.h"
51 #include "gromacs/utility/errorcodes.h"
52 #include "gromacs/utility/gmxassert.h"
53 #include "gromacs/utility/messagestringcollector.h"
54 #include "gromacs/utility/stringutil.h"
55
56 #include "parsetree.h"
57 #include "position.h"
58 #include "scanner.h"
59 #include "selelem.h"
60
61 using std::min;
62 using std::max;
63
64 /*!
65  * \param[in] name   Name of the parameter to search.
66  * \param[in] nparam Number of parameters in the \p param array.
67  * \param[in] param  Parameter array to search.
68  * \returns   Pointer to the parameter in the \p param
69  *   or NULL if no parameter with name \p name was found.
70  *
71  * The comparison is case-sensitive.
72  */
73 gmx_ana_selparam_t *
74 gmx_ana_selparam_find(const char *name, int nparam, gmx_ana_selparam_t *param)
75 {
76     int                i;
77
78     if (nparam == 0)
79     {
80         return NULL;
81     }
82     /* Find the first non-null parameter */
83     i = 0;
84     while (i < nparam && param[i].name == NULL)
85     {
86         ++i;
87     }
88     /* Process the special case of a NULL parameter */
89     if (name == NULL)
90     {
91         return (i == 0) ? NULL : &param[i-1];
92     }
93     for ( ; i < nparam; ++i)
94     {
95         if (!strcmp(param[i].name, name))
96         {
97             return &param[i];
98         }
99         /* Check for 'no' prefix on boolean parameters */
100         if (param[i].val.type == NO_VALUE
101             && strlen(name) > 2 && name[0] == 'n' && name[1] == 'o'
102             && !strcmp(param[i].name, name+2))
103         {
104             return &param[i];
105         }
106     }
107     return NULL;
108 }
109
110 /*! \brief
111  * Does a type conversion on a \c t_selexpr_value.
112  *
113  * \param[in,out] value    Value to convert.
114  * \param[in]     type     Type to convert to.
115  * \param[in]     scanner  Scanner data structure.
116  * \returns       0 on success, a non-zero value on error.
117  */
118 static int
119 convert_value(t_selexpr_value *value, e_selvalue_t type, void *scanner)
120 {
121     if (value->type == type || type == NO_VALUE)
122     {
123         return 0;
124     }
125     if (value->bExpr)
126     {
127         /* Conversion from atom selection to position using default
128          * reference positions. */
129         if (value->type == GROUP_VALUE && type == POS_VALUE)
130         {
131             value->u.expr =
132                 _gmx_sel_init_position(value->u.expr, NULL, scanner);
133             if (value->u.expr == NULL)
134             {
135                 return -1;
136             }
137             value->type = type;
138             return 0;
139         }
140         return -1;
141     }
142     else
143     {
144         /* Integers to floating point are easy */
145         if (value->type == INT_VALUE && type == REAL_VALUE)
146         {
147             real r1 = (real)value->u.i.i1;
148             real r2 = (real)value->u.i.i2;
149             value->u.r.r1 = r1;
150             value->u.r.r2 = r2;
151             value->type = type;
152             return 0;
153         }
154         /* Reals that are integer-valued can also be converted */
155         if (value->type == REAL_VALUE && type == INT_VALUE
156             && gmx_within_tol(value->u.r.r1, (int)value->u.r.r1, GMX_REAL_EPS)
157             && gmx_within_tol(value->u.r.r2, (int)value->u.r.r2, GMX_REAL_EPS))
158         {
159             int i1 = (int)value->u.r.r1;
160             int i2 = (int)value->u.r.r2;
161             value->u.i.i1 = i1;
162             value->u.i.i2 = i2;
163             value->type = type;
164             return 0;
165         }
166     }
167     return -1;
168 }
169
170 /*! \brief
171  * Does a type conversion on a list of values.
172  *
173  * \param[in,out] values   Values to convert.
174  * \param[in]     type     Type to convert to.
175  * \param[in]     scanner  Scanner data structure.
176  * \returns       0 on success, a non-zero value on error.
177  */
178 static int
179 convert_values(t_selexpr_value *values, e_selvalue_t type, void *scanner)
180 {
181     t_selexpr_value *value;
182     int              rc, rc1;
183
184     rc = 0;
185     value = values;
186     while (value)
187     {
188         rc1 = convert_value(value, type, scanner);
189         if (rc1 != 0 && rc == 0)
190         {
191             rc = rc1;
192         }
193         value = value->next;
194     }
195     /* FIXME: More informative error messages */
196     return rc;
197 }
198
199 /*! \brief
200  * Adds a child element for a parameter, keeping the parameter order.
201  *
202  * \param[in,out] root  Root element to which the child is added.
203  * \param[in]     child Child to add.
204  * \param[in]     param Parameter for which this child is a value.
205  *
206  * Puts \p child in the child list of \p root such that the list remains
207  * in the same order as the corresponding parameters.
208  */
209 static void
210 place_child(t_selelem *root, t_selelem *child, gmx_ana_selparam_t *param)
211 {
212     gmx_ana_selparam_t *ps;
213     int                 n;
214
215     ps = root->u.expr.method->param;
216     n  = param - ps;
217     /* Put the child element in the correct place */
218     if (!root->child || n < root->child->u.param - ps)
219     {
220         child->next = root->child;
221         root->child = child;
222     }
223     else
224     {
225         t_selelem *prev;
226
227         prev = root->child;
228         while (prev->next && prev->next->u.param - ps >= n)
229         {
230             prev = prev->next;
231         }
232         child->next = prev->next;
233         prev->next  = child;
234     }
235 }
236
237 /*! \brief
238  * Comparison function for sorting integer ranges.
239  * 
240  * \param[in] a Pointer to the first range.
241  * \param[in] b Pointer to the second range.
242  * \returns   -1, 0, or 1 depending on the relative order of \p a and \p b.
243  *
244  * The ranges are primarily sorted based on their starting point, and
245  * secondarily based on length (longer ranges come first).
246  */
247 static int
248 cmp_int_range(const void *a, const void *b)
249 {
250     if (((int *)a)[0] < ((int *)b)[0])
251     {
252         return -1;
253     }
254     if (((int *)a)[0] > ((int *)b)[0])
255     {
256         return 1;
257     }
258     if (((int *)a)[1] > ((int *)b)[1])
259     {
260         return -1;
261     }
262     return 0;
263 }
264
265 /*! \brief
266  * Comparison function for sorting real ranges.
267  *
268  * \param[in] a Pointer to the first range.
269  * \param[in] b Pointer to the second range.
270  * \returns   -1, 0, or 1 depending on the relative order of \p a and \p b.
271  *
272  * The ranges are primarily sorted based on their starting point, and
273  * secondarily based on length (longer ranges come first).
274  */
275 static int
276 cmp_real_range(const void *a, const void *b)
277 {
278     if (((real *)a)[0] < ((real *)b)[0])
279     {
280         return -1;
281     }
282     if (((real *)a)[0] > ((real *)b)[0])
283     {
284         return 1;
285     }
286     if (((real *)a)[1] > ((real *)b)[1])
287     {
288         return -1;
289     }
290     return 0;
291 }
292
293 /*! \brief
294  * Parses the values for a parameter that takes integer or real ranges.
295  * 
296  * \param[in] nval   Number of values in \p values.
297  * \param[in] values Pointer to the list of values.
298  * \param     param  Parameter to parse.
299  * \param[in] scanner Scanner data structure.
300  * \returns   true if the values were parsed successfully, false otherwise.
301  */
302 static bool
303 parse_values_range(int nval, t_selexpr_value *values, gmx_ana_selparam_t *param,
304                    void *scanner)
305 {
306     t_selexpr_value    *value;
307     int                *idata;
308     real               *rdata;
309     int                 i, j, n;
310
311     param->flags &= ~SPAR_DYNAMIC;
312     if (param->val.type != INT_VALUE && param->val.type != REAL_VALUE)
313     {
314         GMX_ERROR_NORET(gmx::eeInternalError, "Invalid range parameter type");
315         return false;
316     }
317     idata = NULL;
318     rdata = NULL;
319     if (param->val.type == INT_VALUE)
320     {
321         snew(idata, nval*2);
322     }
323     else
324     {
325         snew(rdata, nval*2);
326     }
327     value = values;
328     i = 0;
329     while (value)
330     {
331         if (value->bExpr)
332         {
333             _gmx_selparser_error(scanner, "expressions not supported within range parameters");
334             return false;
335         }
336         if (value->type != param->val.type)
337         {
338             GMX_ERROR_NORET(gmx::eeInternalError, "Invalid range value type");
339             return false;
340         }
341         if (param->val.type == INT_VALUE)
342         {
343             /* Make sure the input range is in increasing order */
344             if (value->u.i.i1 > value->u.i.i2)
345             {
346                 int tmp       = value->u.i.i1;
347                 value->u.i.i1 = value->u.i.i2;
348                 value->u.i.i2 = tmp;
349             }
350             /* Check if the new range overlaps or extends the previous one */
351             if (i > 0 && value->u.i.i1 <= idata[i-1]+1 && value->u.i.i2 >= idata[i-2]-1)
352             {
353                 idata[i-2] = min(idata[i-2], value->u.i.i1);
354                 idata[i-1] = max(idata[i-1], value->u.i.i2);
355             }
356             else
357             {
358                 idata[i++] = value->u.i.i1;
359                 idata[i++] = value->u.i.i2;
360             }
361         }
362         else
363         {
364             /* Make sure the input range is in increasing order */
365             if (value->u.r.r1 > value->u.r.r2)
366             {
367                 real tmp      = value->u.r.r1;
368                 value->u.r.r1 = value->u.r.r2;
369                 value->u.r.r2 = tmp;
370             }
371             /* Check if the new range overlaps or extends the previous one */
372             if (i > 0 && value->u.r.r1 <= rdata[i-1] && value->u.r.r2 >= rdata[i-2])
373             {
374                 rdata[i-2] = min(rdata[i-2], value->u.r.r1);
375                 rdata[i-1] = max(rdata[i-1], value->u.r.r2);
376             }
377             else
378             {
379                 rdata[i++] = value->u.r.r1;
380                 rdata[i++] = value->u.r.r2;
381             }
382         }
383         value = value->next;
384     }
385     n = i/2;
386     /* Sort the ranges and merge consequent ones */
387     if (param->val.type == INT_VALUE)
388     {
389         qsort(idata, n, 2*sizeof(int), &cmp_int_range);
390         for (i = j = 2; i < 2*n; i += 2)
391         {
392             if (idata[j-1]+1 >= idata[i])
393             {
394                 if (idata[i+1] > idata[j-1])
395                 {
396                     idata[j-1] = idata[i+1];
397                 }
398             }
399             else
400             {
401                 idata[j]   = idata[i];
402                 idata[j+1] = idata[i+1];
403                 j += 2;
404             }
405         }
406     }
407     else
408     {
409         qsort(rdata, n, 2*sizeof(real), &cmp_real_range);
410         for (i = j = 2; i < 2*n; i += 2)
411         {
412             if (rdata[j-1]+1 >= rdata[i])
413             {
414                 if (rdata[i+1] > rdata[j-1])
415                 {
416                     rdata[j-1] = rdata[i+1];
417                 }
418             }
419             else
420             {
421                 rdata[j]   = rdata[i];
422                 rdata[j+1] = rdata[i+1];
423                 j += 2;
424             }
425         }
426     }
427     n = j/2;
428     /* Store the values */
429     if (param->flags & SPAR_VARNUM)
430     {
431         param->val.nr  = n;
432         if (param->val.type == INT_VALUE)
433         {
434             srenew(idata, j);
435             _gmx_selvalue_setstore_alloc(&param->val, idata, j);
436         }
437         else
438         {
439             srenew(rdata, j);
440             _gmx_selvalue_setstore_alloc(&param->val, rdata, j);
441         }
442     }
443     else
444     {
445         if (n != param->val.nr)
446         {
447             _gmx_selparser_error(scanner, "the value should consist of exactly one range");
448             sfree(idata);
449             sfree(rdata);
450             return false;
451         }
452         if (param->val.type == INT_VALUE)
453         {
454             memcpy(param->val.u.i, idata, 2*n*sizeof(int));
455             sfree(idata);
456         }
457         else
458         {
459             memcpy(param->val.u.r, rdata, 2*n*sizeof(real));
460             sfree(rdata);
461         }
462     }
463     if (param->nvalptr)
464     {
465         *param->nvalptr = param->val.nr;
466     }
467     param->nvalptr = NULL;
468
469     return true;
470 }
471
472 /*! \brief
473  * Parses the values for a parameter that takes a variable number of values.
474  * 
475  * \param[in] nval   Number of values in \p values.
476  * \param[in] values Pointer to the list of values.
477  * \param     param  Parameter to parse.
478  * \param     root   Selection element to which child expressions are added.
479  * \param[in] scanner Scanner data structure.
480  * \returns   true if the values were parsed successfully, false otherwise.
481  *
482  * For integer ranges, the sequence of numbers from the first to second value
483  * is stored, each as a separate value.
484  */
485 static bool
486 parse_values_varnum(int nval, t_selexpr_value *values,
487                     gmx_ana_selparam_t *param, t_selelem *root, void *scanner)
488 {
489     t_selexpr_value    *value;
490     int                 i, j;
491
492     param->flags &= ~SPAR_DYNAMIC;
493     /* Update nval if there are integer ranges. */
494     if (param->val.type == INT_VALUE)
495     {
496         value = values;
497         while (value)
498         {
499             if (value->type == INT_VALUE && !value->bExpr)
500             {
501                 nval += abs(value->u.i.i2 - value->u.i.i1);
502             }
503             value = value->next;
504         }
505     }
506
507     /* Check that the value type is actually implemented */
508     if (param->val.type != INT_VALUE && param->val.type != REAL_VALUE
509         && param->val.type != STR_VALUE && param->val.type != POS_VALUE)
510     {
511         GMX_ERROR_NORET(gmx::eeInternalError,
512                         "Variable-count value type not implemented");
513         return false;
514     }
515
516     /* Reserve appropriate amount of memory */
517     if (param->val.type == POS_VALUE)
518     {
519         gmx_ana_pos_reserve(param->val.u.p, nval, 0);
520         gmx_ana_pos_set_nr(param->val.u.p, nval);
521         gmx_ana_indexmap_init(&param->val.u.p->m, NULL, NULL, INDEX_UNKNOWN);
522     }
523     else
524     {
525         _gmx_selvalue_reserve(&param->val, nval);
526     }
527
528     value = values;
529     i     = 0;
530     while (value)
531     {
532         if (value->bExpr)
533         {
534             _gmx_selparser_error(scanner, "expressions not supported within value lists");
535             return false;
536         }
537         if (value->type != param->val.type)
538         {
539             GMX_ERROR_NORET(gmx::eeInternalError, "Invalid value type");
540             return false;
541         }
542         switch (param->val.type)
543         {
544             case INT_VALUE:
545                 if (value->u.i.i1 <= value->u.i.i2)
546                 {
547                     for (j = value->u.i.i1; j <= value->u.i.i2; ++j)
548                     {
549                         param->val.u.i[i++] = j;
550                     }
551                 }
552                 else
553                 {
554                     for (j = value->u.i.i1; j >= value->u.i.i2; --j)
555                     {
556                         param->val.u.i[i++] = j;
557                     }
558                 }
559                 break;
560             case REAL_VALUE:
561                 if (value->u.r.r1 != value->u.r.r2)
562                 {
563                     _gmx_selparser_error(scanner, "real ranges not supported");
564                     return false;
565                 }
566                 param->val.u.r[i++] = value->u.r.r1;
567                 break;
568             case STR_VALUE:  param->val.u.s[i++] = strdup(value->u.s); break;
569             case POS_VALUE:  copy_rvec(value->u.x, param->val.u.p->x[i++]); break;
570             default: /* Should not be reached */
571                 GMX_ERROR_NORET(gmx::eeInternalError, "Invalid value type");
572                 return false;
573         }
574         value = value->next;
575     }
576     param->val.nr = i;
577     if (param->nvalptr)
578     {
579         *param->nvalptr = param->val.nr;
580     }
581     param->nvalptr = NULL;
582     /* Create a dummy child element to store the string values.
583      * This element is responsible for freeing the values, but carries no
584      * other function. */
585     if (param->val.type == STR_VALUE)
586     {
587         t_selelem *child;
588
589         child = _gmx_selelem_create(SEL_CONST);
590         _gmx_selelem_set_vtype(child, STR_VALUE);
591         child->name = param->name;
592         child->flags &= ~SEL_ALLOCVAL;
593         child->flags |= SEL_FLAGSSET | SEL_VARNUMVAL | SEL_ALLOCDATA;
594         child->v.nr = param->val.nr;
595         _gmx_selvalue_setstore(&child->v, param->val.u.s);
596         /* Because the child is not group-valued, the u union is not used
597          * for anything, so we can abuse it by storing the parameter value
598          * as place_child() expects, but this is really ugly... */
599         child->u.param = param;
600         place_child(root, child, param);
601     }
602
603     return true;
604 }
605
606 /*! \brief
607  * Adds a new subexpression reference to a selection element.
608  *
609  * \param[in,out] root  Root element to which the subexpression is added.
610  * \param[in]     param Parameter for which this expression is a value.
611  * \param[in]     expr  Expression to add.
612  * \param[in]     scanner Scanner data structure.
613  * \returns       The created child element.
614  *
615  * Creates a new \ref SEL_SUBEXPRREF element and adds it into the child
616  * list of \p root.
617  * If \p expr is already a \ref SEL_SUBEXPRREF, it is used as it is.
618  * \ref SEL_ALLOCVAL is cleared for the returned element.
619  */
620 static t_selelem *
621 add_child(t_selelem *root, gmx_ana_selparam_t *param, t_selelem *expr,
622           void *scanner)
623 {
624     t_selelem          *child;
625     int                 rc;
626
627     if (root->type != SEL_EXPRESSION && root->type != SEL_MODIFIER)
628     {
629         GMX_ERROR_NORET(gmx::eeInternalError,
630                         "Unsupported root element for selection parameter parser");
631         return NULL;
632     }
633     /* Create a subexpression reference element if necessary */
634     if (expr->type == SEL_SUBEXPRREF)
635     {
636         child = expr;
637     }
638     else
639     {
640         child = _gmx_selelem_create(SEL_SUBEXPRREF);
641         if (!child)
642         {
643             return NULL;
644         }
645         _gmx_selelem_set_vtype(child, expr->v.type);
646         child->child  = expr;
647     }
648     /* Setup the child element */
649     child->flags &= ~SEL_ALLOCVAL;
650     child->u.param = param;
651     if (child->v.type != param->val.type)
652     {
653         _gmx_selparser_error(scanner, "invalid expression value");
654         goto on_error;
655     }
656     rc = _gmx_selelem_update_flags(child, scanner);
657     if (rc != 0)
658     {
659         goto on_error;
660     }
661     if ((child->flags & SEL_DYNAMIC) && !(param->flags & SPAR_DYNAMIC))
662     {
663         _gmx_selparser_error(scanner, "dynamic values not supported");
664         goto on_error;
665     }
666     if (!(child->flags & SEL_DYNAMIC))
667     {
668         param->flags &= ~SPAR_DYNAMIC;
669     }
670     /* Put the child element in the correct place */
671     place_child(root, child, param);
672     return child;
673
674 on_error:
675     if (child != expr)
676     {
677         _gmx_selelem_free(child);
678     }
679     return NULL;
680 }
681
682 /*! \brief
683  * Parses an expression value for a parameter that takes a variable number of values.
684  * 
685  * \param[in] nval   Number of values in \p values.
686  * \param[in] values Pointer to the list of values.
687  * \param     param  Parameter to parse.
688  * \param     root   Selection element to which child expressions are added.
689  * \param[in] scanner Scanner data structure.
690  * \returns   true if the values were parsed successfully, false otherwise.
691  */
692 static bool
693 parse_values_varnum_expr(int nval, t_selexpr_value *values,
694                          gmx_ana_selparam_t *param, t_selelem *root,
695                          void *scanner)
696 {
697     t_selexpr_value    *value;
698     t_selelem          *child;
699
700     if (nval != 1 || !values->bExpr)
701     {
702         GMX_ERROR_NORET(gmx::eeInternalError, "Invalid expression value");
703         return false;
704     }
705
706     value = values;
707     child = add_child(root, param, value->u.expr, scanner);
708     value->u.expr = NULL;
709     if (!child)
710     {
711         return false;
712     }
713
714     /* Process single-valued expressions */
715     /* TODO: We should also handle SEL_SINGLEVAL expressions here */
716     if (child->v.type == POS_VALUE || child->v.type == GROUP_VALUE)
717     {
718         /* Set the value storage */
719         _gmx_selvalue_setstore(&child->v, param->val.u.ptr);
720         param->val.nr = 1;
721         if (param->nvalptr)
722         {
723             *param->nvalptr = param->val.nr;
724         }
725         param->nvalptr = NULL;
726         return true;
727     }
728
729     if (!(child->flags & SEL_VARNUMVAL))
730     {
731         _gmx_selparser_error(scanner, "invalid expression value");
732         return false;
733     }
734
735     child->flags   |= SEL_ALLOCVAL;
736     param->val.nr   = -1;
737     *param->nvalptr = param->val.nr;
738     /* Rest of the initialization is done during compilation in
739      * init_method(). */
740
741     return true;
742 }
743
744 /*! \brief
745  * Initializes the storage of an expression value.
746  *
747  * \param[in,out] sel   Selection element that evaluates the value.
748  * \param[in]     param Parameter to receive the value.
749  * \param[in]     i     The value of \p sel evaluates the value \p i for
750  *   \p param.
751  * \param[in]     scanner Scanner data structure.
752  *
753  * Initializes the data pointer of \p sel such that the result is stored
754  * as the value \p i of \p param.
755  * This function is used internally by parse_values_std().
756  */
757 static bool
758 set_expr_value_store(t_selelem *sel, gmx_ana_selparam_t *param, int i,
759                      void *scanner)
760 {
761     if (sel->v.type != GROUP_VALUE && !(sel->flags & SEL_SINGLEVAL))
762     {
763         _gmx_selparser_error(scanner, "invalid expression value");
764         return false;
765     }
766     switch (sel->v.type)
767     {
768         case INT_VALUE:   sel->v.u.i = &param->val.u.i[i]; break;
769         case REAL_VALUE:  sel->v.u.r = &param->val.u.r[i]; break;
770         case STR_VALUE:   sel->v.u.s = &param->val.u.s[i]; break;
771         case POS_VALUE:   sel->v.u.p = &param->val.u.p[i]; break;
772         case GROUP_VALUE: sel->v.u.g = &param->val.u.g[i]; break;
773         default: /* Error */
774             GMX_ERROR_NORET(gmx::eeInternalError, "Invalid value type");
775             return false;
776     }
777     sel->v.nr = 1;
778     sel->v.nalloc = -1;
779     return true;
780 }
781
782 /*! \brief
783  * Parses the values for a parameter that takes a constant number of values.
784  * 
785  * \param[in] nval   Number of values in \p values.
786  * \param[in] values Pointer to the list of values.
787  * \param     param  Parameter to parse.
788  * \param     root   Selection element to which child expressions are added.
789  * \param[in] scanner Scanner data structure.
790  * \returns   true if the values were parsed successfully, false otherwise.
791  *
792  * For integer ranges, the sequence of numbers from the first to second value
793  * is stored, each as a separate value.
794  */
795 static bool
796 parse_values_std(int nval, t_selexpr_value *values, gmx_ana_selparam_t *param,
797                  t_selelem *root, void *scanner)
798 {
799     t_selexpr_value   *value;
800     t_selelem         *child;
801     int                i, j;
802     bool               bDynamic;
803
804     /* Handle atom-valued parameters */
805     if (param->flags & SPAR_ATOMVAL)
806     {
807         if (nval > 1)
808         {
809             _gmx_selparser_error(scanner, "more than one value not supported");
810             return false;
811         }
812         value = values;
813         if (value->bExpr)
814         {
815             child = add_child(root, param, value->u.expr, scanner);
816             value->u.expr = NULL;
817             if (!child)
818             {
819                 return false;
820             }
821             child->flags |= SEL_ALLOCVAL;
822             if (child->v.type != GROUP_VALUE && (child->flags & SEL_ATOMVAL))
823             {
824                 /* Rest of the initialization is done during compilation in
825                  * init_method(). */
826                 /* TODO: Positions are not correctly handled */
827                 param->val.nr = -1;
828                 if (param->nvalptr)
829                 {
830                     *param->nvalptr = -1;
831                 }
832                 return true;
833             }
834             param->flags  &= ~SPAR_ATOMVAL;
835             param->val.nr  = 1;
836             if (param->nvalptr)
837             {
838                 *param->nvalptr = 1;
839             }
840             param->nvalptr = NULL;
841             if (param->val.type == INT_VALUE || param->val.type == REAL_VALUE
842                 || param->val.type == STR_VALUE)
843             {
844                 _gmx_selvalue_reserve(&param->val, 1);
845             }
846             return set_expr_value_store(child, param, 0, scanner);
847         }
848         /* If we reach here, proceed with normal parameter handling */
849         param->val.nr = 1;
850         if (param->val.type == INT_VALUE || param->val.type == REAL_VALUE
851             || param->val.type == STR_VALUE)
852         {
853             _gmx_selvalue_reserve(&param->val, 1);
854         }
855         param->flags &= ~SPAR_ATOMVAL;
856         param->flags &= ~SPAR_DYNAMIC;
857     }
858
859     value = values;
860     i = 0;
861     bDynamic = false;
862     while (value && i < param->val.nr)
863     {
864         if (value->type != param->val.type)
865         {
866             _gmx_selparser_error(scanner, "incorrect value skipped");
867             value = value->next;
868             continue;
869         }
870         if (value->bExpr)
871         {
872             child = add_child(root, param, value->u.expr, scanner);
873             /* Clear the expression from the value once it is stored */
874             value->u.expr = NULL;
875             /* Check that the expression is valid */
876             if (!child)
877             {
878                 return false;
879             }
880             if (!set_expr_value_store(child, param, i, scanner))
881             {
882                 return false;
883             }
884             if (child->flags & SEL_DYNAMIC)
885             {
886                 bDynamic = true;
887             }
888         }
889         else
890         {
891             /* Value is not an expression */
892             switch (value->type)
893             {
894                 case INT_VALUE:
895                     if (value->u.i.i1 <= value->u.i.i2)
896                     {
897                         for (j = value->u.i.i1; j <= value->u.i.i2 && i < param->val.nr; ++j)
898                         {
899                             param->val.u.i[i++] = j;
900                         }
901                         if (j != value->u.i.i2 + 1)
902                         {
903                             _gmx_selparser_error(scanner, "extra values skipped");
904                         }
905                     }
906                     else
907                     {
908                         for (j = value->u.i.i1; j >= value->u.i.i2 && i < param->val.nr; --j)
909                         {
910                             param->val.u.i[i++] = j;
911                         }
912                         if (j != value->u.i.i2 - 1)
913                         {
914                             _gmx_selparser_error(scanner, "extra values skipped");
915                         }
916                     }
917                     --i;
918                     break;
919                 case REAL_VALUE:
920                     if (value->u.r.r1 != value->u.r.r2)
921                     {
922                         _gmx_selparser_error(scanner, "real ranges not supported");
923                         return false;
924                     }
925                     param->val.u.r[i] = value->u.r.r1;
926                     break;
927                 case STR_VALUE:
928                     param->val.u.s[i] = strdup(value->u.s);
929                     break;
930                 case POS_VALUE:
931                     gmx_ana_pos_init_const(&param->val.u.p[i], value->u.x);
932                     break;
933                 case NO_VALUE:
934                 case GROUP_VALUE:
935                     GMX_ERROR_NORET(gmx::eeInternalError,
936                                     "Invalid non-expression value");
937                     return false;
938             }
939         }
940         ++i;
941         value = value->next;
942     }
943     if (value != NULL)
944     {
945         _gmx_selparser_error(scanner, "extra values'");
946         return false;
947     }
948     if (i < param->val.nr)
949     {
950         _gmx_selparser_error(scanner, "not enough values");
951         return false;
952     }
953     if (!bDynamic)
954     {
955         param->flags &= ~SPAR_DYNAMIC;
956     }
957     if (param->nvalptr)
958     {
959         *param->nvalptr = param->val.nr;
960     }
961     param->nvalptr = NULL;
962
963     return true;
964 }
965
966 /*! \brief
967  * Parses the values for a boolean parameter.
968  *
969  * \param[in] name   Name by which the parameter was given.
970  * \param[in] nval   Number of values in \p values.
971  * \param[in] values Pointer to the list of values.
972  * \param     param  Parameter to parse.
973  * \param[in] scanner Scanner data structure.
974  * \returns   true if the values were parsed successfully, false otherwise.
975  */
976 static bool
977 parse_values_bool(const char *name, int nval, t_selexpr_value *values,
978                   gmx_ana_selparam_t *param, void *scanner)
979 {
980     bool bSetNo;
981     int  len;
982
983     if (param->val.type != NO_VALUE)
984     {
985         GMX_ERROR_NORET(gmx::eeInternalError, "Invalid boolean parameter");
986         return false;
987     }
988     if (nval > 1 || (values && values->type != INT_VALUE))
989     {
990         _gmx_selparser_error(scanner, "parameter takes only a yes/no/on/off/0/1 value");
991         return false;
992     }
993
994     bSetNo = false;
995     /* Check if the parameter name is given with a 'no' prefix */
996     len = name != NULL ? strlen(name) : 0;
997     if (len > 2 && name[0] == 'n' && name[1] == 'o'
998         && strncmp(name+2, param->name, len-2) == 0)
999     {
1000         bSetNo = true;
1001     }
1002     if (bSetNo && nval > 0)
1003     {
1004         _gmx_selparser_error(scanner, "parameter 'no%s' should not have a value",
1005                              param->name);
1006         return false;
1007     }
1008     if (values && values->u.i.i1 == 0)
1009     {
1010         bSetNo = true;
1011     }
1012
1013     *param->val.u.b = bSetNo ? false : true;
1014     return true;
1015 }
1016
1017 /*! \brief
1018  * Parses the values for an enumeration parameter.
1019  *
1020  * \param[in] nval   Number of values in \p values.
1021  * \param[in] values Pointer to the list of values.
1022  * \param     param  Parameter to parse.
1023  * \param[in] scanner Scanner data structure.
1024  * \returns   true if the values were parsed successfully, false otherwise.
1025  */
1026 static bool
1027 parse_values_enum(int nval, t_selexpr_value *values, gmx_ana_selparam_t *param,
1028                   void *scanner)
1029 {
1030     int  i, len, match;
1031
1032     if (nval != 1)
1033     {
1034         _gmx_selparser_error(scanner, "a single value is required");
1035         return false;
1036     }
1037     if (values->type != STR_VALUE || param->val.type != STR_VALUE)
1038     {
1039         GMX_ERROR_NORET(gmx::eeInternalError, "Invalid enum parameter");
1040         return false;
1041     }
1042     if (values->bExpr)
1043     {
1044         _gmx_selparser_error(scanner, "expression value for enumerated parameter not supported");
1045         return false;
1046     }
1047
1048     len = strlen(values->u.s);
1049     i = 1;
1050     match = 0;
1051     while (param->val.u.s[i] != NULL)
1052     {
1053         if (strncmp(values->u.s, param->val.u.s[i], len) == 0)
1054         {
1055             /* Check if there is a duplicate match */
1056             if (match > 0)
1057             {
1058                 _gmx_selparser_error(scanner, "ambiguous value");
1059                 return false;
1060             }
1061             match = i;
1062         }
1063         ++i;
1064     }
1065     if (match == 0)
1066     {
1067         _gmx_selparser_error(scanner, "invalid value");
1068         return false;
1069     }
1070     param->val.u.s[0] = param->val.u.s[match];
1071     return true;
1072 }
1073
1074 /*! \brief
1075  * Replaces constant expressions with their values.
1076  *
1077  * \param[in,out] values First element in the value list to process.
1078  */
1079 static void
1080 convert_const_values(t_selexpr_value *values)
1081 {
1082     t_selexpr_value *val;
1083
1084     val = values;
1085     while (val)
1086     {
1087         if (val->bExpr && val->u.expr->v.type != GROUP_VALUE &&
1088             val->u.expr->type == SEL_CONST)
1089         {
1090             t_selelem *expr = val->u.expr;
1091             val->bExpr = false;
1092             switch (expr->v.type)
1093             {
1094                 case INT_VALUE:
1095                     val->u.i.i1 = val->u.i.i2 = expr->v.u.i[0];
1096                     break;
1097                 case REAL_VALUE:
1098                     val->u.r.r1 = val->u.r.r2 = expr->v.u.r[0];
1099                     break;
1100                 case STR_VALUE:
1101                     val->u.s = expr->v.u.s[0];
1102                     break;
1103                 case POS_VALUE:
1104                     copy_rvec(expr->v.u.p->x[0], val->u.x);
1105                     break;
1106                 default:
1107                     GMX_ERROR_NORET(gmx::eeInternalError,
1108                                     "Unsupported value type");
1109                     break;
1110             }
1111             _gmx_selelem_free(expr);
1112         }
1113         val = val->next;
1114     }
1115 }
1116
1117 /*!
1118  * \param     pparams List of parameters from the selection parser.
1119  * \param[in] nparam  Number of parameters in \p params.
1120  * \param     params  Array of parameters to parse.
1121  * \param     root    Selection element to which child expressions are added.
1122  * \param[in] scanner Scanner data structure.
1123  * \returns   true if the parameters were parsed successfully, false otherwise.
1124  *
1125  * Initializes the \p params array based on the parameters in \p pparams.
1126  * See the documentation of \c gmx_ana_selparam_t for different options
1127  * available for parsing.
1128  *
1129  * The list \p pparams and any associated values are freed after the parameters
1130  * have been processed, no matter is there was an error or not.
1131  */
1132 bool
1133 _gmx_sel_parse_params(t_selexpr_param *pparams, int nparam, gmx_ana_selparam_t *params,
1134                       t_selelem *root, void *scanner)
1135 {
1136     gmx::MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner);
1137     t_selexpr_param    *pparam;
1138     gmx_ana_selparam_t *oparam;
1139     bool                bOk, rc;
1140     int                 i;
1141
1142     /* Check that the value pointers of SPAR_VARNUM parameters are NULL and
1143      * that they are not NULL for other parameters */
1144     bOk = true;
1145     for (i = 0; i < nparam; ++i)
1146     {
1147         std::string contextStr = gmx::formatString("In parameter '%s'", params[i].name);
1148         gmx::MessageStringContext  context(errors, contextStr);
1149         if (params[i].val.type != POS_VALUE && (params[i].flags & (SPAR_VARNUM | SPAR_ATOMVAL)))
1150         {
1151             if (params[i].val.u.ptr != NULL)
1152             {
1153                 _gmx_selparser_error(scanner, "value pointer is not NULL "
1154                                      "although it should be for SPAR_VARNUM "
1155                                      "and SPAR_ATOMVAL parameters");
1156             }
1157             if ((params[i].flags & SPAR_VARNUM)
1158                 && (params[i].flags & SPAR_DYNAMIC) && !params[i].nvalptr)
1159             {
1160                 _gmx_selparser_error(scanner, "nvalptr is NULL but both "
1161                                      "SPAR_VARNUM and SPAR_DYNAMIC are specified");
1162                 bOk = false;
1163             }
1164         }
1165         else
1166         {
1167             if (params[i].val.u.ptr == NULL)
1168             {
1169                 _gmx_selparser_error(scanner, "value pointer is NULL");
1170                 bOk = false;
1171             }
1172         }
1173     }
1174     if (!bOk)
1175     {
1176         _gmx_selexpr_free_params(pparams);
1177         return false;
1178     }
1179     /* Parse the parameters */
1180     pparam = pparams;
1181     i      = 0;
1182     while (pparam)
1183     {
1184         std::string contextStr;
1185         /* Find the parameter and make some checks */
1186         if (pparam->name != NULL)
1187         {
1188             contextStr = gmx::formatString("In parameter '%s'", pparam->name);
1189             i = -1;
1190             oparam = gmx_ana_selparam_find(pparam->name, nparam, params);
1191         }
1192         else if (i >= 0)
1193         {
1194             contextStr = gmx::formatString("In value %d", i + 1);
1195             oparam = &params[i];
1196             if (oparam->name != NULL)
1197             {
1198                 oparam = NULL;
1199                 _gmx_selparser_error(scanner, "too many NULL parameters provided");
1200                 bOk = false;
1201                 pparam = pparam->next;
1202                 continue;
1203             }
1204             ++i;
1205         }
1206         else
1207         {
1208             _gmx_selparser_error(scanner, "all NULL parameters should appear in the beginning of the list");
1209             bOk = false;
1210             pparam = pparam->next;
1211             continue;
1212         }
1213         gmx::MessageStringContext  context(errors, contextStr);
1214         if (!oparam)
1215         {
1216             _gmx_selparser_error(scanner, "unknown parameter skipped");
1217             bOk = false;
1218             goto next_param;
1219         }
1220         if (oparam->val.type != NO_VALUE && pparam->value == NULL)
1221         {
1222             GMX_ASSERT(pparam->nval == 0, "Inconsistent values and value count");
1223             _gmx_selparser_error(scanner, "no value provided");
1224             bOk = false;
1225             goto next_param;
1226         }
1227         if (oparam->flags & SPAR_SET)
1228         {
1229             _gmx_selparser_error(scanner, "parameter set multiple times, extra values skipped");
1230             bOk = false;
1231             goto next_param;
1232         }
1233         oparam->flags |= SPAR_SET;
1234         /* Process the values for the parameter */
1235         convert_const_values(pparam->value);
1236         if (convert_values(pparam->value, oparam->val.type, scanner) != 0)
1237         {
1238             _gmx_selparser_error(scanner, "invalid value");
1239             bOk = false;
1240             goto next_param;
1241         }
1242         if (oparam->val.type == NO_VALUE)
1243         {
1244             rc = parse_values_bool(pparam->name, pparam->nval, pparam->value, oparam, scanner);
1245         }
1246         else if (oparam->flags & SPAR_RANGES)
1247         {
1248             rc = parse_values_range(pparam->nval, pparam->value, oparam, scanner);
1249         }
1250         else if (oparam->flags & SPAR_VARNUM)
1251         {
1252             if (pparam->nval == 1 && pparam->value->bExpr)
1253             {
1254                 rc = parse_values_varnum_expr(pparam->nval, pparam->value, oparam, root, scanner);
1255             }
1256             else
1257             {
1258                 rc = parse_values_varnum(pparam->nval, pparam->value, oparam, root, scanner);
1259             }
1260         }
1261         else if (oparam->flags & SPAR_ENUMVAL)
1262         {
1263             rc = parse_values_enum(pparam->nval, pparam->value, oparam, scanner);
1264         }
1265         else
1266         {
1267             rc = parse_values_std(pparam->nval, pparam->value, oparam, root, scanner);
1268         }
1269         if (!rc)
1270         {
1271             bOk = false;
1272         }
1273         /* Advance to the next parameter */
1274 next_param:
1275         pparam = pparam->next;
1276     }
1277     /* Check that all required parameters are present */
1278     for (i = 0; i < nparam; ++i)
1279     {
1280         if (!(params[i].flags & SPAR_OPTIONAL) && !(params[i].flags & SPAR_SET))
1281         {
1282             _gmx_selparser_error(scanner, "required parameter '%s' not specified", params[i].name);
1283             bOk = false;
1284         }
1285     }
1286
1287     _gmx_selexpr_free_params(pparams);
1288     return bOk;
1289 }