Remove interactive help from core selection parser
authorTeemu Murtola <teemu.murtola@gmail.com>
Fri, 14 Mar 2014 18:19:55 +0000 (20:19 +0200)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Tue, 18 Mar 2014 08:50:12 +0000 (09:50 +0100)
The help is now handled in the loop that processes user input, and it
never gets into the parser itself.  This removes several special cases
from the parser and simplifies it.

Add a few string utilities and tests for them to make it easy to handle
the help commands.

Change-Id: Ida58bccd3b9ced4b7060485cc2f064b73796c996

14 files changed:
src/gromacs/selection/parser.cpp
src/gromacs/selection/parser.h
src/gromacs/selection/parser.y
src/gromacs/selection/parsetree.cpp
src/gromacs/selection/parsetree.h
src/gromacs/selection/scanner.cpp
src/gromacs/selection/scanner.l
src/gromacs/selection/scanner_flex.h
src/gromacs/selection/selectioncollection.cpp
src/gromacs/selection/symrec.cpp
src/gromacs/selection/tests/selectioncollection.cpp
src/gromacs/utility/stringutil.cpp
src/gromacs/utility/stringutil.h
src/gromacs/utility/tests/stringutil.cpp

index 0928827aa8f517876dc2c112e700c0f0e6254206..d7bb592310a84cde493fb26421ee8b3e48948e91 100644 (file)
@@ -140,7 +140,7 @@ extern int _gmx_sel_yydebug;
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2009,2010,2011,2012,2013, by the GROMACS development team, led by
+ * Copyright (c) 2009,2010,2011,2012,2013,2014, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -189,38 +189,36 @@ extern int _gmx_sel_yydebug;
       know about them.  */
    enum yytokentype {
      INVALID = 258,
-     HELP = 259,
-     HELP_TOPIC = 260,
-     TOK_INT = 261,
-     TOK_REAL = 262,
-     STR = 263,
-     IDENTIFIER = 264,
-     CMD_SEP = 265,
-     GROUP = 266,
-     TO = 267,
-     VARIABLE_NUMERIC = 268,
-     VARIABLE_GROUP = 269,
-     VARIABLE_POS = 270,
-     KEYWORD_NUMERIC = 271,
-     KEYWORD_STR = 272,
-     KEYWORD_POS = 273,
-     KEYWORD_GROUP = 274,
-     METHOD_NUMERIC = 275,
-     METHOD_GROUP = 276,
-     METHOD_POS = 277,
-     MODIFIER = 278,
-     EMPTY_POSMOD = 279,
-     PARAM = 280,
-     END_OF_METHOD = 281,
-     OF = 282,
-     CMP_OP = 283,
-     PARAM_REDUCT = 284,
-     XOR = 285,
-     OR = 286,
-     AND = 287,
-     NOT = 288,
-     UNARY_NEG = 289,
-     NUM_REDUCT = 290
+     TOK_INT = 259,
+     TOK_REAL = 260,
+     STR = 261,
+     IDENTIFIER = 262,
+     CMD_SEP = 263,
+     GROUP = 264,
+     TO = 265,
+     VARIABLE_NUMERIC = 266,
+     VARIABLE_GROUP = 267,
+     VARIABLE_POS = 268,
+     KEYWORD_NUMERIC = 269,
+     KEYWORD_STR = 270,
+     KEYWORD_POS = 271,
+     KEYWORD_GROUP = 272,
+     METHOD_NUMERIC = 273,
+     METHOD_GROUP = 274,
+     METHOD_POS = 275,
+     MODIFIER = 276,
+     EMPTY_POSMOD = 277,
+     PARAM = 278,
+     END_OF_METHOD = 279,
+     OF = 280,
+     CMP_OP = 281,
+     PARAM_REDUCT = 282,
+     XOR = 283,
+     OR = 284,
+     AND = 285,
+     NOT = 286,
+     UNARY_NEG = 287,
+     NUM_REDUCT = 288
    };
 #endif
 
@@ -246,7 +244,7 @@ typedef union YYSTYPE
 
 
 /* Line 350 of yacc.c  */
-#line 250 "parser.cpp"
+#line 248 "parser.cpp"
 } YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
@@ -283,7 +281,7 @@ void _gmx_sel_yypstate_delete ();
 /* Copy the second part of user declarations.  */
 
 /* Line 353 of yacc.c  */
-#line 287 "parser.cpp"
+#line 285 "parser.cpp"
 
 #ifdef short
 # undef short
@@ -478,20 +476,20 @@ union yyalloc
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  2
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   361
+#define YYLAST   378
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  51
+#define YYNTOKENS  49
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  27
+#define YYNNTS  25
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  93
+#define YYNRULES  89
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  153
+#define YYNSTATES  149
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   290
+#define YYMAXUTOK   288
 
 #define YYTRANSLATE(YYX)                                               \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -503,15 +501,15 @@ static const yytype_uint8 yytranslate[] =
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-      42,    43,    36,    34,    47,    35,     2,    37,     2,     2,
+      40,    41,    34,    32,    45,    33,     2,    35,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,    41,     2,    45,     2,     2,     2,     2,     2,     2,
+       2,    39,     2,    43,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,    46,     2,    48,    39,     2,     2,     2,     2,     2,
+       2,    44,     2,    46,    37,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,    49,     2,    50,    44,     2,     2,     2,
+       2,     2,     2,    47,     2,    48,    42,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -527,72 +525,68 @@ static const yytype_uint8 yytranslate[] =
        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
        5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
       15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
-      25,    26,    27,    28,    29,    30,    31,    32,    33,    38,
-      40
+      25,    26,    27,    28,    29,    30,    31,    36,    38
 };
 
 #if YYDEBUG
 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
    YYRHS.  */
-static const yytype_uint16 yyprhs[] =
+static const yytype_uint8 yyprhs[] =
 {
        0,     0,     3,     4,     7,    10,    13,    14,    16,    18,
-      20,    22,    25,    29,    33,    37,    40,    41,    44,    46,
-      48,    52,    56,    58,    61,    63,    66,    68,    70,    72,
-      74,    77,    81,    85,    89,    93,    96,    99,   101,   103,
-     105,   107,   109,   112,   116,   121,   125,   129,   131,   133,
-     136,   140,   144,   148,   152,   156,   159,   163,   167,   169,
-     172,   180,   184,   187,   191,   193,   195,   197,   199,   202,
-     203,   206,   209,   211,   215,   216,   219,   223,   225,   229,
-     231,   234,   238,   240,   242,   244,   246,   248,   250,   252,
-     254,   256,   260,   264
+      20,    23,    27,    31,    35,    37,    39,    43,    47,    49,
+      52,    54,    57,    59,    61,    63,    65,    68,    72,    76,
+      80,    84,    87,    90,    92,    94,    96,    98,   100,   103,
+     107,   112,   116,   120,   122,   124,   127,   131,   135,   139,
+     143,   147,   150,   154,   158,   160,   163,   171,   175,   178,
+     182,   184,   186,   188,   190,   193,   194,   197,   200,   202,
+     206,   207,   210,   214,   216,   220,   222,   225,   229,   231,
+     233,   235,   237,   239,   241,   243,   245,   247,   251,   255
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
 static const yytype_int8 yyrhs[] =
 {
-      52,     0,    -1,    -1,    52,    53,    -1,    54,    10,    -1,
-       1,    10,    -1,    -1,    55,    -1,     6,    -1,    61,    -1,
-      57,    -1,    61,    57,    -1,     9,    41,    62,    -1,     9,
-      41,    65,    -1,     9,    41,    67,    -1,     4,    56,    -1,
-      -1,    56,     5,    -1,    67,    -1,    62,    -1,    42,    57,
-      43,    -1,    57,    23,    68,    -1,     6,    -1,    35,     6,
-      -1,     7,    -1,    35,     7,    -1,    58,    -1,    59,    -1,
-       8,    -1,     9,    -1,    33,    62,    -1,    62,    32,    62,
-      -1,    62,    31,    62,    -1,    42,    62,    43,    -1,    65,
-      28,    65,    -1,    11,    61,    -1,    11,     6,    -1,    24,
-      -1,    18,    -1,    44,    -1,    45,    -1,    41,    -1,    63,
-      19,    -1,    63,    17,    73,    -1,    63,    17,    64,    73,
-      -1,    63,    16,    73,    -1,    63,    21,    68,    -1,     6,
-      -1,     7,    -1,    63,    16,    -1,    63,    20,    68,    -1,
-      65,    34,    65,    -1,    65,    35,    65,    -1,    65,    36,
-      65,    -1,    65,    37,    65,    -1,    35,    65,    -1,    65,
-      39,    65,    -1,    42,    65,    43,    -1,    61,    -1,    63,
-      17,    -1,    46,    60,    47,    60,    47,    60,    48,    -1,
-      42,    67,    43,    -1,    22,    68,    -1,    18,    27,    62,
-      -1,    14,    -1,    13,    -1,    15,    -1,    69,    -1,    69,
-      26,    -1,    -1,    69,    70,    -1,    25,    71,    -1,    72,
-      -1,    49,    72,    50,    -1,    -1,    72,    75,    -1,    72,
-      47,    75,    -1,    74,    -1,    49,    74,    50,    -1,    76,
-      -1,    74,    76,    -1,    74,    47,    76,    -1,    62,    -1,
-      67,    -1,    65,    -1,    66,    -1,    77,    -1,    58,    -1,
-      59,    -1,    61,    -1,    77,    -1,    58,    12,    58,    -1,
-      58,    12,    59,    -1,    59,    12,    60,    -1
+      50,     0,    -1,    -1,    50,    51,    -1,    52,     8,    -1,
+       1,     8,    -1,    -1,     4,    -1,    57,    -1,    53,    -1,
+      57,    53,    -1,     7,    39,    58,    -1,     7,    39,    61,
+      -1,     7,    39,    63,    -1,    63,    -1,    58,    -1,    40,
+      53,    41,    -1,    53,    21,    64,    -1,     4,    -1,    33,
+       4,    -1,     5,    -1,    33,     5,    -1,    54,    -1,    55,
+      -1,     6,    -1,     7,    -1,    31,    58,    -1,    58,    30,
+      58,    -1,    58,    29,    58,    -1,    40,    58,    41,    -1,
+      61,    26,    61,    -1,     9,    57,    -1,     9,     4,    -1,
+      22,    -1,    16,    -1,    42,    -1,    43,    -1,    39,    -1,
+      59,    17,    -1,    59,    15,    69,    -1,    59,    15,    60,
+      69,    -1,    59,    14,    69,    -1,    59,    19,    64,    -1,
+       4,    -1,     5,    -1,    59,    14,    -1,    59,    18,    64,
+      -1,    61,    32,    61,    -1,    61,    33,    61,    -1,    61,
+      34,    61,    -1,    61,    35,    61,    -1,    33,    61,    -1,
+      61,    37,    61,    -1,    40,    61,    41,    -1,    57,    -1,
+      59,    15,    -1,    44,    56,    45,    56,    45,    56,    46,
+      -1,    40,    63,    41,    -1,    20,    64,    -1,    16,    25,
+      58,    -1,    12,    -1,    11,    -1,    13,    -1,    65,    -1,
+      65,    24,    -1,    -1,    65,    66,    -1,    23,    67,    -1,
+      68,    -1,    47,    68,    48,    -1,    -1,    68,    71,    -1,
+      68,    45,    71,    -1,    70,    -1,    47,    70,    48,    -1,
+      72,    -1,    70,    72,    -1,    70,    45,    72,    -1,    58,
+      -1,    63,    -1,    61,    -1,    62,    -1,    73,    -1,    54,
+      -1,    55,    -1,    57,    -1,    73,    -1,    54,    10,    54,
+      -1,    54,    10,    55,    -1,    55,    10,    56,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   199,   199,   204,   215,   216,   238,   244,   250,   261,
-     273,   279,   286,   293,   300,   311,   320,   325,   336,   337,
-     344,   345,   359,   360,   364,   365,   368,   369,   372,   373,
-     381,   392,   403,   414,   418,   429,   436,   445,   446,   451,
-     452,   453,   457,   465,   473,   481,   492,   507,   518,   532,
-     540,   551,   557,   563,   569,   575,   581,   587,   594,   605,
-     620,   629,   633,   643,   657,   665,   673,   686,   688,   694,
-     699,   710,   719,   720,   725,   730,   738,   749,   750,   754,
-     760,   768,   778,   784,   790,   796,   802,   806,   812,   818,
-     825,   829,   835,   841
+       0,   193,   193,   198,   209,   210,   232,   237,   248,   260,
+     266,   273,   280,   287,   297,   298,   305,   306,   320,   321,
+     325,   326,   329,   330,   333,   334,   342,   353,   364,   375,
+     379,   390,   397,   406,   407,   412,   413,   414,   418,   426,
+     434,   442,   453,   468,   479,   493,   501,   512,   518,   524,
+     530,   536,   542,   548,   555,   566,   581,   590,   594,   604,
+     618,   626,   634,   647,   649,   655,   660,   671,   680,   681,
+     686,   691,   699,   710,   711,   715,   721,   729,   739,   745,
+     751,   757,   763,   767,   773,   779,   786,   790,   796,   802
 };
 #endif
 
@@ -601,17 +595,16 @@ static const yytype_uint16 yyrline[] =
    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
 static const char *const yytname[] =
 {
-  "$end", "error", "$undefined", "INVALID", "HELP", "HELP_TOPIC",
-  "TOK_INT", "TOK_REAL", "STR", "IDENTIFIER", "CMD_SEP", "GROUP", "TO",
-  "VARIABLE_NUMERIC", "VARIABLE_GROUP", "VARIABLE_POS", "KEYWORD_NUMERIC",
-  "KEYWORD_STR", "KEYWORD_POS", "KEYWORD_GROUP", "METHOD_NUMERIC",
-  "METHOD_GROUP", "METHOD_POS", "MODIFIER", "EMPTY_POSMOD", "PARAM",
-  "END_OF_METHOD", "OF", "CMP_OP", "PARAM_REDUCT", "XOR", "OR", "AND",
-  "NOT", "'+'", "'-'", "'*'", "'/'", "UNARY_NEG", "'^'", "NUM_REDUCT",
-  "'='", "'('", "')'", "'~'", "'?'", "'['", "','", "']'", "'{'", "'}'",
-  "$accept", "commands", "command", "cmd_plain", "help_request",
-  "help_topic", "selection", "integer_number", "real_number", "number",
-  "string", "sel_expr", "pos_mod", "str_match_type", "num_expr",
+  "$end", "error", "$undefined", "INVALID", "TOK_INT", "TOK_REAL", "STR",
+  "IDENTIFIER", "CMD_SEP", "GROUP", "TO", "VARIABLE_NUMERIC",
+  "VARIABLE_GROUP", "VARIABLE_POS", "KEYWORD_NUMERIC", "KEYWORD_STR",
+  "KEYWORD_POS", "KEYWORD_GROUP", "METHOD_NUMERIC", "METHOD_GROUP",
+  "METHOD_POS", "MODIFIER", "EMPTY_POSMOD", "PARAM", "END_OF_METHOD", "OF",
+  "CMP_OP", "PARAM_REDUCT", "XOR", "OR", "AND", "NOT", "'+'", "'-'", "'*'",
+  "'/'", "UNARY_NEG", "'^'", "NUM_REDUCT", "'='", "'('", "')'", "'~'",
+  "'?'", "'['", "','", "']'", "'{'", "'}'", "$accept", "commands",
+  "command", "cmd_plain", "selection", "integer_number", "real_number",
+  "number", "string", "sel_expr", "pos_mod", "str_match_type", "num_expr",
   "str_expr", "pos_expr", "method_params", "method_param_list",
   "method_param", "value_list", "value_list_contents", "basic_value_list",
   "basic_value_list_contents", "value_item", "basic_value_item",
@@ -627,40 +620,37 @@ static const yytype_uint16 yytoknum[] =
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
      265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
      275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
-     285,   286,   287,   288,    43,    45,    42,    47,   289,    94,
-     290,    61,    40,    41,   126,    63,    91,    44,    93,   123,
-     125
+     285,   286,    43,    45,    42,    47,   287,    94,   288,    61,
+      40,    41,   126,    63,    91,    44,    93,   123,   125
 };
 # endif
 
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,    51,    52,    52,    53,    53,    54,    54,    54,    54,
-      54,    54,    54,    54,    54,    55,    56,    56,    57,    57,
-      57,    57,    58,    58,    59,    59,    60,    60,    61,    61,
-      62,    62,    62,    62,    62,    62,    62,    63,    63,    64,
-      64,    64,    62,    62,    62,    62,    62,    65,    65,    65,
-      65,    65,    65,    65,    65,    65,    65,    65,    66,    66,
-      67,    67,    67,    67,    62,    65,    67,    68,    68,    69,
-      69,    70,    71,    71,    72,    72,    72,    73,    73,    74,
-      74,    74,    75,    75,    75,    75,    75,    76,    76,    76,
-      76,    77,    77,    77
+       0,    49,    50,    50,    51,    51,    52,    52,    52,    52,
+      52,    52,    52,    52,    53,    53,    53,    53,    54,    54,
+      55,    55,    56,    56,    57,    57,    58,    58,    58,    58,
+      58,    58,    58,    59,    59,    60,    60,    60,    58,    58,
+      58,    58,    58,    61,    61,    61,    61,    61,    61,    61,
+      61,    61,    61,    61,    62,    62,    63,    63,    63,    63,
+      58,    61,    63,    64,    64,    65,    65,    66,    67,    67,
+      68,    68,    68,    69,    69,    70,    70,    70,    71,    71,
+      71,    71,    71,    72,    72,    72,    72,    73,    73,    73
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
 static const yytype_uint8 yyr2[] =
 {
        0,     2,     0,     2,     2,     2,     0,     1,     1,     1,
-       1,     2,     3,     3,     3,     2,     0,     2,     1,     1,
-       3,     3,     1,     2,     1,     2,     1,     1,     1,     1,
-       2,     3,     3,     3,     3,     2,     2,     1,     1,     1,
-       1,     1,     2,     3,     4,     3,     3,     1,     1,     2,
-       3,     3,     3,     3,     3,     2,     3,     3,     1,     2,
-       7,     3,     2,     3,     1,     1,     1,     1,     2,     0,
-       2,     2,     1,     3,     0,     2,     3,     1,     3,     1,
-       2,     3,     1,     1,     1,     1,     1,     1,     1,     1,
-       1,     3,     3,     3
+       2,     3,     3,     3,     1,     1,     3,     3,     1,     2,
+       1,     2,     1,     1,     1,     1,     2,     3,     3,     3,
+       3,     2,     2,     1,     1,     1,     1,     1,     2,     3,
+       4,     3,     3,     1,     1,     2,     3,     3,     3,     3,
+       3,     2,     3,     3,     1,     2,     7,     3,     2,     3,
+       1,     1,     1,     1,     2,     0,     2,     2,     1,     3,
+       0,     2,     3,     1,     3,     1,     2,     3,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     3,     3,     3
 };
 
 /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
@@ -668,175 +658,174 @@ static const yytype_uint8 yyr2[] =
    means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
-       2,     0,     1,     0,    16,    47,    48,    28,    29,     0,
-      65,    64,    66,    38,    69,    37,     0,     0,     0,     0,
-       3,     0,     7,    10,     9,    19,     0,     0,    18,     5,
-      15,     0,    36,    29,    35,     0,    62,    67,    47,    38,
-       0,    30,     0,     0,    55,     0,    19,     0,    18,    22,
-      24,     0,    26,    27,     0,     4,    69,    11,     0,     0,
-      49,     0,    42,    69,    69,     0,     0,     0,     0,     0,
-       0,    17,     0,    12,    13,    14,    63,    74,    68,    70,
-       0,     0,    49,    20,    33,    57,    61,    23,    25,     0,
-      21,    32,    31,     0,    87,    88,    89,    45,    77,    79,
-      90,    41,    39,    40,     0,    43,    50,    46,    34,    51,
-      52,    53,    54,    56,     0,    74,    71,    72,     0,     0,
-       0,     0,     0,    80,    44,     0,    47,    48,     0,     0,
-       0,     0,    58,    82,     0,    84,    85,    83,    75,    86,
-       0,    78,    91,    92,    93,    81,    73,    47,    48,    76,
-      59,     0,    60
+       2,     0,     1,     0,    43,    44,    24,    25,     0,    61,
+      60,    62,    34,    65,    33,     0,     0,     0,     0,     3,
+       0,     9,     8,    15,     0,     0,    14,     5,     0,    32,
+      25,    31,     0,    58,    63,    43,    34,     0,    26,     0,
+       0,    51,     0,    15,     0,    14,    18,    20,     0,    22,
+      23,     0,     4,    65,    10,     0,     0,    45,     0,    38,
+      65,    65,     0,     0,     0,     0,     0,     0,     0,    11,
+      12,    13,    59,    70,    64,    66,     0,     0,    45,    16,
+      29,    53,    57,    19,    21,     0,    17,    28,    27,     0,
+      83,    84,    85,    41,    73,    75,    86,    37,    35,    36,
+       0,    39,    46,    42,    30,    47,    48,    49,    50,    52,
+       0,    70,    67,    68,     0,     0,     0,     0,     0,    76,
+      40,     0,    43,    44,     0,     0,     0,     0,    54,    78,
+       0,    80,    81,    79,    71,    82,     0,    74,    87,    88,
+      89,    77,    69,    43,    44,    72,    55,     0,    56
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-      -1,     1,    20,    21,    22,    30,    23,    94,    95,    54,
-      96,   133,    26,   104,    27,   136,   137,    36,    37,    79,
-     116,   117,   105,    98,   138,    99,   100
+      -1,     1,    19,    20,    21,    90,    91,    51,    92,   129,
+      24,   100,    25,   132,   133,    33,    34,    75,   112,   113,
+     101,    94,   134,    95,    96
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -95
+#define YYPACT_NINF -84
 static const yytype_int16 yypact[] =
 {
-     -95,   134,   -95,     2,   -95,     4,   -95,   -95,   -17,   145,
-     -95,   -95,   -95,     1,   -95,   -95,   283,   299,   246,    20,
-     -95,    23,   -95,    18,   246,    87,   323,   150,   -95,   -95,
-      44,   269,   -95,   -95,   -95,   283,   -95,    57,   -95,   -95,
-     283,   -95,   299,    78,    15,    19,   -22,   193,    58,   -95,
-     -95,   167,   -95,   -95,    59,   -95,   -95,    18,   283,   283,
-      81,    51,   -95,   -95,   -95,   299,   299,   299,   299,   299,
-     299,   -95,   269,    87,   150,   -95,    87,    61,   -95,   -95,
-     -22,   293,   -95,   -95,   -95,   -95,   -95,   -95,   -95,    20,
-     -95,    76,   -95,    11,   102,   108,   -95,   -95,   187,   -95,
-     -95,   -95,   -95,   -95,   153,   -95,   -95,   -95,   315,   161,
-     161,    15,    15,    15,    58,   -95,   -95,   202,    82,    -3,
-      20,    20,    11,   -95,   -95,   157,   119,   127,   313,   232,
-     102,   108,   -95,    87,   340,   315,   -95,   -95,   -95,   -95,
-      20,   -95,   -95,   -95,   -95,   -95,   -95,   138,   143,   -95,
-      51,    98,   -95
+     -84,   148,   -84,     4,     6,   -84,   -84,   -20,   189,   -84,
+     -84,   -84,     1,   -84,   -84,   322,   216,   285,     0,   -84,
+      27,    16,   285,    22,   122,   173,   -84,   -84,   308,   -84,
+     -84,   -84,   322,   -84,    71,   -84,   -84,   322,   -84,   216,
+      49,    24,   -11,   -13,   232,    23,   -84,   -84,   140,   -84,
+     -84,    21,   -84,   -84,    16,   322,   322,    40,   197,   -84,
+     -84,   -84,   216,   216,   216,   216,   216,   216,   308,    22,
+     173,   -84,    22,    30,   -84,   -84,   -13,    47,   -84,   -84,
+     -84,   -84,   -84,   -84,   -84,     0,   -84,    56,   -84,    85,
+      93,    99,   -84,   -84,   210,   -84,   -84,   -84,   -84,   -84,
+      36,   -84,   -84,   -84,   139,    94,    94,    24,    24,    24,
+      23,   -84,   -84,   241,    78,    17,     0,     0,    85,   -84,
+     -84,   178,   116,   125,   338,   271,    93,    99,   -84,    22,
+     349,   139,   -84,   -84,   -84,   -84,     0,   -84,   -84,   -84,
+     -84,   -84,   -84,   133,   136,   -84,   197,   104,   -84
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int8 yypgoto[] =
 {
-     -95,   -95,   -95,   -95,   -95,   -95,    67,   -18,    -8,   -87,
-      -1,    21,     8,   -95,    -2,   -95,    12,    41,   -95,   -95,
-     -95,    42,   -53,    84,    53,   -50,   -94
+     -84,   -84,   -84,   -84,    -4,   -17,   -15,   -83,    -1,   110,
+       9,   -84,    -8,   -84,    10,    54,   -84,   -84,   -84,    51,
+     -51,    62,    33,   -79,   -28
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
    number is the opposite.  If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -26
+#define YYTABLE_NINF -22
 static const yytype_int16 yytable[] =
 {
-      24,    52,   118,    49,    50,     7,    33,    97,    34,    58,
-      59,    53,    29,    28,    -8,    44,    47,    49,    50,     7,
-      33,    84,    25,   139,    31,    43,    49,    50,    35,    74,
-      48,   139,    51,    55,   144,   139,    28,    41,    47,    46,
-      81,    56,    56,    75,   122,    25,    51,   141,   123,    71,
-      43,   124,    73,   151,    70,    51,    76,    49,    50,     7,
-      33,    80,    83,   108,   109,   110,   111,   112,   113,   123,
-      47,    52,   145,    43,    43,    43,    43,    43,    43,    91,
-      92,    53,    77,    78,   114,    45,    51,    49,    50,     7,
-      33,    57,   101,    80,    82,   102,   103,    90,    63,   130,
-      93,    86,   142,    52,   106,   107,    89,   130,    59,   131,
-     115,   130,   143,    53,   120,   135,   132,   131,    58,    59,
-     121,   131,    52,   135,   132,   134,    44,   135,   132,   140,
-      93,   -22,    53,   134,     2,     3,    43,   134,     4,   -24,
-       5,     6,     7,     8,    -6,     9,   152,    10,    11,    12,
-     -23,    32,    13,     7,    33,   -25,    14,   125,    15,    49,
-      50,     7,    33,   126,   127,     7,    33,    16,     9,    17,
-      10,    11,    12,    87,    88,    13,    18,   119,    65,    14,
-      19,    15,   149,     0,    66,    67,    68,    69,    51,    70,
-      16,     0,   128,    49,    50,     7,    33,    68,    69,    72,
-      70,     0,    93,    19,   129,     0,     0,   146,   126,   127,
-       7,    33,     0,     9,     0,    10,    11,    12,     0,     0,
-      13,    65,    51,     0,    14,     0,    15,    66,    67,    68,
-      69,     0,    70,     0,   122,    16,    85,   128,   126,   127,
-       7,    33,     0,     9,    72,    10,    11,    12,    19,   129,
-      13,     0,    38,     6,    14,     0,    15,     9,     0,    10,
-      11,    12,     0,     0,    13,    16,     0,   128,    14,     0,
-      15,     0,     0,     0,    72,    38,     6,     0,    19,    16,
-       9,    17,    10,    11,    12,     0,     0,    13,    18,    38,
-       6,    14,    19,    15,     9,     0,    10,    11,     0,     0,
-       0,    39,    16,     0,    17,    38,     6,    15,     0,     0,
-       0,    72,    10,     0,     0,    19,    16,    39,    17,   147,
-     148,     0,     0,    15,     0,    40,    10,    66,    67,    68,
-      69,    39,    70,     0,    17,     0,    85,    15,     0,    60,
-      61,    42,    62,    63,    64,     0,     0,     0,    17,    66,
-      67,    68,    69,     0,    70,    42,    60,   150,     0,    62,
-      63,    64
+      22,    49,   114,    50,    46,    47,    93,    31,    41,    44,
+      53,    26,    27,    42,    -7,   119,    55,    56,    54,    28,
+      70,    46,    47,     6,    30,    40,    32,    45,    80,    44,
+      79,    77,    26,    48,   140,    52,   119,    53,    71,   141,
+      46,    47,     6,    30,    46,    47,     6,    30,    40,   120,
+      48,    55,    56,   147,   104,   105,   106,   107,   108,   109,
+      44,    67,   118,    78,    82,   137,    85,    60,    49,    48,
+      50,    40,    40,    40,    40,    40,    40,   111,   110,    63,
+      64,    65,    66,    89,    67,   135,    56,    89,    81,    46,
+      47,     6,    30,   135,    73,    74,   126,   135,   127,   138,
+      49,   139,    50,   116,   126,   131,   127,    86,   126,   117,
+     127,    23,   128,   131,   102,   103,    41,   131,    48,    49,
+     128,    50,   130,   136,   128,    38,   -18,    43,    65,    66,
+     130,    67,    23,    40,   130,   -20,    57,    58,    69,    59,
+      60,    61,    72,   -19,    83,    84,   -21,    76,     2,     3,
+     148,   115,     4,     5,     6,     7,    -6,     8,   145,     9,
+      10,    11,   121,     0,    12,    87,    88,     0,    13,     0,
+      14,    63,    64,    65,    66,     0,    67,     0,    76,    15,
+       0,    16,   122,   123,     6,    30,     0,     8,    17,     9,
+      10,    11,    18,    29,    12,     6,    30,     0,    13,    62,
+      14,    46,    47,     6,    30,    63,    64,    65,    66,    15,
+      67,   124,     0,     0,    46,    47,     6,    30,    68,     0,
+      35,     5,    18,   125,     0,     0,   142,     9,     0,     0,
+      48,     0,    36,     0,     0,     0,    97,     0,    14,    98,
+      99,     0,     0,    48,    89,   122,   123,     6,    30,    16,
+       8,     0,     9,    10,    11,   118,    39,    12,    62,     0,
+       0,    13,     0,    14,    63,    64,    65,    66,     0,    67,
+       0,     0,    15,    81,   124,   122,   123,     6,    30,     0,
+       8,    68,     9,    10,    11,    18,   125,    12,     0,    35,
+       5,    13,     0,    14,     8,     0,     9,    10,    11,     0,
+       0,    12,    15,     0,   124,    13,     0,    14,     0,     0,
+       0,    68,    35,     5,     0,    18,    15,     8,    16,     9,
+      10,    11,     0,     0,    12,    17,    35,     5,    13,    18,
+      14,     8,     0,     9,    10,     0,     0,     0,    36,    15,
+       0,    16,   143,   144,    14,     0,     0,     0,    68,     9,
+       0,     0,    18,    15,    36,    16,     0,     0,     0,     0,
+      14,     0,    37,    57,   146,     0,    59,    60,    61,     0,
+       0,    16,     0,     0,     0,     0,     0,     0,    39
 };
 
 #define yypact_value_is_default(yystate) \
-  ((yystate) == (-95))
+  ((yystate) == (-84))
 
 #define yytable_value_is_error(yytable_value) \
   YYID (0)
 
 static const yytype_int16 yycheck[] =
 {
-       1,    19,    89,     6,     7,     8,     9,    60,     9,    31,
-      32,    19,    10,     1,    10,    17,    18,     6,     7,     8,
-       9,    43,     1,   117,    41,    17,     6,     7,    27,    31,
-      18,   125,    35,    10,   121,   129,    24,    16,    40,    18,
-      42,    23,    23,    31,    47,    24,    35,    50,    98,     5,
-      42,   104,    31,   140,    39,    35,    35,     6,     7,     8,
-       9,    40,    43,    65,    66,    67,    68,    69,    70,   119,
-      72,    89,   122,    65,    66,    67,    68,    69,    70,    58,
-      59,    89,    25,    26,    72,    18,    35,     6,     7,     8,
-       9,    24,    41,    72,    16,    44,    45,    56,    20,   117,
-      49,    43,   120,   121,    63,    64,    47,   125,    32,   117,
-      49,   129,   120,   121,    12,   117,   117,   125,    31,    32,
-      12,   129,   140,   125,   125,   117,   128,   129,   129,    47,
-      49,    12,   140,   125,     0,     1,   128,   129,     4,    12,
-       6,     7,     8,     9,    10,    11,    48,    13,    14,    15,
-      12,     6,    18,     8,     9,    12,    22,   115,    24,     6,
-       7,     8,     9,     6,     7,     8,     9,    33,    11,    35,
-      13,    14,    15,     6,     7,    18,    42,    93,    28,    22,
-      46,    24,   129,    -1,    34,    35,    36,    37,    35,    39,
-      33,    -1,    35,     6,     7,     8,     9,    36,    37,    42,
-      39,    -1,    49,    46,    47,    -1,    -1,    50,     6,     7,
-       8,     9,    -1,    11,    -1,    13,    14,    15,    -1,    -1,
-      18,    28,    35,    -1,    22,    -1,    24,    34,    35,    36,
-      37,    -1,    39,    -1,    47,    33,    43,    35,     6,     7,
-       8,     9,    -1,    11,    42,    13,    14,    15,    46,    47,
-      18,    -1,     6,     7,    22,    -1,    24,    11,    -1,    13,
-      14,    15,    -1,    -1,    18,    33,    -1,    35,    22,    -1,
-      24,    -1,    -1,    -1,    42,     6,     7,    -1,    46,    33,
-      11,    35,    13,    14,    15,    -1,    -1,    18,    42,     6,
-       7,    22,    46,    24,    11,    -1,    13,    14,    -1,    -1,
-      -1,    18,    33,    -1,    35,     6,     7,    24,    -1,    -1,
-      -1,    42,    13,    -1,    -1,    46,    33,    18,    35,     6,
-       7,    -1,    -1,    24,    -1,    42,    13,    34,    35,    36,
-      37,    18,    39,    -1,    35,    -1,    43,    24,    -1,    16,
-      17,    42,    19,    20,    21,    -1,    -1,    -1,    35,    34,
-      35,    36,    37,    -1,    39,    42,    16,    17,    -1,    19,
-      20,    21
+       1,    18,    85,    18,     4,     5,    57,     8,    16,    17,
+      21,     1,     8,    17,     8,    94,    29,    30,    22,    39,
+      28,     4,     5,     6,     7,    16,    25,    17,    41,    37,
+      41,    39,    22,    33,   117,     8,   115,    21,    28,   118,
+       4,     5,     6,     7,     4,     5,     6,     7,    39,   100,
+      33,    29,    30,   136,    62,    63,    64,    65,    66,    67,
+      68,    37,    45,    14,    41,    48,    45,    18,    85,    33,
+      85,    62,    63,    64,    65,    66,    67,    47,    68,    32,
+      33,    34,    35,    47,    37,   113,    30,    47,    41,     4,
+       5,     6,     7,   121,    23,    24,   113,   125,   113,   116,
+     117,   116,   117,    10,   121,   113,   121,    53,   125,    10,
+     125,     1,   113,   121,    60,    61,   124,   125,    33,   136,
+     121,   136,   113,    45,   125,    15,    10,    17,    34,    35,
+     121,    37,    22,   124,   125,    10,    14,    15,    28,    17,
+      18,    19,    32,    10,     4,     5,    10,    37,     0,     1,
+      46,    89,     4,     5,     6,     7,     8,     9,   125,    11,
+      12,    13,   111,    -1,    16,    55,    56,    -1,    20,    -1,
+      22,    32,    33,    34,    35,    -1,    37,    -1,    68,    31,
+      -1,    33,     4,     5,     6,     7,    -1,     9,    40,    11,
+      12,    13,    44,     4,    16,     6,     7,    -1,    20,    26,
+      22,     4,     5,     6,     7,    32,    33,    34,    35,    31,
+      37,    33,    -1,    -1,     4,     5,     6,     7,    40,    -1,
+       4,     5,    44,    45,    -1,    -1,    48,    11,    -1,    -1,
+      33,    -1,    16,    -1,    -1,    -1,    39,    -1,    22,    42,
+      43,    -1,    -1,    33,    47,     4,     5,     6,     7,    33,
+       9,    -1,    11,    12,    13,    45,    40,    16,    26,    -1,
+      -1,    20,    -1,    22,    32,    33,    34,    35,    -1,    37,
+      -1,    -1,    31,    41,    33,     4,     5,     6,     7,    -1,
+       9,    40,    11,    12,    13,    44,    45,    16,    -1,     4,
+       5,    20,    -1,    22,     9,    -1,    11,    12,    13,    -1,
+      -1,    16,    31,    -1,    33,    20,    -1,    22,    -1,    -1,
+      -1,    40,     4,     5,    -1,    44,    31,     9,    33,    11,
+      12,    13,    -1,    -1,    16,    40,     4,     5,    20,    44,
+      22,     9,    -1,    11,    12,    -1,    -1,    -1,    16,    31,
+      -1,    33,     4,     5,    22,    -1,    -1,    -1,    40,    11,
+      -1,    -1,    44,    31,    16,    33,    -1,    -1,    -1,    -1,
+      22,    -1,    40,    14,    15,    -1,    17,    18,    19,    -1,
+      -1,    33,    -1,    -1,    -1,    -1,    -1,    -1,    40
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
    symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
-       0,    52,     0,     1,     4,     6,     7,     8,     9,    11,
-      13,    14,    15,    18,    22,    24,    33,    35,    42,    46,
-      53,    54,    55,    57,    61,    62,    63,    65,    67,    10,
-      56,    41,     6,     9,    61,    27,    68,    69,     6,    18,
-      42,    62,    42,    63,    65,    57,    62,    65,    67,     6,
-       7,    35,    58,    59,    60,    10,    23,    57,    31,    32,
-      16,    17,    19,    20,    21,    28,    34,    35,    36,    37,
-      39,     5,    42,    62,    65,    67,    62,    25,    26,    70,
-      62,    65,    16,    43,    43,    43,    43,     6,     7,    47,
-      68,    62,    62,    49,    58,    59,    61,    73,    74,    76,
-      77,    41,    44,    45,    64,    73,    68,    68,    65,    65,
-      65,    65,    65,    65,    67,    49,    71,    72,    60,    74,
-      12,    12,    47,    76,    73,    72,     6,     7,    35,    47,
-      58,    59,    61,    62,    63,    65,    66,    67,    75,    77,
-      47,    50,    58,    59,    60,    76,    50,     6,     7,    75,
-      17,    60,    48
+       0,    50,     0,     1,     4,     5,     6,     7,     9,    11,
+      12,    13,    16,    20,    22,    31,    33,    40,    44,    51,
+      52,    53,    57,    58,    59,    61,    63,     8,    39,     4,
+       7,    57,    25,    64,    65,     4,    16,    40,    58,    40,
+      59,    61,    53,    58,    61,    63,     4,     5,    33,    54,
+      55,    56,     8,    21,    53,    29,    30,    14,    15,    17,
+      18,    19,    26,    32,    33,    34,    35,    37,    40,    58,
+      61,    63,    58,    23,    24,    66,    58,    61,    14,    41,
+      41,    41,    41,     4,     5,    45,    64,    58,    58,    47,
+      54,    55,    57,    69,    70,    72,    73,    39,    42,    43,
+      60,    69,    64,    64,    61,    61,    61,    61,    61,    61,
+      63,    47,    67,    68,    56,    70,    10,    10,    45,    72,
+      69,    68,     4,     5,    33,    45,    54,    55,    57,    58,
+      59,    61,    62,    63,    71,    73,    45,    48,    54,    55,
+      56,    72,    48,     4,     5,    71,    15,    56,    46
 };
 
 #define yyerrok                (yyerrstatus = 0)
@@ -1382,194 +1371,180 @@ yydestruct (yymsg, yytype, yyvaluep, scanner)
 
   switch (yytype)
     {
-      case 5: /* HELP_TOPIC */
+      case 6: /* STR */
 /* Line 1381 of yacc.c  */
-#line 178 "parser.y"
-       { free(((*yyvaluep).str));        };
-/* Line 1381 of yacc.c  */
-#line 1391 "parser.cpp"
-       break;
-      case 8: /* STR */
-/* Line 1381 of yacc.c  */
-#line 178 "parser.y"
+#line 173 "parser.y"
        { free(((*yyvaluep).str));        };
 /* Line 1381 of yacc.c  */
-#line 1398 "parser.cpp"
+#line 1380 "parser.cpp"
        break;
-      case 9: /* IDENTIFIER */
+      case 7: /* IDENTIFIER */
 /* Line 1381 of yacc.c  */
-#line 178 "parser.y"
+#line 173 "parser.y"
        { free(((*yyvaluep).str));        };
 /* Line 1381 of yacc.c  */
-#line 1405 "parser.cpp"
+#line 1387 "parser.cpp"
        break;
-      case 18: /* KEYWORD_POS */
+      case 16: /* KEYWORD_POS */
 /* Line 1381 of yacc.c  */
-#line 178 "parser.y"
+#line 173 "parser.y"
        { free(((*yyvaluep).str));        };
 /* Line 1381 of yacc.c  */
-#line 1412 "parser.cpp"
+#line 1394 "parser.cpp"
        break;
-      case 25: /* PARAM */
+      case 23: /* PARAM */
 /* Line 1381 of yacc.c  */
-#line 179 "parser.y"
+#line 174 "parser.y"
        { if(((*yyvaluep).str)) free(((*yyvaluep).str)); };
 /* Line 1381 of yacc.c  */
-#line 1419 "parser.cpp"
+#line 1401 "parser.cpp"
        break;
-      case 28: /* CMP_OP */
+      case 26: /* CMP_OP */
 /* Line 1381 of yacc.c  */
-#line 178 "parser.y"
+#line 173 "parser.y"
        { free(((*yyvaluep).str));        };
 /* Line 1381 of yacc.c  */
-#line 1426 "parser.cpp"
+#line 1408 "parser.cpp"
        break;
-      case 52: /* commands */
+      case 50: /* commands */
 /* Line 1381 of yacc.c  */
-#line 180 "parser.y"
+#line 175 "parser.y"
        { delete ((*yyvaluep).sel);       };
 /* Line 1381 of yacc.c  */
-#line 1433 "parser.cpp"
+#line 1415 "parser.cpp"
        break;
-      case 53: /* command */
+      case 51: /* command */
 /* Line 1381 of yacc.c  */
-#line 180 "parser.y"
+#line 175 "parser.y"
        { delete ((*yyvaluep).sel);       };
 /* Line 1381 of yacc.c  */
-#line 1440 "parser.cpp"
+#line 1422 "parser.cpp"
        break;
-      case 54: /* cmd_plain */
+      case 52: /* cmd_plain */
 /* Line 1381 of yacc.c  */
-#line 180 "parser.y"
+#line 175 "parser.y"
        { delete ((*yyvaluep).sel);       };
 /* Line 1381 of yacc.c  */
-#line 1447 "parser.cpp"
-       break;
-      case 56: /* help_topic */
-/* Line 1381 of yacc.c  */
-#line 185 "parser.y"
-       { delete ((*yyvaluep).vlist);       };
-/* Line 1381 of yacc.c  */
-#line 1454 "parser.cpp"
+#line 1429 "parser.cpp"
        break;
-      case 57: /* selection */
+      case 53: /* selection */
 /* Line 1381 of yacc.c  */
-#line 180 "parser.y"
+#line 175 "parser.y"
        { delete ((*yyvaluep).sel);       };
 /* Line 1381 of yacc.c  */
-#line 1461 "parser.cpp"
+#line 1436 "parser.cpp"
        break;
-      case 61: /* string */
+      case 57: /* string */
 /* Line 1381 of yacc.c  */
-#line 178 "parser.y"
+#line 173 "parser.y"
        { free(((*yyvaluep).str));        };
 /* Line 1381 of yacc.c  */
-#line 1468 "parser.cpp"
+#line 1443 "parser.cpp"
        break;
-      case 62: /* sel_expr */
+      case 58: /* sel_expr */
 /* Line 1381 of yacc.c  */
-#line 181 "parser.y"
+#line 176 "parser.y"
        { delete ((*yyvaluep).sel);       };
 /* Line 1381 of yacc.c  */
-#line 1475 "parser.cpp"
+#line 1450 "parser.cpp"
        break;
-      case 63: /* pos_mod */
+      case 59: /* pos_mod */
 /* Line 1381 of yacc.c  */
-#line 179 "parser.y"
+#line 174 "parser.y"
        { if(((*yyvaluep).str)) free(((*yyvaluep).str)); };
 /* Line 1381 of yacc.c  */
-#line 1482 "parser.cpp"
+#line 1457 "parser.cpp"
        break;
-      case 65: /* num_expr */
+      case 61: /* num_expr */
 /* Line 1381 of yacc.c  */
-#line 181 "parser.y"
+#line 176 "parser.y"
        { delete ((*yyvaluep).sel);       };
 /* Line 1381 of yacc.c  */
-#line 1489 "parser.cpp"
+#line 1464 "parser.cpp"
        break;
-      case 66: /* str_expr */
+      case 62: /* str_expr */
 /* Line 1381 of yacc.c  */
-#line 181 "parser.y"
+#line 176 "parser.y"
        { delete ((*yyvaluep).sel);       };
 /* Line 1381 of yacc.c  */
-#line 1496 "parser.cpp"
+#line 1471 "parser.cpp"
        break;
-      case 67: /* pos_expr */
+      case 63: /* pos_expr */
 /* Line 1381 of yacc.c  */
-#line 181 "parser.y"
+#line 176 "parser.y"
        { delete ((*yyvaluep).sel);       };
 /* Line 1381 of yacc.c  */
-#line 1503 "parser.cpp"
+#line 1478 "parser.cpp"
        break;
-      case 68: /* method_params */
+      case 64: /* method_params */
 /* Line 1381 of yacc.c  */
-#line 182 "parser.y"
+#line 177 "parser.y"
        { delete ((*yyvaluep).plist);       };
 /* Line 1381 of yacc.c  */
-#line 1510 "parser.cpp"
+#line 1485 "parser.cpp"
        break;
-      case 69: /* method_param_list */
+      case 65: /* method_param_list */
 /* Line 1381 of yacc.c  */
-#line 182 "parser.y"
+#line 177 "parser.y"
        { delete ((*yyvaluep).plist);       };
 /* Line 1381 of yacc.c  */
-#line 1517 "parser.cpp"
+#line 1492 "parser.cpp"
        break;
-      case 70: /* method_param */
+      case 66: /* method_param */
 /* Line 1381 of yacc.c  */
-#line 182 "parser.y"
+#line 177 "parser.y"
        { delete ((*yyvaluep).param);       };
 /* Line 1381 of yacc.c  */
-#line 1524 "parser.cpp"
+#line 1499 "parser.cpp"
        break;
-      case 71: /* value_list */
+      case 67: /* value_list */
 /* Line 1381 of yacc.c  */
-#line 183 "parser.y"
+#line 178 "parser.y"
        { delete ((*yyvaluep).vlist);       };
 /* Line 1381 of yacc.c  */
-#line 1531 "parser.cpp"
+#line 1506 "parser.cpp"
        break;
-      case 72: /* value_list_contents */
+      case 68: /* value_list_contents */
 /* Line 1381 of yacc.c  */
-#line 183 "parser.y"
+#line 178 "parser.y"
        { delete ((*yyvaluep).vlist);       };
 /* Line 1381 of yacc.c  */
-#line 1538 "parser.cpp"
+#line 1513 "parser.cpp"
        break;
-      case 73: /* basic_value_list */
+      case 69: /* basic_value_list */
 /* Line 1381 of yacc.c  */
-#line 183 "parser.y"
+#line 178 "parser.y"
        { delete ((*yyvaluep).vlist);       };
 /* Line 1381 of yacc.c  */
-#line 1545 "parser.cpp"
+#line 1520 "parser.cpp"
        break;
-      case 74: /* basic_value_list_contents */
+      case 70: /* basic_value_list_contents */
 /* Line 1381 of yacc.c  */
-#line 183 "parser.y"
+#line 178 "parser.y"
        { delete ((*yyvaluep).vlist);       };
 /* Line 1381 of yacc.c  */
-#line 1552 "parser.cpp"
+#line 1527 "parser.cpp"
        break;
-      case 75: /* value_item */
+      case 71: /* value_item */
 /* Line 1381 of yacc.c  */
-#line 184 "parser.y"
+#line 179 "parser.y"
        { delete ((*yyvaluep).val);       };
 /* Line 1381 of yacc.c  */
-#line 1559 "parser.cpp"
+#line 1534 "parser.cpp"
        break;
-      case 76: /* basic_value_item */
+      case 72: /* basic_value_item */
 /* Line 1381 of yacc.c  */
-#line 184 "parser.y"
+#line 179 "parser.y"
        { delete ((*yyvaluep).val);       };
 /* Line 1381 of yacc.c  */
-#line 1566 "parser.cpp"
+#line 1541 "parser.cpp"
        break;
-      case 77: /* value_item_range */
+      case 73: /* value_item_range */
 /* Line 1381 of yacc.c  */
-#line 184 "parser.y"
+#line 179 "parser.y"
        { delete ((*yyvaluep).val);       };
 /* Line 1381 of yacc.c  */
-#line 1573 "parser.cpp"
+#line 1548 "parser.cpp"
        break;
 
       default:
@@ -1917,7 +1892,7 @@ yyreduce:
     {
         case 2:
 /* Line 1787 of yacc.c  */
-#line 199 "parser.y"
+#line 193 "parser.y"
     {
                  BEGIN_ACTION;
                  set_empty((yyval.sel));
@@ -1927,7 +1902,7 @@ yyreduce:
 
   case 3:
 /* Line 1787 of yacc.c  */
-#line 205 "parser.y"
+#line 199 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.sel), _gmx_sel_append_selection(get((yyvsp[(2) - (2)].sel)), get((yyvsp[(1) - (2)].sel)), scanner));
@@ -1939,13 +1914,13 @@ yyreduce:
 
   case 4:
 /* Line 1787 of yacc.c  */
-#line 215 "parser.y"
+#line 209 "parser.y"
     { (yyval.sel) = (yyvsp[(1) - (2)].sel); }
     break;
 
   case 5:
 /* Line 1787 of yacc.c  */
-#line 217 "parser.y"
+#line 211 "parser.y"
     {
                  BEGIN_ACTION;
                  _gmx_selparser_error(scanner, "invalid selection '%s'",
@@ -1967,10 +1942,9 @@ yyreduce:
 
   case 6:
 /* Line 1787 of yacc.c  */
-#line 238 "parser.y"
+#line 232 "parser.y"
     {
                  BEGIN_ACTION;
-                 _gmx_sel_handle_empty_cmd(scanner);
                  set_empty((yyval.sel));
                  END_ACTION;
              }
@@ -1978,17 +1952,7 @@ yyreduce:
 
   case 7:
 /* Line 1787 of yacc.c  */
-#line 245 "parser.y"
-    {
-                 BEGIN_ACTION;
-                 set_empty((yyval.sel));
-                 END_ACTION;
-             }
-    break;
-
-  case 8:
-/* Line 1787 of yacc.c  */
-#line 251 "parser.y"
+#line 238 "parser.y"
     {
                  BEGIN_ACTION;
                  SelectionTreeElementPointer s
@@ -2001,9 +1965,9 @@ yyreduce:
              }
     break;
 
-  case 9:
+  case 8:
 /* Line 1787 of yacc.c  */
-#line 262 "parser.y"
+#line 249 "parser.y"
     {
                  BEGIN_ACTION;
                  scoped_ptr_sfree nameGuard((yyvsp[(1) - (1)].str));
@@ -2017,9 +1981,9 @@ yyreduce:
              }
     break;
 
-  case 10:
+  case 9:
 /* Line 1787 of yacc.c  */
-#line 274 "parser.y"
+#line 261 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.sel), _gmx_sel_init_selection(NULL, get((yyvsp[(1) - (1)].sel)), scanner));
@@ -2027,9 +1991,9 @@ yyreduce:
              }
     break;
 
-  case 11:
+  case 10:
 /* Line 1787 of yacc.c  */
-#line 280 "parser.y"
+#line 267 "parser.y"
     {
                  BEGIN_ACTION;
                  scoped_ptr_sfree nameGuard((yyvsp[(1) - (2)].str));
@@ -2038,9 +2002,9 @@ yyreduce:
              }
     break;
 
-  case 12:
+  case 11:
 /* Line 1787 of yacc.c  */
-#line 287 "parser.y"
+#line 274 "parser.y"
     {
                  BEGIN_ACTION;
                  scoped_ptr_sfree nameGuard((yyvsp[(1) - (3)].str));
@@ -2049,9 +2013,9 @@ yyreduce:
              }
     break;
 
-  case 13:
+  case 12:
 /* Line 1787 of yacc.c  */
-#line 294 "parser.y"
+#line 281 "parser.y"
     {
                  BEGIN_ACTION;
                  scoped_ptr_sfree nameGuard((yyvsp[(1) - (3)].str));
@@ -2060,9 +2024,9 @@ yyreduce:
              }
     break;
 
-  case 14:
+  case 13:
 /* Line 1787 of yacc.c  */
-#line 301 "parser.y"
+#line 288 "parser.y"
     {
                  BEGIN_ACTION;
                  scoped_ptr_sfree nameGuard((yyvsp[(1) - (3)].str));
@@ -2071,47 +2035,15 @@ yyreduce:
              }
     break;
 
-  case 15:
-/* Line 1787 of yacc.c  */
-#line 312 "parser.y"
-    {
-                 BEGIN_ACTION;
-                 _gmx_sel_handle_help_cmd(get((yyvsp[(2) - (2)].vlist)), scanner);
-                 END_ACTION;
-             }
-    break;
-
-  case 16:
-/* Line 1787 of yacc.c  */
-#line 320 "parser.y"
-    {
-                 BEGIN_ACTION;
-                 set((yyval.vlist), SelectionParserValue::createList());
-                 END_ACTION;
-             }
-    break;
-
-  case 17:
-/* Line 1787 of yacc.c  */
-#line 326 "parser.y"
-    {
-                 BEGIN_ACTION;
-                 SelectionParserValueListPointer list(get((yyvsp[(1) - (2)].vlist)));
-                 list->push_back(SelectionParserValue::createString((yyvsp[(2) - (2)].str)));
-                 set((yyval.vlist), move(list));
-                 END_ACTION;
-             }
-    break;
-
-  case 18:
+  case 14:
 /* Line 1787 of yacc.c  */
-#line 336 "parser.y"
+#line 297 "parser.y"
     { (yyval.sel) = (yyvsp[(1) - (1)].sel); }
     break;
 
-  case 19:
+  case 15:
 /* Line 1787 of yacc.c  */
-#line 338 "parser.y"
+#line 299 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.sel), _gmx_sel_init_position(get((yyvsp[(1) - (1)].sel)), NULL, scanner));
@@ -2120,15 +2052,15 @@ yyreduce:
              }
     break;
 
-  case 20:
+  case 16:
 /* Line 1787 of yacc.c  */
-#line 344 "parser.y"
+#line 305 "parser.y"
     { (yyval.sel) = (yyvsp[(2) - (3)].sel); }
     break;
 
-  case 21:
+  case 17:
 /* Line 1787 of yacc.c  */
-#line 346 "parser.y"
+#line 307 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.sel), _gmx_sel_init_modifier((yyvsp[(2) - (3)].meth), get((yyvsp[(3) - (3)].plist)), get((yyvsp[(1) - (3)].sel)), scanner));
@@ -2137,57 +2069,57 @@ yyreduce:
              }
     break;
 
-  case 22:
+  case 18:
 /* Line 1787 of yacc.c  */
-#line 359 "parser.y"
+#line 320 "parser.y"
     { (yyval.i) = (yyvsp[(1) - (1)].i); }
     break;
 
-  case 23:
+  case 19:
 /* Line 1787 of yacc.c  */
-#line 360 "parser.y"
+#line 321 "parser.y"
     { (yyval.i) = -(yyvsp[(2) - (2)].i); }
     break;
 
-  case 24:
+  case 20:
 /* Line 1787 of yacc.c  */
-#line 364 "parser.y"
+#line 325 "parser.y"
     { (yyval.r) = (yyvsp[(1) - (1)].r); }
     break;
 
-  case 25:
+  case 21:
 /* Line 1787 of yacc.c  */
-#line 365 "parser.y"
+#line 326 "parser.y"
     { (yyval.r) = -(yyvsp[(2) - (2)].r); }
     break;
 
-  case 26:
+  case 22:
 /* Line 1787 of yacc.c  */
-#line 368 "parser.y"
+#line 329 "parser.y"
     { (yyval.r) = (yyvsp[(1) - (1)].i); }
     break;
 
-  case 27:
+  case 23:
 /* Line 1787 of yacc.c  */
-#line 369 "parser.y"
+#line 330 "parser.y"
     { (yyval.r) = (yyvsp[(1) - (1)].r); }
     break;
 
-  case 28:
+  case 24:
 /* Line 1787 of yacc.c  */
-#line 372 "parser.y"
+#line 333 "parser.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
-  case 29:
+  case 25:
 /* Line 1787 of yacc.c  */
-#line 373 "parser.y"
+#line 334 "parser.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str); }
     break;
 
-  case 30:
+  case 26:
 /* Line 1787 of yacc.c  */
-#line 382 "parser.y"
+#line 343 "parser.y"
     {
                  BEGIN_ACTION;
                  SelectionTreeElementPointer arg(get((yyvsp[(2) - (2)].sel)));
@@ -2200,9 +2132,9 @@ yyreduce:
              }
     break;
 
-  case 31:
+  case 27:
 /* Line 1787 of yacc.c  */
-#line 393 "parser.y"
+#line 354 "parser.y"
     {
                  BEGIN_ACTION;
                  SelectionTreeElementPointer arg1(get((yyvsp[(1) - (3)].sel))), arg2(get((yyvsp[(3) - (3)].sel)));
@@ -2215,9 +2147,9 @@ yyreduce:
              }
     break;
 
-  case 32:
+  case 28:
 /* Line 1787 of yacc.c  */
-#line 404 "parser.y"
+#line 365 "parser.y"
     {
                  BEGIN_ACTION;
                  SelectionTreeElementPointer arg1(get((yyvsp[(1) - (3)].sel))), arg2(get((yyvsp[(3) - (3)].sel)));
@@ -2230,15 +2162,15 @@ yyreduce:
              }
     break;
 
-  case 33:
+  case 29:
 /* Line 1787 of yacc.c  */
-#line 414 "parser.y"
+#line 375 "parser.y"
     { (yyval.sel) = (yyvsp[(2) - (3)].sel); }
     break;
 
-  case 34:
+  case 30:
 /* Line 1787 of yacc.c  */
-#line 419 "parser.y"
+#line 380 "parser.y"
     {
                  BEGIN_ACTION;
                  scoped_ptr_sfree opGuard((yyvsp[(2) - (3)].str));
@@ -2248,9 +2180,9 @@ yyreduce:
              }
     break;
 
-  case 35:
+  case 31:
 /* Line 1787 of yacc.c  */
-#line 430 "parser.y"
+#line 391 "parser.y"
     {
                  BEGIN_ACTION;
                  scoped_ptr_sfree nameGuard((yyvsp[(2) - (2)].str));
@@ -2259,9 +2191,9 @@ yyreduce:
              }
     break;
 
-  case 36:
+  case 32:
 /* Line 1787 of yacc.c  */
-#line 437 "parser.y"
+#line 398 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.sel), _gmx_sel_init_group_by_id((yyvsp[(2) - (2)].i), scanner));
@@ -2269,39 +2201,39 @@ yyreduce:
              }
     break;
 
-  case 37:
+  case 33:
 /* Line 1787 of yacc.c  */
-#line 445 "parser.y"
+#line 406 "parser.y"
     { (yyval.str) = NULL; }
     break;
 
-  case 38:
+  case 34:
 /* Line 1787 of yacc.c  */
-#line 446 "parser.y"
+#line 407 "parser.y"
     { (yyval.str) = (yyvsp[(1) - (1)].str);   }
     break;
 
-  case 39:
+  case 35:
 /* Line 1787 of yacc.c  */
-#line 451 "parser.y"
+#line 412 "parser.y"
     { (yyval.smt) = gmx::eStringMatchType_RegularExpression; }
     break;
 
-  case 40:
+  case 36:
 /* Line 1787 of yacc.c  */
-#line 452 "parser.y"
+#line 413 "parser.y"
     { (yyval.smt) = gmx::eStringMatchType_Wildcard; }
     break;
 
-  case 41:
+  case 37:
 /* Line 1787 of yacc.c  */
-#line 453 "parser.y"
+#line 414 "parser.y"
     { (yyval.smt) = gmx::eStringMatchType_Exact; }
     break;
 
-  case 42:
+  case 38:
 /* Line 1787 of yacc.c  */
-#line 458 "parser.y"
+#line 419 "parser.y"
     {
                  BEGIN_ACTION;
                  scoped_ptr_sfree posmodGuard((yyvsp[(1) - (2)].str));
@@ -2311,9 +2243,9 @@ yyreduce:
              }
     break;
 
-  case 43:
+  case 39:
 /* Line 1787 of yacc.c  */
-#line 466 "parser.y"
+#line 427 "parser.y"
     {
                  BEGIN_ACTION;
                  scoped_ptr_sfree posmodGuard((yyvsp[(1) - (3)].str));
@@ -2323,9 +2255,9 @@ yyreduce:
              }
     break;
 
-  case 44:
+  case 40:
 /* Line 1787 of yacc.c  */
-#line 474 "parser.y"
+#line 435 "parser.y"
     {
                  BEGIN_ACTION;
                  scoped_ptr_sfree posmodGuard((yyvsp[(1) - (4)].str));
@@ -2335,9 +2267,9 @@ yyreduce:
              }
     break;
 
-  case 45:
+  case 41:
 /* Line 1787 of yacc.c  */
-#line 482 "parser.y"
+#line 443 "parser.y"
     {
                  BEGIN_ACTION;
                  scoped_ptr_sfree posmodGuard((yyvsp[(1) - (3)].str));
@@ -2347,9 +2279,9 @@ yyreduce:
              }
     break;
 
-  case 46:
+  case 42:
 /* Line 1787 of yacc.c  */
-#line 493 "parser.y"
+#line 454 "parser.y"
     {
                  BEGIN_ACTION;
                  scoped_ptr_sfree posmodGuard((yyvsp[(1) - (3)].str));
@@ -2359,9 +2291,9 @@ yyreduce:
              }
     break;
 
-  case 47:
+  case 43:
 /* Line 1787 of yacc.c  */
-#line 508 "parser.y"
+#line 469 "parser.y"
     {
                  BEGIN_ACTION;
                  SelectionTreeElementPointer sel(
@@ -2374,9 +2306,9 @@ yyreduce:
              }
     break;
 
-  case 48:
+  case 44:
 /* Line 1787 of yacc.c  */
-#line 519 "parser.y"
+#line 480 "parser.y"
     {
                  BEGIN_ACTION;
                  SelectionTreeElementPointer sel(
@@ -2389,9 +2321,9 @@ yyreduce:
              }
     break;
 
-  case 49:
+  case 45:
 /* Line 1787 of yacc.c  */
-#line 533 "parser.y"
+#line 494 "parser.y"
     {
                  BEGIN_ACTION;
                  scoped_ptr_sfree posmodGuard((yyvsp[(1) - (2)].str));
@@ -2401,9 +2333,9 @@ yyreduce:
              }
     break;
 
-  case 50:
+  case 46:
 /* Line 1787 of yacc.c  */
-#line 541 "parser.y"
+#line 502 "parser.y"
     {
                  BEGIN_ACTION;
                  scoped_ptr_sfree posmodGuard((yyvsp[(1) - (3)].str));
@@ -2413,9 +2345,9 @@ yyreduce:
              }
     break;
 
-  case 51:
+  case 47:
 /* Line 1787 of yacc.c  */
-#line 552 "parser.y"
+#line 513 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.sel), _gmx_sel_init_arithmetic(get((yyvsp[(1) - (3)].sel)), get((yyvsp[(3) - (3)].sel)), '+', scanner));
@@ -2423,9 +2355,9 @@ yyreduce:
              }
     break;
 
-  case 52:
+  case 48:
 /* Line 1787 of yacc.c  */
-#line 558 "parser.y"
+#line 519 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.sel), _gmx_sel_init_arithmetic(get((yyvsp[(1) - (3)].sel)), get((yyvsp[(3) - (3)].sel)), '-', scanner));
@@ -2433,9 +2365,9 @@ yyreduce:
              }
     break;
 
-  case 53:
+  case 49:
 /* Line 1787 of yacc.c  */
-#line 564 "parser.y"
+#line 525 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.sel), _gmx_sel_init_arithmetic(get((yyvsp[(1) - (3)].sel)), get((yyvsp[(3) - (3)].sel)), '*', scanner));
@@ -2443,9 +2375,9 @@ yyreduce:
              }
     break;
 
-  case 54:
+  case 50:
 /* Line 1787 of yacc.c  */
-#line 570 "parser.y"
+#line 531 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.sel), _gmx_sel_init_arithmetic(get((yyvsp[(1) - (3)].sel)), get((yyvsp[(3) - (3)].sel)), '/', scanner));
@@ -2453,9 +2385,9 @@ yyreduce:
              }
     break;
 
-  case 55:
+  case 51:
 /* Line 1787 of yacc.c  */
-#line 576 "parser.y"
+#line 537 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.sel), _gmx_sel_init_arithmetic(get((yyvsp[(2) - (2)].sel)), SelectionTreeElementPointer(), '-', scanner));
@@ -2463,9 +2395,9 @@ yyreduce:
              }
     break;
 
-  case 56:
+  case 52:
 /* Line 1787 of yacc.c  */
-#line 582 "parser.y"
+#line 543 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.sel), _gmx_sel_init_arithmetic(get((yyvsp[(1) - (3)].sel)), get((yyvsp[(3) - (3)].sel)), '^', scanner));
@@ -2473,15 +2405,15 @@ yyreduce:
              }
     break;
 
-  case 57:
+  case 53:
 /* Line 1787 of yacc.c  */
-#line 587 "parser.y"
+#line 548 "parser.y"
     { (yyval.sel) = (yyvsp[(2) - (3)].sel); }
     break;
 
-  case 58:
+  case 54:
 /* Line 1787 of yacc.c  */
-#line 595 "parser.y"
+#line 556 "parser.y"
     {
                  BEGIN_ACTION;
                  SelectionTreeElementPointer sel(
@@ -2494,9 +2426,9 @@ yyreduce:
              }
     break;
 
-  case 59:
+  case 55:
 /* Line 1787 of yacc.c  */
-#line 606 "parser.y"
+#line 567 "parser.y"
     {
                  BEGIN_ACTION;
                  scoped_ptr_sfree posmodGuard((yyvsp[(1) - (2)].str));
@@ -2506,9 +2438,9 @@ yyreduce:
              }
     break;
 
-  case 60:
+  case 56:
 /* Line 1787 of yacc.c  */
-#line 621 "parser.y"
+#line 582 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.sel), _gmx_sel_init_const_position((yyvsp[(2) - (7)].r), (yyvsp[(4) - (7)].r), (yyvsp[(6) - (7)].r)));
@@ -2516,15 +2448,15 @@ yyreduce:
              }
     break;
 
-  case 61:
+  case 57:
 /* Line 1787 of yacc.c  */
-#line 629 "parser.y"
+#line 590 "parser.y"
     { (yyval.sel) = (yyvsp[(2) - (3)].sel); }
     break;
 
-  case 62:
+  case 58:
 /* Line 1787 of yacc.c  */
-#line 634 "parser.y"
+#line 595 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.sel), _gmx_sel_init_method((yyvsp[(1) - (2)].meth), get((yyvsp[(2) - (2)].plist)), NULL, scanner));
@@ -2533,9 +2465,9 @@ yyreduce:
              }
     break;
 
-  case 63:
+  case 59:
 /* Line 1787 of yacc.c  */
-#line 644 "parser.y"
+#line 605 "parser.y"
     {
                  BEGIN_ACTION;
                  scoped_ptr_sfree keywordGuard((yyvsp[(1) - (3)].str));
@@ -2545,9 +2477,9 @@ yyreduce:
              }
     break;
 
-  case 64:
+  case 60:
 /* Line 1787 of yacc.c  */
-#line 658 "parser.y"
+#line 619 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.sel), _gmx_sel_init_variable_ref(get((yyvsp[(1) - (1)].sel))));
@@ -2555,9 +2487,9 @@ yyreduce:
              }
     break;
 
-  case 65:
+  case 61:
 /* Line 1787 of yacc.c  */
-#line 666 "parser.y"
+#line 627 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.sel), _gmx_sel_init_variable_ref(get((yyvsp[(1) - (1)].sel))));
@@ -2565,9 +2497,9 @@ yyreduce:
              }
     break;
 
-  case 66:
+  case 62:
 /* Line 1787 of yacc.c  */
-#line 674 "parser.y"
+#line 635 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.sel), _gmx_sel_init_variable_ref(get((yyvsp[(1) - (1)].sel))));
@@ -2575,21 +2507,21 @@ yyreduce:
              }
     break;
 
-  case 67:
+  case 63:
 /* Line 1787 of yacc.c  */
-#line 687 "parser.y"
+#line 648 "parser.y"
     { (yyval.plist) = (yyvsp[(1) - (1)].plist); }
     break;
 
-  case 68:
+  case 64:
 /* Line 1787 of yacc.c  */
-#line 689 "parser.y"
+#line 650 "parser.y"
     { (yyval.plist) = (yyvsp[(1) - (2)].plist); }
     break;
 
-  case 69:
+  case 65:
 /* Line 1787 of yacc.c  */
-#line 694 "parser.y"
+#line 655 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.plist), SelectionParserParameter::createList());
@@ -2597,9 +2529,9 @@ yyreduce:
              }
     break;
 
-  case 70:
+  case 66:
 /* Line 1787 of yacc.c  */
-#line 700 "parser.y"
+#line 661 "parser.y"
     {
                  BEGIN_ACTION;
                  SelectionParserParameterListPointer list(get((yyvsp[(1) - (2)].plist)));
@@ -2609,9 +2541,9 @@ yyreduce:
              }
     break;
 
-  case 71:
+  case 67:
 /* Line 1787 of yacc.c  */
-#line 711 "parser.y"
+#line 672 "parser.y"
     {
                  BEGIN_ACTION;
                  scoped_ptr_sfree nameGuard((yyvsp[(1) - (2)].str));
@@ -2620,21 +2552,21 @@ yyreduce:
              }
     break;
 
-  case 72:
+  case 68:
 /* Line 1787 of yacc.c  */
-#line 719 "parser.y"
+#line 680 "parser.y"
     { (yyval.vlist) = (yyvsp[(1) - (1)].vlist);   }
     break;
 
-  case 73:
+  case 69:
 /* Line 1787 of yacc.c  */
-#line 720 "parser.y"
+#line 681 "parser.y"
     { (yyval.vlist) = (yyvsp[(2) - (3)].vlist);   }
     break;
 
-  case 74:
+  case 70:
 /* Line 1787 of yacc.c  */
-#line 725 "parser.y"
+#line 686 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.vlist), SelectionParserValue::createList());
@@ -2642,9 +2574,9 @@ yyreduce:
              }
     break;
 
-  case 75:
+  case 71:
 /* Line 1787 of yacc.c  */
-#line 731 "parser.y"
+#line 692 "parser.y"
     {
                  BEGIN_ACTION;
                  SelectionParserValueListPointer list(get((yyvsp[(1) - (2)].vlist)));
@@ -2654,9 +2586,9 @@ yyreduce:
              }
     break;
 
-  case 76:
+  case 72:
 /* Line 1787 of yacc.c  */
-#line 739 "parser.y"
+#line 700 "parser.y"
     {
                  BEGIN_ACTION;
                  SelectionParserValueListPointer list(get((yyvsp[(1) - (3)].vlist)));
@@ -2666,21 +2598,21 @@ yyreduce:
              }
     break;
 
-  case 77:
+  case 73:
 /* Line 1787 of yacc.c  */
-#line 749 "parser.y"
+#line 710 "parser.y"
     { (yyval.vlist) = (yyvsp[(1) - (1)].vlist); }
     break;
 
-  case 78:
+  case 74:
 /* Line 1787 of yacc.c  */
-#line 750 "parser.y"
+#line 711 "parser.y"
     { (yyval.vlist) = (yyvsp[(2) - (3)].vlist); }
     break;
 
-  case 79:
+  case 75:
 /* Line 1787 of yacc.c  */
-#line 755 "parser.y"
+#line 716 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.vlist), SelectionParserValue::createList(get((yyvsp[(1) - (1)].val))));
@@ -2688,9 +2620,9 @@ yyreduce:
              }
     break;
 
-  case 80:
+  case 76:
 /* Line 1787 of yacc.c  */
-#line 761 "parser.y"
+#line 722 "parser.y"
     {
                  BEGIN_ACTION;
                  SelectionParserValueListPointer list(get((yyvsp[(1) - (2)].vlist)));
@@ -2700,9 +2632,9 @@ yyreduce:
              }
     break;
 
-  case 81:
+  case 77:
 /* Line 1787 of yacc.c  */
-#line 769 "parser.y"
+#line 730 "parser.y"
     {
                  BEGIN_ACTION;
                  SelectionParserValueListPointer list(get((yyvsp[(1) - (3)].vlist)));
@@ -2712,9 +2644,9 @@ yyreduce:
              }
     break;
 
-  case 82:
+  case 78:
 /* Line 1787 of yacc.c  */
-#line 779 "parser.y"
+#line 740 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.val), SelectionParserValue::createExpr(get((yyvsp[(1) - (1)].sel))));
@@ -2722,9 +2654,9 @@ yyreduce:
              }
     break;
 
-  case 83:
+  case 79:
 /* Line 1787 of yacc.c  */
-#line 785 "parser.y"
+#line 746 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.val), SelectionParserValue::createExpr(get((yyvsp[(1) - (1)].sel))));
@@ -2732,9 +2664,9 @@ yyreduce:
              }
     break;
 
-  case 84:
+  case 80:
 /* Line 1787 of yacc.c  */
-#line 791 "parser.y"
+#line 752 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.val), SelectionParserValue::createExpr(get((yyvsp[(1) - (1)].sel))));
@@ -2742,9 +2674,9 @@ yyreduce:
              }
     break;
 
-  case 85:
+  case 81:
 /* Line 1787 of yacc.c  */
-#line 797 "parser.y"
+#line 758 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.val), SelectionParserValue::createExpr(get((yyvsp[(1) - (1)].sel))));
@@ -2752,15 +2684,15 @@ yyreduce:
              }
     break;
 
-  case 86:
+  case 82:
 /* Line 1787 of yacc.c  */
-#line 802 "parser.y"
+#line 763 "parser.y"
     { (yyval.val) = (yyvsp[(1) - (1)].val); }
     break;
 
-  case 87:
+  case 83:
 /* Line 1787 of yacc.c  */
-#line 807 "parser.y"
+#line 768 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.val), SelectionParserValue::createInteger((yyvsp[(1) - (1)].i)));
@@ -2768,9 +2700,9 @@ yyreduce:
              }
     break;
 
-  case 88:
+  case 84:
 /* Line 1787 of yacc.c  */
-#line 813 "parser.y"
+#line 774 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.val), SelectionParserValue::createReal((yyvsp[(1) - (1)].r)));
@@ -2778,9 +2710,9 @@ yyreduce:
              }
     break;
 
-  case 89:
+  case 85:
 /* Line 1787 of yacc.c  */
-#line 819 "parser.y"
+#line 780 "parser.y"
     {
                  BEGIN_ACTION;
                  scoped_ptr_sfree stringGuard((yyvsp[(1) - (1)].str));
@@ -2789,15 +2721,15 @@ yyreduce:
              }
     break;
 
-  case 90:
+  case 86:
 /* Line 1787 of yacc.c  */
-#line 825 "parser.y"
+#line 786 "parser.y"
     { (yyval.val) = (yyvsp[(1) - (1)].val); }
     break;
 
-  case 91:
+  case 87:
 /* Line 1787 of yacc.c  */
-#line 830 "parser.y"
+#line 791 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.val), SelectionParserValue::createIntegerRange((yyvsp[(1) - (3)].i), (yyvsp[(3) - (3)].i)));
@@ -2805,9 +2737,9 @@ yyreduce:
              }
     break;
 
-  case 92:
+  case 88:
 /* Line 1787 of yacc.c  */
-#line 836 "parser.y"
+#line 797 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.val), SelectionParserValue::createRealRange((yyvsp[(1) - (3)].i), (yyvsp[(3) - (3)].r)));
@@ -2815,9 +2747,9 @@ yyreduce:
              }
     break;
 
-  case 93:
+  case 89:
 /* Line 1787 of yacc.c  */
-#line 842 "parser.y"
+#line 803 "parser.y"
     {
                  BEGIN_ACTION;
                  set((yyval.val), SelectionParserValue::createRealRange((yyvsp[(1) - (3)].r), (yyvsp[(3) - (3)].r)));
@@ -2827,7 +2759,7 @@ yyreduce:
 
 
 /* Line 1787 of yacc.c  */
-#line 2831 "parser.cpp"
+#line 2763 "parser.cpp"
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
index aca40fef2bbee062d8b04ea3b4203047633241f1..5ccdff7781200a5b78195020a1e16da7edf46f52 100644 (file)
@@ -46,7 +46,7 @@ extern int _gmx_sel_yydebug;
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2009,2010,2011,2012,2013, by the GROMACS development team, led by
+ * Copyright (c) 2009,2010,2011,2012,2013,2014, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -95,38 +95,36 @@ extern int _gmx_sel_yydebug;
       know about them.  */
    enum yytokentype {
      INVALID = 258,
-     HELP = 259,
-     HELP_TOPIC = 260,
-     TOK_INT = 261,
-     TOK_REAL = 262,
-     STR = 263,
-     IDENTIFIER = 264,
-     CMD_SEP = 265,
-     GROUP = 266,
-     TO = 267,
-     VARIABLE_NUMERIC = 268,
-     VARIABLE_GROUP = 269,
-     VARIABLE_POS = 270,
-     KEYWORD_NUMERIC = 271,
-     KEYWORD_STR = 272,
-     KEYWORD_POS = 273,
-     KEYWORD_GROUP = 274,
-     METHOD_NUMERIC = 275,
-     METHOD_GROUP = 276,
-     METHOD_POS = 277,
-     MODIFIER = 278,
-     EMPTY_POSMOD = 279,
-     PARAM = 280,
-     END_OF_METHOD = 281,
-     OF = 282,
-     CMP_OP = 283,
-     PARAM_REDUCT = 284,
-     XOR = 285,
-     OR = 286,
-     AND = 287,
-     NOT = 288,
-     UNARY_NEG = 289,
-     NUM_REDUCT = 290
+     TOK_INT = 259,
+     TOK_REAL = 260,
+     STR = 261,
+     IDENTIFIER = 262,
+     CMD_SEP = 263,
+     GROUP = 264,
+     TO = 265,
+     VARIABLE_NUMERIC = 266,
+     VARIABLE_GROUP = 267,
+     VARIABLE_POS = 268,
+     KEYWORD_NUMERIC = 269,
+     KEYWORD_STR = 270,
+     KEYWORD_POS = 271,
+     KEYWORD_GROUP = 272,
+     METHOD_NUMERIC = 273,
+     METHOD_GROUP = 274,
+     METHOD_POS = 275,
+     MODIFIER = 276,
+     EMPTY_POSMOD = 277,
+     PARAM = 278,
+     END_OF_METHOD = 279,
+     OF = 280,
+     CMP_OP = 281,
+     PARAM_REDUCT = 282,
+     XOR = 283,
+     OR = 284,
+     AND = 285,
+     NOT = 286,
+     UNARY_NEG = 287,
+     NUM_REDUCT = 288
    };
 #endif
 
@@ -152,7 +150,7 @@ typedef union YYSTYPE
 
 
 /* Line 2049 of yacc.c  */
-#line 156 "parser.h"
+#line 154 "parser.h"
 } YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
index 9fc8223203e138a62fee49e923d1d978923d5155..0f2e913351884839b95d85e8fdd288979611da34 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2009,2010,2011,2012,2013, by the GROMACS development team, led by
+ * Copyright (c) 2009,2010,2011,2012,2013,2014, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -93,10 +93,6 @@ using gmx::SelectionTreeElementPointer;
 /* Invalid token to report lexer errors */
 %token INVALID
 
-/* Tokens for help requests */
-%token         HELP
-%token <str>   HELP_TOPIC
-
 /* Simple input tokens */
 %token <i>     TOK_INT
 %token <r>     TOK_REAL
@@ -173,16 +169,14 @@ using gmx::SelectionTreeElementPointer;
 %type <param> method_param
 %type <vlist> value_list value_list_contents basic_value_list basic_value_list_contents
 %type <val>   value_item value_item_range basic_value_item
-%type <vlist> help_topic
 
-%destructor { free($$);        } HELP_TOPIC STR IDENTIFIER KEYWORD_POS CMP_OP string
+%destructor { free($$);        } STR IDENTIFIER KEYWORD_POS CMP_OP string
 %destructor { if($$) free($$); } PARAM pos_mod
 %destructor { delete $$;       } commands command cmd_plain selection
 %destructor { delete $$;       } sel_expr num_expr str_expr pos_expr
 %destructor { delete $$;       } method_params method_param_list method_param
 %destructor { delete $$;       } value_list value_list_contents basic_value_list basic_value_list_contents
 %destructor { delete $$;       } value_item value_item_range basic_value_item
-%destructor { delete $$;       } help_topic
 
 %expect 35
 %debug
@@ -235,13 +229,6 @@ command:     cmd_plain CMD_SEP  { $$ = $1; }
 
 /* Commands can be selections or variable assignments */
 cmd_plain:   /* empty */
-             {
-                 BEGIN_ACTION;
-                 _gmx_sel_handle_empty_cmd(scanner);
-                 set_empty($$);
-                 END_ACTION;
-             }
-           | help_request
              {
                  BEGIN_ACTION;
                  set_empty($$);
@@ -306,32 +293,6 @@ cmd_plain:   /* empty */
              }
 ;
 
-/* Help requests */
-help_request:
-             HELP help_topic
-             {
-                 BEGIN_ACTION;
-                 _gmx_sel_handle_help_cmd(get($2), scanner);
-                 END_ACTION;
-             }
-;
-
-help_topic:  /* empty */
-             {
-                 BEGIN_ACTION;
-                 set($$, SelectionParserValue::createList());
-                 END_ACTION;
-             }
-           | help_topic HELP_TOPIC
-             {
-                 BEGIN_ACTION;
-                 SelectionParserValueListPointer list(get($1));
-                 list->push_back(SelectionParserValue::createString($2));
-                 set($$, move(list));
-                 END_ACTION;
-             }
-;
-
 /* Selection is made of an expression and zero or more modifiers */
 selection:   pos_expr           { $$ = $1; }
            | sel_expr
index 83b040cfdf246fdf0fa0b8f4666559e8909c5a40..44b2cc5af5f5b7c804e6a72fa20c6aab4209b1c2 100644 (file)
 #include "gromacs/legacyheaders/smalloc.h"
 #include "gromacs/legacyheaders/string2.h"
 
-#include "gromacs/onlinehelp/helpmanager.h"
-#include "gromacs/onlinehelp/helpwritercontext.h"
 #include "gromacs/selection/poscalc.h"
 #include "gromacs/selection/selection.h"
 #include "gromacs/selection/selmethod.h"
 #include "parsetree.h"
 #include "selectioncollection-impl.h"
 #include "selelem.h"
-#include "selhelp.h"
 #include "symrec.h"
 
 #include "scanner.h"
@@ -1163,47 +1160,3 @@ _gmx_sel_parser_should_finish(yyscan_t scanner)
     gmx_ana_selcollection_t *sc = _gmx_sel_lexer_selcollection(scanner);
     return (int)sc->sel.size() == _gmx_sel_lexer_exp_selcount(scanner);
 }
-
-void
-_gmx_sel_handle_empty_cmd(yyscan_t /*scanner*/)
-{
-    // This is now handled outside the actual parser, in
-    // selectioncollection.cpp.  This stub will be removed as part of later
-    // refactoring related to the selection parser.
-}
-
-/*!
- * \param[in] topic   Topic for which help was requested, or NULL for general
- *                    help.
- * \param[in] scanner Scanner data structure.
- *
- * \p topic is freed by this function.
- */
-void
-_gmx_sel_handle_help_cmd(const gmx::SelectionParserValueListPointer &topic,
-                         yyscan_t                                    scanner)
-{
-    gmx_ana_selcollection_t *sc = _gmx_sel_lexer_selcollection(scanner);
-
-    if (sc->rootHelp.get() == NULL)
-    {
-        sc->rootHelp = gmx::createSelectionHelpTopic();
-    }
-    gmx::HelpWriterContext context(&gmx::File::standardError(),
-                                   gmx::eHelpOutputFormat_Console);
-    gmx::HelpManager       manager(*sc->rootHelp, context);
-    try
-    {
-        SelectionParserValueList::const_iterator value;
-        for (value = topic->begin(); value != topic->end(); ++value)
-        {
-            manager.enterTopic(value->stringValue());
-        }
-    }
-    catch (const gmx::InvalidInputError &ex)
-    {
-        fprintf(stderr, "%s\n", ex.what());
-        return;
-    }
-    manager.writeCurrentTopic();
-}
index 01b85dad061ee179fa0b5d2ef16ede208d219017..142fe7e1a6f4e23a3caebb03419ead3bae4cf995 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2009,2010,2011,2012,2013, by the GROMACS development team, led by
+ * Copyright (c) 2009,2010,2011,2012,2013,2014, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -480,14 +480,6 @@ _gmx_sel_append_selection(const gmx::SelectionTreeElementPointer &sel,
 bool
 _gmx_sel_parser_should_finish(void *scanner);
 
-/** Handle empty commands. */
-void
-_gmx_sel_handle_empty_cmd(void *scanner);
-/** Process help commands. */
-void
-_gmx_sel_handle_help_cmd(const gmx::SelectionParserValueListPointer &topic,
-                         void                                       *scanner);
-
 /* In params.c */
 /** Initializes an array of parameters based on input from the selection parser. */
 bool
index bd42f4c9f6469dfc74ffd809d9c1bde9a172e408..96c483316bef1ac148f2dc4e230230d64e8799e6 100644 (file)
@@ -2,7 +2,7 @@
 #line 50 "scanner.l"
 // Required before flex definitions, since it includes <stdint.h>.
 // Otherwise, compilers not strictly C99 get macro redefinition errors,
-// since flex defines INT64_MAX etc. in such cases.
+// since flex defines INT32_MAX etc. in such cases.
 #include "gromacs/legacyheaders/types/simple.h"
 
 
@@ -355,8 +355,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
        *yy_cp = '\0'; \
        yyg->yy_c_buf_p = yy_cp;
 
-#define YY_NUM_RULES 26
-#define YY_END_OF_BUFFER 27
+#define YY_NUM_RULES 21
+#define YY_END_OF_BUFFER 22
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -364,17 +364,16 @@ struct yy_trans_info
        flex_int32_t yy_verify;
        flex_int32_t yy_nxt;
        };
-static yyconst flex_int16_t yy_accept[89] =
+static yyconst flex_int16_t yy_accept[76] =
     {   0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-       27,   25,   23,    6,   20,   25,    1,   25,   25,    2,
-        6,   21,   25,   22,   25,   24,   22,   22,   22,   22,
-       22,   22,   22,   25,   22,   22,   22,   22,   11,    8,
-       10,   10,    9,   23,   21,    0,    4,    0,    1,   17,
-        3,    3,    2,   24,   24,   22,    5,   22,   22,   22,
-       22,   18,   15,   22,   18,   16,   13,   22,   12,   22,
-        8,    9,    0,    0,    3,   17,   22,   22,   20,   19,
-       13,    0,    3,    3,   22,    7,   14,    0
+        0,    0,    0,    0,    0,    0,    0,    0,   22,   20,
+       18,    6,   15,   20,    1,   20,   20,    2,    6,   16,
+       20,   17,   20,   19,   17,   17,   17,   17,   17,   17,
+       20,   17,   17,   17,   17,   18,   16,    0,    4,    0,
+        1,   12,    3,    3,    2,   19,   19,   17,    5,   17,
+       17,   17,   13,   10,   17,   13,   11,    8,   17,    7,
+       17,    0,    0,    3,   12,   17,   15,   14,    8,    0,
+        3,    3,   17,    9,    0
     } ;
 
 static yyconst flex_int32_t yy_ec[256] =
@@ -390,9 +389,9 @@ static yyconst flex_int32_t yy_ec[256] =
        14,   14,   14,   14,   14,   14,   14,   14,   14,   14,
         1,   16,    1,    1,   17,    1,   18,   14,   14,   19,
 
-       20,   21,   22,   23,   14,   14,   14,   24,   14,   25,
-       26,   27,   14,   28,   29,   30,   31,   14,   14,   32,
-       33,   14,    1,   34,    1,    1,    1,    1,    1,    1,
+       20,   21,   22,   14,   14,   14,   14,   14,   14,   23,
+       24,   25,   14,   26,   27,   28,   29,   14,   14,   30,
+       31,   14,    1,   32,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -409,90 +408,76 @@ static yyconst flex_int32_t yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
-static yyconst flex_int32_t yy_meta[35] =
+static yyconst flex_int32_t yy_meta[33] =
     {   0,
         1,    1,    2,    1,    1,    1,    1,    1,    3,    4,
         1,    1,    1,    4,    4,    1,    4,    4,    4,    4,
         4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
-        4,    4,    4,    1
+        4,    1
     } ;
 
-static yyconst flex_int16_t yy_base[94] =
+static yyconst flex_int16_t yy_base[80] =
     {   0,
-        0,    0,  129,  128,   10,   12,    0,    0,   45,    0,
-      153,  156,  150,  156,  138,   75,    0,  143,  139,   72,
-      156,  135,  134,    0,  143,  136,  119,  115,  122,  115,
-      112,  113,  112,  103,   62,  110,   68,  115,  156,  132,
-      156,  156,    0,  131,  156,   79,  156,  127,    0,  156,
-       84,   87,   91,  122,   31,    0,  156,  111,  103,  104,
-       97,    0,    0,   98,  156,    0,   95,  103,    0,   94,
-      120,    0,   34,  107,   76,    0,   82,   83,    0,    0,
-        0,   99,   98,   95,   76,    0,    0,  156,  111,  115,
-      117,   94,   84
-
+        0,    0,   89,   88,   10,   12,    0,    0,  111,  114,
+      108,  114,   96,   32,    0,  101,   97,   29,  114,   93,
+       92,    0,  101,   94,   79,   75,   76,   73,   74,   73,
+       64,   19,   71,   29,   74,   91,  114,   37,  114,   87,
+        0,  114,   36,   44,   48,   82,   52,    0,  114,   71,
+       65,   60,    0,    0,   61,  114,    0,   58,   64,    0,
+       57,   57,   73,   60,    0,   53,    0,    0,    0,   71,
+       66,   62,   41,    0,  114,   70,   74,   76,   43
     } ;
 
-static yyconst flex_int16_t yy_def[94] =
+static yyconst flex_int16_t yy_def[80] =
     {   0,
-       88,    1,    1,    1,    1,    1,    1,    1,   88,    9,
-       88,   88,   88,   88,   88,   89,   90,   88,   88,   91,
-       88,   88,   88,   92,   88,   91,   92,   92,   92,   92,
-       92,   92,   92,   88,   92,   92,   92,   92,   88,   88,
-       88,   88,   93,   88,   88,   89,   88,   88,   90,   88,
-       88,   88,   91,   91,   91,   92,   88,   92,   92,   92,
-       92,   92,   92,   92,   88,   92,   92,   92,   92,   92,
-       88,   93,   88,   88,   91,   92,   92,   92,   92,   92,
-       92,   88,   88,   88,   92,   92,   92,    0,   88,   88,
-       88,   88,   88
-
+       75,    1,    1,    1,    1,    1,    1,    1,   75,   75,
+       75,   75,   75,   76,   77,   75,   75,   78,   75,   75,
+       75,   79,   75,   78,   79,   79,   79,   79,   79,   79,
+       75,   79,   79,   79,   79,   75,   75,   76,   75,   75,
+       77,   75,   75,   75,   78,   78,   78,   79,   75,   79,
+       79,   79,   79,   79,   79,   75,   79,   79,   79,   79,
+       79,   75,   75,   78,   79,   79,   79,   79,   79,   75,
+       75,   75,   79,   79,    0,   75,   75,   75,   75
     } ;
 
-static yyconst flex_int16_t yy_nxt[191] =
+static yyconst flex_int16_t yy_nxt[147] =
     {   0,
-       12,   13,   14,   15,   16,   17,   18,   12,   19,   20,
-       21,   22,   23,   24,   24,   25,   26,   27,   24,   24,
-       24,   28,   29,   24,   30,   31,   24,   24,   24,   32,
-       24,   33,   24,   34,   36,   37,   36,   37,   74,   88,
-       75,   82,   38,   83,   38,   39,   40,   41,   39,   39,
-       39,   39,   39,   39,   39,   42,   39,   39,   43,   43,
-       39,   39,   43,   43,   43,   43,   43,   43,   43,   43,
-       43,   43,   43,   43,   43,   43,   43,   43,   39,   47,
-       52,   53,   66,   47,   88,   75,   55,   72,   68,   62,
-       48,   55,   69,   51,   48,   62,   51,   56,   73,   52,
-
-       53,   73,   87,   73,   84,   55,   73,   83,   83,   86,
-       55,   46,   85,   46,   46,   49,   84,   49,   49,   54,
-       54,   71,   69,   81,   79,   80,   79,   78,   77,   76,
-       88,   46,   44,   71,   70,   67,   65,   64,   63,   62,
-       61,   60,   59,   58,   88,   57,   45,   45,   51,   50,
-       45,   44,   88,   35,   35,   11,   88,   88,   88,   88,
-       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
-       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
-       88,   88,   88,   88,   88,   88,   88,   88,   88,   88
+       10,   11,   12,   13,   14,   15,   16,   10,   17,   18,
+       19,   20,   21,   22,   22,   23,   24,   25,   22,   22,
+       22,   26,   27,   28,   22,   22,   22,   29,   22,   30,
+       22,   31,   33,   34,   33,   34,   39,   44,   45,   57,
+       35,   39,   35,   47,   53,   43,   48,   40,   47,   59,
+       62,   60,   40,   43,   53,   62,   44,   45,   62,   63,
+       75,   64,   47,   62,   70,   74,   71,   47,   75,   64,
+       38,   72,   38,   38,   41,   71,   41,   41,   46,   46,
+       71,   73,   72,   60,   69,   67,   68,   67,   66,   65,
+       75,   38,   36,   61,   58,   56,   55,   54,   53,   52,
+
+       51,   50,   75,   49,   37,   37,   43,   42,   37,   36,
+       75,   32,   32,    9,   75,   75,   75,   75,   75,   75,
+       75,   75,   75,   75,   75,   75,   75,   75,   75,   75,
+       75,   75,   75,   75,   75,   75,   75,   75,   75,   75,
+       75,   75,   75,   75,   75,   75
     } ;
 
-static yyconst flex_int16_t yy_chk[191] =
+static yyconst flex_int16_t yy_chk[147] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    5,    5,    6,    6,   55,   55,
-       55,   73,    5,   73,    6,    9,    9,    9,    9,    9,
-        9,    9,    9,    9,    9,    9,    9,    9,    9,    9,
-        9,    9,    9,    9,    9,    9,    9,    9,    9,    9,
-        9,    9,    9,    9,    9,    9,    9,    9,    9,   16,
-       20,   20,   35,   46,   75,   75,   20,   93,   37,   35,
-       16,   20,   37,   51,   46,   37,   52,   92,   51,   53,
-
-       53,   52,   85,   51,   84,   53,   52,   83,   82,   78,
-       53,   89,   77,   89,   89,   90,   74,   90,   90,   91,
-       91,   71,   70,   68,   67,   64,   61,   60,   59,   58,
-       54,   48,   44,   40,   38,   36,   34,   33,   32,   31,
-       30,   29,   28,   27,   26,   25,   23,   22,   19,   18,
-       15,   13,   11,    4,    3,   88,   88,   88,   88,   88,
-       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
-       88,   88,   88,   88,   88,   88,   88,   88,   88,   88,
-       88,   88,   88,   88,   88,   88,   88,   88,   88,   88
+        1,    1,    5,    5,    6,    6,   14,   18,   18,   32,
+        5,   38,    6,   18,   32,   43,   79,   14,   18,   34,
+       43,   34,   38,   44,   34,   43,   45,   45,   44,   47,
+       47,   47,   45,   44,   62,   73,   62,   45,   64,   64,
+       76,   72,   76,   76,   77,   71,   77,   77,   78,   78,
+       70,   66,   63,   61,   59,   58,   55,   52,   51,   50,
+       46,   40,   36,   35,   33,   31,   30,   29,   28,   27,
+
+       26,   25,   24,   23,   21,   20,   17,   16,   13,   11,
+        9,    4,    3,   75,   75,   75,   75,   75,   75,   75,
+       75,   75,   75,   75,   75,   75,   75,   75,   75,   75,
+       75,   75,   75,   75,   75,   75,   75,   75,   75,   75,
+       75,   75,   75,   75,   75,   75
     } ;
 
 /* The intent behind this definition is that it'll catch
@@ -506,7 +491,7 @@ static yyconst flex_int16_t yy_chk[191] =
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2009,2010,2011,2012,2013, by the GROMACS development team, led by
+ * Copyright (c) 2009,2010,2011,2012,2013,2014, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -567,14 +552,12 @@ static yyconst flex_int16_t yy_chk[191] =
 
 
 
-
-#line 572 "scanner.cpp"
+#line 556 "scanner.cpp"
 
 #define INITIAL 0
 #define matchof 1
 #define matchbool 2
 #define cmdstart 3
-#define help 4
 
 #ifndef YY_NO_UNISTD_H
 /* Special case for "unistd.h", since it is non-ANSI. We include it way
@@ -797,7 +780,7 @@ YY_DECL
        register int yy_act;
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 
-#line 91 "scanner.l"
+#line 90 "scanner.l"
 
 
 
@@ -825,13 +808,13 @@ YY_DECL
         BEGIN(cmdstart);
         state->bCmdStart = false;
     }
-    else if (YYSTATE != help)
+    else
     {
         BEGIN(0);
     }
 
 
-#line 835 "scanner.cpp"
+#line 818 "scanner.cpp"
 
        if ( !yyg->yy_init )
                {
@@ -884,13 +867,13 @@ yy_match:
                        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                                {
                                yy_current_state = (int) yy_def[yy_current_state];
-                               if ( yy_current_state >= 89 )
+                               if ( yy_current_state >= 76 )
                                        yy_c = yy_meta[(unsigned int) yy_c];
                                }
                        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
                        ++yy_cp;
                        }
-               while ( yy_current_state != 88 );
+               while ( yy_current_state != 75 );
                yy_cp = yyg->yy_last_accepting_cpos;
                yy_current_state = yyg->yy_last_accepting_state;
 
@@ -912,34 +895,34 @@ do_action:        /* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 124 "scanner.l"
+#line 123 "scanner.l"
 
        YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 125 "scanner.l"
+#line 124 "scanner.l"
 { yylval->i   = strtol(yytext, NULL, 10);    ADD_TOKEN; return TOK_INT; }
        YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 126 "scanner.l"
+#line 125 "scanner.l"
 { yylval->r   = strtod(yytext, NULL);        ADD_TOKEN; return TOK_REAL; }
        YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 127 "scanner.l"
+#line 126 "scanner.l"
 { yylval->str = gmx_strndup(yytext+1, yyleng-2); ADD_TOKEN; return STR;  }
        YY_BREAK
 case 5:
 /* rule 5 can match eol */
 YY_RULE_SETUP
-#line 129 "scanner.l"
+#line 128 "scanner.l"
 { _gmx_sel_lexer_add_token(" ", 1, state); }
        YY_BREAK
 case 6:
 /* rule 6 can match eol */
 YY_RULE_SETUP
-#line 130 "scanner.l"
+#line 129 "scanner.l"
 {
                     if (yytext[0] == ';' || state->bInteractive)
                     {
@@ -954,122 +937,93 @@ YY_RULE_SETUP
                 }
        YY_BREAK
 case YY_STATE_EOF(cmdstart):
-#line 143 "scanner.l"
+#line 142 "scanner.l"
 { state->bCmdStart = true; yyterminate(); }
        YY_BREAK
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(matchof):
 case YY_STATE_EOF(matchbool):
-case YY_STATE_EOF(help):
-#line 144 "scanner.l"
+#line 143 "scanner.l"
 { state->bCmdStart = true; return CMD_SEP; }
        YY_BREAK
+
 case 7:
 YY_RULE_SETUP
 #line 146 "scanner.l"
-{ if (YYSTATE == cmdstart) { BEGIN(help); } return HELP; }
+{ ADD_TOKEN; yylval->i = 1; return TOK_INT; }
        YY_BREAK
-
 case 8:
 YY_RULE_SETUP
-#line 148 "scanner.l"
-
+#line 147 "scanner.l"
+{ ADD_TOKEN; yylval->i = 0; return TOK_INT; }
        YY_BREAK
+
 case 9:
 YY_RULE_SETUP
 #line 149 "scanner.l"
-{ yylval->str = gmx_strndup(yytext, yyleng); return HELP_TOPIC; }
+{ ADD_TOKEN; return GROUP; }
        YY_BREAK
 case 10:
-/* rule 10 can match eol */
 YY_RULE_SETUP
 #line 150 "scanner.l"
-{ state->bCmdStart = true; return CMD_SEP; }
+{ ADD_TOKEN; return TO; }
        YY_BREAK
 case 11:
 YY_RULE_SETUP
 #line 151 "scanner.l"
-{ return INVALID; }
-       YY_BREAK
-
-
-case 12:
-YY_RULE_SETUP
-#line 155 "scanner.l"
-{ ADD_TOKEN; yylval->i = 1; return TOK_INT; }
-       YY_BREAK
-case 13:
-YY_RULE_SETUP
-#line 156 "scanner.l"
-{ ADD_TOKEN; yylval->i = 0; return TOK_INT; }
-       YY_BREAK
-
-case 14:
-YY_RULE_SETUP
-#line 158 "scanner.l"
-{ ADD_TOKEN; return GROUP; }
-       YY_BREAK
-case 15:
-YY_RULE_SETUP
-#line 159 "scanner.l"
-{ ADD_TOKEN; return TO; }
-       YY_BREAK
-case 16:
-YY_RULE_SETUP
-#line 160 "scanner.l"
 { ADD_TOKEN; BEGIN(0); return OF; }
        YY_BREAK
-case 17:
+case 12:
 YY_RULE_SETUP
-#line 161 "scanner.l"
+#line 152 "scanner.l"
 { ADD_TOKEN; return AND; }
        YY_BREAK
-case 18:
+case 13:
 YY_RULE_SETUP
-#line 162 "scanner.l"
+#line 153 "scanner.l"
 { ADD_TOKEN; return OR; }
        YY_BREAK
-case 19:
+case 14:
 YY_RULE_SETUP
-#line 163 "scanner.l"
+#line 154 "scanner.l"
 { ADD_TOKEN; return XOR; }
        YY_BREAK
-case 20:
+case 15:
 YY_RULE_SETUP
-#line 164 "scanner.l"
+#line 155 "scanner.l"
 { ADD_TOKEN; return NOT; }
        YY_BREAK
-case 21:
+case 16:
 YY_RULE_SETUP
-#line 165 "scanner.l"
+#line 156 "scanner.l"
 { yylval->str = gmx_strndup(yytext, yyleng); ADD_TOKEN; return CMP_OP; }
        YY_BREAK
-case 22:
+case 17:
 YY_RULE_SETUP
-#line 167 "scanner.l"
+#line 158 "scanner.l"
 { return _gmx_sel_lexer_process_identifier(yylval, yytext, yyleng, state); }
        YY_BREAK
-case 23:
+case 18:
 YY_RULE_SETUP
-#line 169 "scanner.l"
+#line 160 "scanner.l"
 { _gmx_sel_lexer_add_token(" ", 1, state); }
        YY_BREAK
-case 24:
+case 19:
 YY_RULE_SETUP
-#line 170 "scanner.l"
+#line 161 "scanner.l"
 { yylval->str = gmx_strndup(yytext, yyleng); ADD_TOKEN; return STR; }
        YY_BREAK
-case 25:
+case 20:
 YY_RULE_SETUP
-#line 171 "scanner.l"
+#line 162 "scanner.l"
 { ADD_TOKEN; return yytext[0]; }
        YY_BREAK
-case 26:
+case 21:
 YY_RULE_SETUP
-#line 172 "scanner.l"
+#line 163 "scanner.l"
 YY_FATAL_ERROR( "flex scanner jammed" );
        YY_BREAK
-#line 1073 "scanner.cpp"
+#line 1027 "scanner.cpp"
 
        case YY_END_OF_BUFFER:
                {
@@ -1362,7 +1316,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
                while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                        {
                        yy_current_state = (int) yy_def[yy_current_state];
-                       if ( yy_current_state >= 89 )
+                       if ( yy_current_state >= 76 )
                                yy_c = yy_meta[(unsigned int) yy_c];
                        }
                yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1391,11 +1345,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                {
                yy_current_state = (int) yy_def[yy_current_state];
-               if ( yy_current_state >= 89 )
+               if ( yy_current_state >= 76 )
                        yy_c = yy_meta[(unsigned int) yy_c];
                }
        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-       yy_is_jam = (yy_current_state == 88);
+       yy_is_jam = (yy_current_state == 75);
 
        (void)yyg;
        return yy_is_jam ? 0 : yy_current_state;
@@ -2220,4 +2174,4 @@ void _gmx_sel_yyfree (void * ptr , yyscan_t yyscanner)
 
 #define YYTABLES_NAME "yytables"
 
-#line 172 "scanner.l"
+#line 163 "scanner.l"
index f200acd045208155a97c30e1b6717afb157cd434..dcd53898f9ad0fc13b06f3efd4cfdb0910a1c5cd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2009,2010,2011,2012,2013, by the GROMACS development team, led by
+ * Copyright (c) 2009,2010,2011,2012,2013,2014, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -86,7 +86,6 @@ COMMENT    (#.*)
 %s matchof
 %s matchbool
 %s cmdstart
-%x help
 
 %%
 
@@ -115,7 +114,7 @@ COMMENT    (#.*)
         BEGIN(cmdstart);
         state->bCmdStart = false;
     }
-    else if (YYSTATE != help)
+    else
     {
         BEGIN(0);
     }
@@ -143,14 +142,6 @@ COMMENT    (#.*)
 <cmdstart><<EOF>> { state->bCmdStart = true; yyterminate(); }
 <<EOF>>         { state->bCmdStart = true; return CMD_SEP; }
 
-help            { if (YYSTATE == cmdstart) { BEGIN(help); } return HELP; }
-<help>{
-[[:blank:]]+
-{IDENTIFIER}    { yylval->str = gmx_strndup(yytext, yyleng); return HELP_TOPIC; }
-";"|\n          { state->bCmdStart = true; return CMD_SEP; }
-.               { return INVALID; }
-}
-
 <matchbool>{
 yes|on          { ADD_TOKEN; yylval->i = 1; return TOK_INT; }
 no|off          { ADD_TOKEN; yylval->i = 0; return TOK_INT; }
index b2c9e5c6638aec18188504727f501932ce08a3c1..89dabd919a2d7676bda7721e73d023c42a9a5aab 100644 (file)
@@ -6,7 +6,7 @@
 #line 50 "scanner.l"
 // Required before flex definitions, since it includes <stdint.h>.
 // Otherwise, compilers not strictly C99 get macro redefinition errors,
-// since flex defines INT64_MAX etc. in such cases.
+// since flex defines INT32_MAX etc. in such cases.
 #include "gromacs/legacyheaders/types/simple.h"
 
 
@@ -229,7 +229,6 @@ void _gmx_sel_yyfree (void * ,yyscan_t yyscanner );
 #define matchof 1
 #define matchbool 2
 #define cmdstart 3
-#define help 4
 
 #endif
 
@@ -341,8 +340,8 @@ extern int _gmx_sel_yylex (yyscan_t yyscanner);
 #undef YY_DECL
 #endif
 
-#line 172 "scanner.l"
+#line 163 "scanner.l"
 
-#line 347 "scanner_flex.h"
+#line 346 "scanner_flex.h"
 #undef _gmx_sel_yyIN_HEADER
 #endif /* _gmx_sel_yyHEADER_H */
index 614dd01ae7babb1f44e4b86cf0a56df29bc544e7..18bcff9838d8ce7afd5d42ea9e512f54b3bf4334 100644 (file)
  */
 #include "selectioncollection.h"
 
+#include <cctype>
 #include <cstdio>
 
+#include <string>
+#include <vector>
+
 #include <boost/shared_ptr.hpp>
 
 #include "gromacs/legacyheaders/oenv.h"
 #include "gromacs/legacyheaders/smalloc.h"
 #include "gromacs/legacyheaders/xvgr.h"
 
+#include "gromacs/onlinehelp/helpmanager.h"
+#include "gromacs/onlinehelp/helpwritercontext.h"
 #include "gromacs/options/basicoptions.h"
 #include "gromacs/options/options.h"
 #include "gromacs/selection/selection.h"
@@ -270,6 +276,42 @@ void printCurrentStatus(gmx_ana_selcollection_t *sc, gmx_ana_indexgrps_t *grps,
     }
 }
 
+/*! \brief
+ * Prints selection help in interactive selection input.
+ *
+ * \param[in] sc    Selection collection data structure.
+ * \param[in] line  Line of user input requesting help (starting with `help`).
+ *
+ * Initializes the selection help if not yet initialized, and finds the help
+ * topic based on words on the input line.
+ */
+void printHelp(gmx_ana_selcollection_t *sc, const std::string &line)
+{
+    if (sc->rootHelp.get() == NULL)
+    {
+        sc->rootHelp = createSelectionHelpTopic();
+    }
+    HelpWriterContext context(&File::standardError(),
+                              eHelpOutputFormat_Console);
+    HelpManager       manager(*sc->rootHelp, context);
+    try
+    {
+        std::vector<std::string>                 topic = splitString(line);
+        std::vector<std::string>::const_iterator value;
+        // First item in the list is the 'help' token.
+        for (value = topic.begin() + 1; value != topic.end(); ++value)
+        {
+            manager.enterTopic(*value);
+        }
+    }
+    catch (const InvalidInputError &ex)
+    {
+        fprintf(stderr, "%s\n", ex.what());
+        return;
+    }
+    manager.writeCurrentTopic();
+}
+
 /*! \brief
  * Helper function that runs the parser once the tokenizer has been
  * initialized.
@@ -316,11 +358,18 @@ SelectionList runParser(yyscan_t scanner, bool bStdIn, int maxnr,
             {
                 if (bInteractive)
                 {
+                    line = stripString(line);
                     if (line.empty())
                     {
                         printCurrentStatus(sc, grps, oldCount, maxnr, context, false);
                         continue;
                     }
+                    if (startsWith(line, "help")
+                        && (line[4] == 0 || std::isspace(line[4])))
+                    {
+                        printHelp(sc, line);
+                        continue;
+                    }
                 }
                 line.append("\n");
                 _gmx_sel_set_lex_input_str(scanner, line.c_str());
index a163e862fc332510500e609d30fbc7a5773e7285..38808d97715b5fe479172e669f85f1a05c1bfb78 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2009,2010,2011,2012,2013, by the GROMACS development team, led by
+ * Copyright (c) 2009,2010,2011,2012,2013,2014, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -185,8 +185,7 @@ SelectionParserSymbolTable::Impl::addReservedSymbols()
         "yes",
         "no",
         "on",
-        "off",
-        "help",
+        "off"
     };
 
     for (size_t i = 0; i < asize(sym_reserved); ++i)
index 2ba8655b0ad4f626abe5855f462c26d57a5d016d..f106e2f4afd5c0fea9fb5ffcc2a8a4f0a50b66e9 100644 (file)
@@ -455,12 +455,6 @@ TEST_F(SelectionCollectionTest, HandlesMissingMethodParamValue3)
                      gmx::InvalidInputError);
 }
 
-TEST_F(SelectionCollectionTest, HandlesHelpKeywordInInvalidContext)
-{
-    EXPECT_THROW_GMX(sc_.parseFromString("resname help"),
-                     gmx::InvalidInputError);
-}
-
 // TODO: Tests for more parser errors
 
 TEST_F(SelectionCollectionTest, HandlesUnknownGroupReferenceParser1)
index 638d10b7109757828971968da8567db2eb7154ec..82bf0a39de7f6e0beefcab95af2349e280a0eab2 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2011,2012,2013, by the GROMACS development team, led by
+ * Copyright (c) 2011,2012,2013,2014, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -79,6 +79,21 @@ std::string stripSuffixIfPresent(const std::string &str, const char *suffix)
     return str;
 }
 
+std::string stripString(const std::string &str)
+{
+    std::string::const_iterator start = str.begin();
+    std::string::const_iterator end   = str.end();
+    while (start != end && std::isspace(*start))
+    {
+        ++start;
+    }
+    while (start != end && std::isspace(*(end - 1)))
+    {
+        --end;
+    }
+    return std::string(start, end);
+}
+
 std::string formatString(const char *fmt, ...)
 {
     va_list           ap;
@@ -112,6 +127,30 @@ std::string formatString(const char *fmt, ...)
     }
 }
 
+std::vector<std::string> splitString(const std::string &str)
+{
+    std::vector<std::string>          result;
+    std::string::const_iterator       currPos = str.begin();
+    const std::string::const_iterator end     = str.end();
+    while (currPos != end)
+    {
+        while (currPos != end && std::isspace(*currPos))
+        {
+            ++currPos;
+        }
+        const std::string::const_iterator startPos = currPos;
+        while (currPos != end && !std::isspace(*currPos))
+        {
+            ++currPos;
+        }
+        if (startPos != end)
+        {
+            result.push_back(std::string(startPos, currPos));
+        }
+    }
+    return result;
+}
+
 std::string concatenateStrings(const char *const *sarray, size_t count)
 {
     std::string result;
index 511b71e99b46cc7a694db26788537b470f982c8e..b799608de6a009e38a975844ffaecb412cdd6fd7 100644 (file)
@@ -98,9 +98,17 @@ bool endsWith(const std::string &str, const char *suffix);
  * Returns \p str if \p suffix is NULL or empty.
  */
 std::string stripSuffixIfPresent(const std::string &str, const char *suffix);
+/*! \brief
+ * Removes leading and trailing whitespace from a string.
+ *
+ * \param[in] str  String to process.
+ * \returns   \p str with leading and trailing whitespaces removed.
+ * \throws    std::bad_alloc if out of memory.
+ */
+std::string stripString(const std::string &str);
 
 /*! \brief
- * Format a string (snprintf() wrapper).
+ * Formats a string (snprintf() wrapper).
  *
  * \throws  std::bad_alloc if out of memory.
  *
@@ -110,6 +118,19 @@ std::string stripSuffixIfPresent(const std::string &str, const char *suffix);
  */
 std::string formatString(const char *fmt, ...);
 
+/*! \brief
+ * Splits a string to whitespace separated tokens.
+ *
+ * \param[in] str  String to process.
+ * \returns   \p str split into tokens at each whitespace sequence.
+ * \throws    std::bad_alloc if out of memory.
+ *
+ * This function works like `split` in Python, i.e., leading and trailing
+ * whitespace is ignored, and consecutive whitespaces are treated as a single
+ * separator.
+ */
+std::vector<std::string> splitString(const std::string &str);
+
 /*! \brief
  * Joins strings from a range with a separator in between.
  *
index ac3942738c1cebd76ea4649700735508193fcb8c..348ffa8964563198fca18852c8edffd34a0e10b6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the GROMACS molecular simulation package.
  *
- * Copyright (c) 2012, by the GROMACS development team, led by
+ * Copyright (c) 2012,2014, by the GROMACS development team, led by
  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
  * and including many others, as listed in the AUTHORS file in the
  * top-level source directory and at http://www.gromacs.org.
@@ -46,6 +46,7 @@
 #include <string>
 #include <vector>
 
+#include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
 #include "gromacs/utility/stringutil.h"
@@ -60,7 +61,7 @@ namespace
  * Tests for simple string utilities
  */
 
-TEST(StringUtilityTest, StartsWithWorks)
+TEST(StringUtilityTest, StartsWith)
 {
     EXPECT_TRUE(gmx::startsWith("foobar", "foo"));
     EXPECT_TRUE(gmx::startsWith("foobar", ""));
@@ -76,7 +77,7 @@ TEST(StringUtilityTest, StartsWithWorks)
     EXPECT_FALSE(gmx::startsWith(std::string("foobar"), "oob"));
 }
 
-TEST(StringUtilityTest, EndsWithWorks)
+TEST(StringUtilityTest, EndsWith)
 {
     EXPECT_TRUE(gmx::endsWith("foobar", "bar"));
     EXPECT_TRUE(gmx::endsWith("foobar", NULL));
@@ -98,6 +99,29 @@ TEST(StringUtilityTest, StripSuffixIfPresent)
     EXPECT_EQ("foobar", gmx::stripSuffixIfPresent("foobar", "foofoobar"));
 }
 
+TEST(StringUtilityTest, StripString)
+{
+    EXPECT_EQ("", gmx::stripString(""));
+    EXPECT_EQ("foo", gmx::stripString("foo"));
+    EXPECT_EQ("foo", gmx::stripString("  foo"));
+    EXPECT_EQ("foo", gmx::stripString("foo "));
+    EXPECT_EQ("f o o", gmx::stripString(" f o o  "));
+}
+
+TEST(StringUtilityTest, SplitString)
+{
+    using ::testing::ElementsAre;
+    using ::testing::IsEmpty;
+    using ::testing::Matcher;
+    Matcher<std::vector<std::string> > matcher = ElementsAre("foo", "bar");
+    EXPECT_THAT(gmx::splitString("foo bar"), matcher);
+    EXPECT_THAT(gmx::splitString("  foo bar"), matcher);
+    EXPECT_THAT(gmx::splitString("foo bar  "), matcher);
+    EXPECT_THAT(gmx::splitString(" foo \t bar  "), matcher);
+    EXPECT_THAT(gmx::splitString(""), IsEmpty());
+    EXPECT_THAT(gmx::splitString("   "), IsEmpty());
+}
+
 /********************************************************************
  * Tests for formatString()
  */