pspp-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Pspp-cvs] pspp/src language/command.c language/command.h ...


From: John Darrington
Subject: [Pspp-cvs] pspp/src language/command.c language/command.h ...
Date: Sat, 11 Nov 2006 23:10:02 +0000

CVSROOT:        /sources/pspp
Module name:    pspp
Changes by:     John Darrington <jmd>   06/11/11 23:10:01

Modified files:
        src/language   : command.c command.h 
        src/language/control: do-if.c loop.c repeat.c temporary.c 
        src/language/data-io: data-list.c data-reader.c data-reader.h 
                              file-handle.h file-handle.q get.c 
                              inpt-pgm.c list.q matrix-data.c 
                              placement-parser.c placement-parser.h 
                              print-space.c print.c 
        src/language/dictionary: apply-dictionary.c formats.c 
                                 missing-values.c modify-variables.c 
                                 numeric.c rename-variables.c 
                                 split-file.c sys-file-info.c 
                                 value-labels.c variable-display.c 
                                 variable-label.c vector.c weight.c 
        src/language/expressions: evaluate.c parse.c private.h public.h 
        src/language/lexer: ChangeLog format-parser.c format-parser.h 
                            lexer.c lexer.h q2c.c range-parser.c 
                            range-parser.h subcommand-list.c 
                            variable-parser.c variable-parser.h 
        src/language/stats: aggregate.c autorecode.c correlations.q 
                            crosstabs.q descriptives.c examine.q flip.c 
                            frequencies.q means.q oneway.q rank.q 
                            regression.q sort-cases.c sort-criteria.c 
                            sort-criteria.h t-test.q 
        src/language/tests: casefile-test.c float-format.c 
                            moments-test.c pool-test.c 
        src/language/utilities: date.c echo.c include.c permissions.c 
                                set.q title.c 
        src/language/xforms: compute.c count.c fail.c recode.c sample.c 
                             select-if.c 
        src/ui/terminal: main.c 

Log message:
        Encapsulated lexer and updated calling functions accordingly.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/command.c?cvsroot=pspp&r1=1.18&r2=1.19
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/command.h?cvsroot=pspp&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/control/do-if.c?cvsroot=pspp&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/control/loop.c?cvsroot=pspp&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/control/repeat.c?cvsroot=pspp&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/control/temporary.c?cvsroot=pspp&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/data-io/data-list.c?cvsroot=pspp&r1=1.24&r2=1.25
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/data-io/data-reader.c?cvsroot=pspp&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/data-io/data-reader.h?cvsroot=pspp&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/data-io/file-handle.h?cvsroot=pspp&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/data-io/file-handle.q?cvsroot=pspp&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/data-io/get.c?cvsroot=pspp&r1=1.20&r2=1.21
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/data-io/inpt-pgm.c?cvsroot=pspp&r1=1.16&r2=1.17
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/data-io/list.q?cvsroot=pspp&r1=1.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/data-io/matrix-data.c?cvsroot=pspp&r1=1.16&r2=1.17
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/data-io/placement-parser.c?cvsroot=pspp&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/data-io/placement-parser.h?cvsroot=pspp&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/data-io/print-space.c?cvsroot=pspp&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/data-io/print.c?cvsroot=pspp&r1=1.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/dictionary/apply-dictionary.c?cvsroot=pspp&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/dictionary/formats.c?cvsroot=pspp&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/dictionary/missing-values.c?cvsroot=pspp&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/dictionary/modify-variables.c?cvsroot=pspp&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/dictionary/numeric.c?cvsroot=pspp&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/dictionary/rename-variables.c?cvsroot=pspp&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/dictionary/split-file.c?cvsroot=pspp&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/dictionary/sys-file-info.c?cvsroot=pspp&r1=1.13&r2=1.14
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/dictionary/value-labels.c?cvsroot=pspp&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/dictionary/variable-display.c?cvsroot=pspp&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/dictionary/variable-label.c?cvsroot=pspp&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/dictionary/vector.c?cvsroot=pspp&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/dictionary/weight.c?cvsroot=pspp&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/expressions/evaluate.c?cvsroot=pspp&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/expressions/parse.c?cvsroot=pspp&r1=1.17&r2=1.18
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/expressions/private.h?cvsroot=pspp&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/expressions/public.h?cvsroot=pspp&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/lexer/ChangeLog?cvsroot=pspp&r1=1.16&r2=1.17
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/lexer/format-parser.c?cvsroot=pspp&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/lexer/format-parser.h?cvsroot=pspp&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/lexer/lexer.c?cvsroot=pspp&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/lexer/lexer.h?cvsroot=pspp&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/lexer/q2c.c?cvsroot=pspp&r1=1.17&r2=1.18
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/lexer/range-parser.c?cvsroot=pspp&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/lexer/range-parser.h?cvsroot=pspp&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/lexer/subcommand-list.c?cvsroot=pspp&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/lexer/variable-parser.c?cvsroot=pspp&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/lexer/variable-parser.h?cvsroot=pspp&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/stats/aggregate.c?cvsroot=pspp&r1=1.18&r2=1.19
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/stats/autorecode.c?cvsroot=pspp&r1=1.13&r2=1.14
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/stats/correlations.q?cvsroot=pspp&r1=1.13&r2=1.14
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/stats/crosstabs.q?cvsroot=pspp&r1=1.21&r2=1.22
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/stats/descriptives.c?cvsroot=pspp&r1=1.16&r2=1.17
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/stats/examine.q?cvsroot=pspp&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/stats/flip.c?cvsroot=pspp&r1=1.13&r2=1.14
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/stats/frequencies.q?cvsroot=pspp&r1=1.21&r2=1.22
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/stats/means.q?cvsroot=pspp&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/stats/oneway.q?cvsroot=pspp&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/stats/rank.q?cvsroot=pspp&r1=1.18&r2=1.19
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/stats/regression.q?cvsroot=pspp&r1=1.37&r2=1.38
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/stats/sort-cases.c?cvsroot=pspp&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/stats/sort-criteria.c?cvsroot=pspp&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/stats/sort-criteria.h?cvsroot=pspp&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/stats/t-test.q?cvsroot=pspp&r1=1.14&r2=1.15
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/tests/casefile-test.c?cvsroot=pspp&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/tests/float-format.c?cvsroot=pspp&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/tests/moments-test.c?cvsroot=pspp&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/tests/pool-test.c?cvsroot=pspp&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/utilities/date.c?cvsroot=pspp&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/utilities/echo.c?cvsroot=pspp&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/utilities/include.c?cvsroot=pspp&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/utilities/permissions.c?cvsroot=pspp&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/utilities/set.q?cvsroot=pspp&r1=1.18&r2=1.19
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/utilities/title.c?cvsroot=pspp&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/xforms/compute.c?cvsroot=pspp&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/xforms/count.c?cvsroot=pspp&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/xforms/fail.c?cvsroot=pspp&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/xforms/recode.c?cvsroot=pspp&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/xforms/sample.c?cvsroot=pspp&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/pspp/src/language/xforms/select-if.c?cvsroot=pspp&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/pspp/src/ui/terminal/main.c?cvsroot=pspp&r1=1.19&r2=1.20

Patches:
Index: language/command.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/command.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -b -r1.18 -r1.19
--- language/command.c  26 Oct 2006 06:16:36 -0000      1.18
+++ language/command.c  11 Nov 2006 23:10:00 -0000      1.19
@@ -108,7 +108,7 @@
     enum states states;         /* States in which command is allowed. */
     enum flags flags;           /* Other command requirements. */
     const char *name;          /* Command name. */
-    int (*function) (struct dataset *);        /* Function to call. */
+    int (*function) (struct lexer *, struct dataset *);        /* Function to 
call. */
   };
 
 /* Define the command array. */
@@ -130,22 +130,22 @@
 
 /* Command parser. */
 
-static const struct command *parse_command_name (void);
-static enum cmd_result do_parse_command (struct dataset *ds, enum cmd_state);
+static const struct command *parse_command_name (struct lexer *lexer);
+static enum cmd_result do_parse_command (struct lexer *, struct dataset *, 
enum cmd_state);
 
 /* Parses an entire command, from command name to terminating
    dot.  On failure, skips to the terminating dot.
    Returns the command's success or failure result. */
 enum cmd_result
-cmd_parse (struct dataset *ds, enum cmd_state state) 
+cmd_parse (struct lexer *lexer, struct dataset *ds, enum cmd_state state) 
 {
   int result;
   
   som_new_series ();
 
-  result = do_parse_command (ds, state);
+  result = do_parse_command (lexer, ds, state);
   if (cmd_result_is_failure (result)) 
-    lex_discard_rest_of_command ();
+    lex_discard_rest_of_command (lexer);
 
   unset_cmd_algorithm ();
   dict_clear_aux (dataset_dict (ds));
@@ -156,7 +156,7 @@
 /* Parses an entire command, from command name to terminating
    dot. */
 static enum cmd_result
-do_parse_command (struct dataset *ds, enum cmd_state state)
+do_parse_command (struct lexer *lexer, struct dataset *ds, enum cmd_state 
state)
 {
   const struct command *command;
   enum cmd_result result;
@@ -164,10 +164,10 @@
   /* Read the command's first token. */
   getl_set_prompt_style (GETL_PROMPT_FIRST);
   set_completion_state (state);
-  lex_get ();
-  if (token == T_STOP)
+  lex_get (lexer);
+  if (lex_token (lexer) == T_STOP)
     return CMD_EOF;
-  else if (token == '.') 
+  else if (lex_token (lexer) == '.') 
     {
       /* Null commands can result from extra empty lines. */
       return CMD_SUCCESS; 
@@ -175,7 +175,7 @@
   getl_set_prompt_style (GETL_PROMPT_LATER);
 
   /* Parse the command name. */
-  command = parse_command_name ();
+  command = parse_command_name (lexer);
   if (command == NULL)
     return CMD_FAILURE;
   else if (command->function == NULL) 
@@ -203,7 +203,7 @@
   /* Execute command. */
   msg_set_command_name (command->name);
   tab_set_command_name (command->name);
-  result = command->function (ds);
+  result = command->function (lexer, ds);
   tab_set_command_name (NULL);
   msg_set_command_name (NULL);
     
@@ -441,10 +441,10 @@
 /* Flags an error that the command whose name is given by the
    WORD_CNT words in WORDS is unknown. */
 static void
-unknown_command_error (char *const words[], size_t word_cnt) 
+unknown_command_error (struct lexer *lexer, char *const words[], size_t 
word_cnt) 
 {
   if (word_cnt == 0) 
-    lex_error (_("expecting command name"));
+    lex_error (lexer, _("expecting command name"));
   else 
     {
       struct string s;
@@ -468,29 +468,30 @@
    struct command if successful.
    If not successful, return a null pointer. */
 static const struct command *
-parse_command_name (void)
+parse_command_name (struct lexer *lexer)
 {
   char *words[16];
   int word_cnt;
   int complete_word_cnt;
   int dash_possible;
 
-  if (token == T_EXP || token == '*' || token == '[') 
+  if (lex_token (lexer) == T_EXP || 
+                 lex_token (lexer) == '*' || lex_token (lexer) == '[') 
     return find_command ("COMMENT");
 
   dash_possible = 0;
   word_cnt = complete_word_cnt = 0;
-  while (token == T_ID || (dash_possible && token == '-')) 
+  while (lex_token (lexer) == T_ID || (dash_possible && lex_token (lexer) == 
'-')) 
     {
       int cmd_match_cnt;
       
       assert (word_cnt < sizeof words / sizeof *words);
-      if (token == T_ID) 
+      if (lex_token (lexer) == T_ID) 
         {
-          words[word_cnt] = ds_xstrdup (&tokstr);
+          words[word_cnt] = ds_xstrdup (lex_tokstr (lexer));
           str_uppercase (words[word_cnt]); 
         }
-      else if (token == '-')
+      else if (lex_token (lexer) == '-')
         words[word_cnt] = xstrdup ("-");
       word_cnt++;
 
@@ -504,7 +505,7 @@
           if (command != NULL) 
             {
               if (!(command->flags & F_KEEP_FINAL_TOKEN))
-                lex_get ();
+                lex_get (lexer);
               free_words (words, word_cnt);
               return command;
             }
@@ -515,7 +516,7 @@
           if (get_complete_match (words, word_cnt) != NULL)
             complete_word_cnt = word_cnt;
         }
-      lex_get ();
+      lex_get (lexer);
     }
 
   /* If we saw a complete command name earlier, drop back to
@@ -542,9 +543,9 @@
         {
           word_cnt--;
           if (strcmp (words[word_cnt], "-")) 
-            lex_put_back_id (words[word_cnt]);
+            lex_put_back_id (lexer, words[word_cnt]);
           else
-            lex_put_back ('-');
+            lex_put_back (lexer, '-');
           free (words[word_cnt]);
         }
 
@@ -553,7 +554,7 @@
     }
 
   /* We didn't get a valid command name. */
-  unknown_command_error (words, word_cnt);
+  unknown_command_error (lexer, words, word_cnt);
   free_words (words, word_cnt);
   return NULL;
 }
@@ -649,40 +650,40 @@
 
 /* Parse and execute FINISH command. */
 int
-cmd_finish (struct dataset *ds UNUSED)
+cmd_finish (struct lexer *lexer UNUSED, struct dataset *ds UNUSED)
 {
   return CMD_FINISH;
 }
 
 /* Parses the N command. */
 int
-cmd_n_of_cases (struct dataset *ds)
+cmd_n_of_cases (struct lexer *lexer, struct dataset *ds)
 {
   /* Value for N. */
   int x;
 
-  if (!lex_force_int ())
+  if (!lex_force_int (lexer))
     return CMD_FAILURE;
-  x = lex_integer ();
-  lex_get ();
-  if (!lex_match_id ("ESTIMATED"))
+  x = lex_integer (lexer);
+  lex_get (lexer);
+  if (!lex_match_id (lexer, "ESTIMATED"))
     dict_set_case_limit (dataset_dict (ds), x);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Parses, performs the EXECUTE procedure. */
 int
-cmd_execute (struct dataset *ds)
+cmd_execute (struct lexer *lexer, struct dataset *ds)
 {
   if (!procedure (ds, NULL, NULL))
     return CMD_CASCADING_FAILURE;
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Parses, performs the ERASE command. */
 int
-cmd_erase (struct dataset *ds UNUSED)
+cmd_erase (struct lexer *lexer, struct dataset *ds UNUSED)
 {
   if (get_safer_mode ()) 
     { 
@@ -690,16 +691,16 @@
       return CMD_FAILURE; 
     } 
   
-  if (!lex_force_match_id ("FILE"))
+  if (!lex_force_match_id (lexer, "FILE"))
     return CMD_FAILURE;
-  lex_match ('=');
-  if (!lex_force_string ())
+  lex_match (lexer, '=');
+  if (!lex_force_string (lexer))
     return CMD_FAILURE;
 
-  if (remove (ds_cstr (&tokstr)) == -1)
+  if (remove (ds_cstr (lex_tokstr (lexer))) == -1)
     {
       msg (SW, _("Error removing `%s': %s."),
-          ds_cstr (&tokstr), strerror (errno));
+          ds_cstr (lex_tokstr (lexer)), strerror (errno));
       return CMD_FAILURE;
     }
 
@@ -763,27 +764,27 @@
 /* Parses the HOST command argument and executes the specified
    command.  Returns a suitable command return code. */
 static int
-run_command (void)
+run_command (struct lexer *lexer)
 {
   const char *cmd;
   int string;
 
   /* Handle either a string argument or a full-line argument. */
   {
-    int c = lex_look_ahead ();
+    int c = lex_look_ahead (lexer);
 
     if (c == '\'' || c == '"')
       {
-       lex_get ();
-       if (!lex_force_string ())
+       lex_get (lexer);
+       if (!lex_force_string (lexer))
          return CMD_FAILURE;
-       cmd = ds_cstr (&tokstr);
+       cmd = ds_cstr (lex_tokstr (lexer));
        string = 1;
       }
     else
       {
-       cmd = lex_rest_of_line (NULL);
-        lex_discard_line ();
+       cmd = lex_rest_of_line (lexer, NULL);
+        lex_discard_line (lexer);
        string = 0;
       }
   }
@@ -795,23 +796,21 @@
   /* Finish parsing. */
   if (string)
     {
-      lex_get ();
+      lex_get (lexer);
 
-      if (token != '.')
+      if (lex_token (lexer) != '.')
        {
-         lex_error (_("expecting end of command"));
+         lex_error (lexer, _("expecting end of command"));
          return CMD_FAILURE;
        }
     }
-  else
-    token = '.';
 
   return CMD_SUCCESS;
 }
 
 /* Parses, performs the HOST command. */
 int
-cmd_host (struct dataset *ds UNUSED)
+cmd_host (struct lexer *lexer, struct dataset *ds UNUSED)
 {
   int code;
 
@@ -824,18 +823,18 @@
 #ifdef unix
   /* Figure out whether to invoke an interactive shell or to execute a
      single shell command. */
-  if (lex_look_ahead () == '.')
+  if (lex_look_ahead (lexer) == '.')
     {
-      lex_get ();
+      lex_get (lexer);
       code = shell () ? CMD_FAILURE : CMD_SUCCESS;
     }
   else
-    code = run_command ();
+    code = run_command (lexer);
 #else /* !unix */
   /* Make sure that the system has a command interpreter, then run a
      command. */
   if (system (NULL) != 0)
-    code = run_command ();
+    code = run_command (lexer);
   else
     {
       msg (SE, _("No operating system support for this command."));
@@ -848,17 +847,17 @@
 
 /* Parses, performs the NEW FILE command. */
 int
-cmd_new_file (struct dataset *ds)
+cmd_new_file (struct lexer *lexer, struct dataset *ds)
 {
   discard_variables (ds);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Parses a comment. */
 int
-cmd_comment (struct dataset *ds UNUSED)
+cmd_comment (struct lexer *lexer, struct dataset *ds UNUSED)
 {
-  lex_skip_comment ();
+  lex_skip_comment (lexer);
   return CMD_SUCCESS;
 }

Index: language/command.h
===================================================================
RCS file: /sources/pspp/pspp/src/language/command.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- language/command.h  26 Oct 2006 06:16:36 -0000      1.6
+++ language/command.h  11 Nov 2006 23:10:00 -0000      1.7
@@ -55,7 +55,9 @@
   };
 
 struct dataset;
-enum cmd_result cmd_parse (struct dataset *ds, enum cmd_state);
+struct lexer; 
+
+enum cmd_result cmd_parse (struct lexer *lexer, struct dataset *ds, enum 
cmd_state);
 
 struct command;
 const char *cmd_complete (const char *, const struct command **);
@@ -63,7 +65,7 @@
 struct dataset;
 
 /* Prototype all the command functions. */
-#define DEF_CMD(STATES, FLAGS, NAME, FUNCTION) int FUNCTION (struct dataset *);
+#define DEF_CMD(STATES, FLAGS, NAME, FUNCTION) int FUNCTION (struct lexer *, 
struct dataset *);
 #define UNIMPL_CMD(NAME, DESCRIPTION)
 #include "command.def"
 #undef DEF_CMD

Index: language/control/do-if.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/control/do-if.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- language/control/do-if.c    26 Oct 2006 06:16:36 -0000      1.9
+++ language/control/do-if.c    11 Nov 2006 23:10:00 -0000      1.10
@@ -83,7 +83,7 @@
 
 static const struct ctl_class do_if_class;
 
-static int parse_clause (struct do_if_trns *, struct dataset *ds);
+static int parse_clause (struct lexer *, struct do_if_trns *, struct dataset 
*ds);
 static void add_clause (struct do_if_trns *,
                         struct expression *condition, int target_index);
 static void add_else (struct do_if_trns *);
@@ -98,7 +98,7 @@
 
 /* Parse DO IF. */
 int
-cmd_do_if (struct dataset *ds)
+cmd_do_if (struct lexer *lexer, struct dataset *ds)
 {
   struct do_if_trns *do_if = xmalloc (sizeof *do_if);
   do_if->clauses = NULL;
@@ -109,34 +109,34 @@
   add_transformation_with_finalizer (ds, do_if_finalize_func,
                                      do_if_trns_proc, do_if_trns_free, do_if);
 
-  return parse_clause (do_if, ds);
+  return parse_clause (lexer, do_if, ds);
 }
 
 /* Parse ELSE IF. */
 int
-cmd_else_if (struct dataset *ds)
+cmd_else_if (struct lexer *lexer, struct dataset *ds)
 {
   struct do_if_trns *do_if = ctl_stack_top (&do_if_class);
   if (do_if == NULL || !must_not_have_else (do_if))
     return CMD_CASCADING_FAILURE;
-  return parse_clause (do_if, ds);
+  return parse_clause (lexer, do_if, ds);
 }
 
 /* Parse ELSE. */
 int
-cmd_else (struct dataset *ds)
+cmd_else (struct lexer *lexer, struct dataset *ds)
 {
   struct do_if_trns *do_if = ctl_stack_top (&do_if_class);
   assert (ds == do_if->ds);
   if (do_if == NULL || !must_not_have_else (do_if))
     return CMD_CASCADING_FAILURE;
   add_else (do_if);
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Parse END IF. */
 int
-cmd_end_if (struct dataset *ds)
+cmd_end_if (struct lexer *lexer, struct dataset *ds)
 {
   struct do_if_trns *do_if = ctl_stack_top (&do_if_class);
   assert (ds == do_if->ds);
@@ -146,7 +146,7 @@
 
   ctl_stack_pop (do_if);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Closes out DO_IF, by adding a sentinel ELSE clause if
@@ -197,17 +197,17 @@
    corresponding clause to DO_IF.  Checks for end of command and
    returns a command return code. */
 static int
-parse_clause (struct do_if_trns *do_if, struct dataset *ds)
+parse_clause (struct lexer *lexer, struct do_if_trns *do_if, struct dataset 
*ds)
 {
   struct expression *condition;
 
-  condition = expr_parse (ds, EXPR_BOOLEAN);
+  condition = expr_parse (lexer, ds, EXPR_BOOLEAN);
   if (condition == NULL)
     return CMD_CASCADING_FAILURE;
 
   add_clause (do_if, condition, next_transformation (ds));
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Adds a clause to DO_IF that tests for the given CONDITION and,

Index: language/control/loop.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/control/loop.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- language/control/loop.c     26 Oct 2006 06:16:36 -0000      1.10
+++ language/control/loop.c     11 Nov 2006 23:10:00 -0000      1.11
@@ -87,27 +87,27 @@
 static trns_free_func loop_trns_free;
 
 static struct loop_trns *create_loop_trns (struct dataset *);
-static bool parse_if_clause (struct loop_trns *, struct expression **);
-static bool parse_index_clause (struct loop_trns *, char index_var_name[]);
+static bool parse_if_clause (struct lexer *, struct loop_trns *, struct 
expression **);
+static bool parse_index_clause (struct lexer *, struct loop_trns *, char 
index_var_name[]);
 static void close_loop (void *);
 
 /* LOOP. */
 
 /* Parses LOOP. */
 int
-cmd_loop (struct dataset *ds)
+cmd_loop (struct lexer *lexer, struct dataset *ds)
 {
   struct loop_trns *loop;
   char index_var_name[LONG_NAME_LEN + 1];
   bool ok = true;
 
   loop = create_loop_trns (ds);
-  while (token != '.' && ok) 
+  while (lex_token (lexer) != '.' && ok) 
     {
-      if (lex_match_id ("IF")) 
-        ok = parse_if_clause (loop, &loop->loop_condition);
+      if (lex_match_id (lexer, "IF")) 
+        ok = parse_if_clause (lexer, loop, &loop->loop_condition);
       else
-        ok = parse_index_clause (loop, index_var_name);
+        ok = parse_index_clause (lexer, loop, index_var_name);
     }
 
   /* Find index variable and create if necessary. */
@@ -126,7 +126,7 @@
 
 /* Parses END LOOP. */
 int
-cmd_end_loop (struct dataset *ds)
+cmd_end_loop (struct lexer *lexer, struct dataset *ds)
 {
   struct loop_trns *loop;
   bool ok = true;
@@ -138,10 +138,10 @@
   assert (loop->ds == ds);
   
   /* Parse syntax. */
-  if (lex_match_id ("IF"))
-    ok = parse_if_clause (loop, &loop->end_loop_condition);
+  if (lex_match_id (lexer, "IF"))
+    ok = parse_if_clause (lexer, loop, &loop->end_loop_condition);
   if (ok)
-    ok = lex_end_of_command () == CMD_SUCCESS;
+    ok = lex_end_of_command (lexer) == CMD_SUCCESS;
 
   if (!ok)
     loop->max_pass_count = 0;
@@ -153,7 +153,7 @@
 
 /* Parses BREAK. */
 int
-cmd_break (struct dataset *ds)
+cmd_break (struct lexer *lexer, struct dataset *ds)
 {
   struct ctl_stmt *loop = ctl_stack_search (&loop_class);
   if (loop == NULL)
@@ -161,7 +161,7 @@
 
   add_transformation (ds, break_trns_proc, NULL, loop);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Closes a LOOP construct by emitting the END LOOP
@@ -187,9 +187,10 @@
    resulting expression to *CONDITION.
    Returns true if successful, false on failure. */
 static bool
-parse_if_clause (struct loop_trns *loop, struct expression **condition) 
+parse_if_clause (struct lexer *lexer, 
+                struct loop_trns *loop, struct expression **condition) 
 {
-  *condition = expr_parse_pool (loop->pool, loop->ds, EXPR_BOOLEAN);
+  *condition = expr_parse_pool (lexer, loop->pool, loop->ds, EXPR_BOOLEAN);
   return *condition != NULL;
 }
 
@@ -197,29 +198,30 @@
    Stores the index variable's name in INDEX_VAR_NAME[].
    Returns true if successful, false on failure. */
 static bool
-parse_index_clause (struct loop_trns *loop, char index_var_name[]) 
+parse_index_clause (struct lexer *lexer, struct loop_trns *loop, char 
index_var_name[]) 
 {
-  if (token != T_ID) 
+  if (lex_token (lexer) != T_ID) 
     {
-      lex_error (NULL);
+      lex_error (lexer, NULL);
       return false;
     }
-  strcpy (index_var_name, tokid);
-  lex_get ();
+  strcpy (index_var_name, lex_tokid (lexer));
+  lex_get (lexer);
 
-  if (!lex_force_match ('='))
+  if (!lex_force_match (lexer, '='))
     return false;
 
-  loop->first_expr = expr_parse_pool (loop->pool, loop->ds, EXPR_NUMBER);
+  loop->first_expr = expr_parse_pool (lexer, loop->pool, 
+                                     loop->ds, EXPR_NUMBER);
   if (loop->first_expr == NULL)
     return false;
 
   for (;;)
     {
       struct expression **e;
-      if (lex_match (T_TO)) 
+      if (lex_match (lexer, T_TO)) 
         e = &loop->last_expr;
-      else if (lex_match (T_BY)) 
+      else if (lex_match (lexer, T_BY)) 
         e = &loop->by_expr;
       else
         break;
@@ -229,13 +231,13 @@
           lex_sbc_only_once (e == &loop->last_expr ? "TO" : "BY");
           return false;
         }
-      *e = expr_parse_pool (loop->pool, loop->ds, EXPR_NUMBER);
+      *e = expr_parse_pool (lexer, loop->pool, loop->ds, EXPR_NUMBER);
       if (*e == NULL)
         return false;
     }
   if (loop->last_expr == NULL) 
     {
-      lex_sbc_missing ("TO");
+      lex_sbc_missing (lexer, "TO");
       return false;
     }
   if (loop->by_expr == NULL)

Index: language/control/repeat.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/control/repeat.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- language/control/repeat.c   28 Oct 2006 08:31:23 -0000      1.14
+++ language/control/repeat.c   11 Nov 2006 23:10:00 -0000      1.15
@@ -83,13 +83,13 @@
     bool print;                         /* Print lines as executed? */
   };
 
-static bool parse_specification (struct repeat_block *);
-static bool parse_lines (struct repeat_block *);
+static bool parse_specification (struct lexer *, struct repeat_block *);
+static bool parse_lines (struct lexer *, struct repeat_block *);
 static void create_vars (struct repeat_block *);
 
-static int parse_ids (const struct dictionary *dict, struct repeat_entry *, 
struct pool *);
-static int parse_numbers (struct repeat_entry *, struct pool *);
-static int parse_strings (struct repeat_entry *, struct pool *);
+static int parse_ids (struct lexer *, const struct dictionary *dict, struct 
repeat_entry *, struct pool *);
+static int parse_numbers (struct lexer *, struct repeat_entry *, struct pool 
*);
+static int parse_strings (struct lexer *, struct repeat_entry *, struct pool 
*);
 
 static void do_repeat_filter (struct string *line, void *block);
 static bool do_repeat_read (struct string *line, char **file_name,
@@ -97,14 +97,14 @@
 static void do_repeat_close (void *block);
 
 int
-cmd_do_repeat (struct dataset *ds)
+cmd_do_repeat (struct lexer *lexer, struct dataset *ds)
 {
   struct repeat_block *block;
 
   block = pool_create_container (struct repeat_block, pool);
   block->ds = ds;
 
-  if (!parse_specification (block) || !parse_lines (block))
+  if (!parse_specification (lexer, block) || !parse_lines (lexer, block))
     goto error;
   
   create_vars (block);
@@ -124,7 +124,7 @@
 /* Parses the whole DO REPEAT command specification.
    Returns success. */
 static bool
-parse_specification (struct repeat_block *block) 
+parse_specification (struct lexer *lexer, struct repeat_block *block) 
 {
   char first_name[LONG_NAME_LEN + 1];
 
@@ -138,16 +138,16 @@
       int count;
 
       /* Get a stand-in variable name and make sure it's unique. */
-      if (!lex_force_id ())
+      if (!lex_force_id (lexer))
        return false;
-      if (dict_lookup_var (dict, tokid))
+      if (dict_lookup_var (dict, lex_tokid (lexer)))
         msg (SW, _("Dummy variable name \"%s\" hides dictionary "
                    "variable \"%s\"."),
-             tokid, tokid);
+             lex_tokid (lexer), lex_tokid (lexer));
       for (iter = block->macros; iter != NULL; iter = iter->next)
-       if (!strcasecmp (iter->id, tokid))
+       if (!strcasecmp (iter->id, lex_tokid (lexer)))
          {
-           msg (SE, _("Dummy variable name \"%s\" is given twice."), tokid);
+           msg (SE, _("Dummy variable name \"%s\" is given twice."), lex_tokid 
(lexer));
            return false;
          }
 
@@ -155,31 +155,31 @@
          list. */
       e = pool_alloc (block->pool, sizeof *e);
       e->next = block->macros;
-      strcpy (e->id, tokid);
+      strcpy (e->id, lex_tokid (lexer));
       block->macros = e;
 
       /* Skip equals sign. */
-      lex_get ();
-      if (!lex_force_match ('='))
+      lex_get (lexer);
+      if (!lex_force_match (lexer, '='))
        return false;
 
       /* Get the details of the variable's possible values. */
-      if (token == T_ID)
-       count = parse_ids (dict, e, block->pool);
-      else if (lex_is_number ())
-       count = parse_numbers (e, block->pool);
-      else if (token == T_STRING)
-       count = parse_strings (e, block->pool);
+      if (lex_token (lexer) == T_ID)
+       count = parse_ids (lexer, dict, e, block->pool);
+      else if (lex_is_number (lexer))
+       count = parse_numbers (lexer, e, block->pool);
+      else if (lex_token (lexer) == T_STRING)
+       count = parse_strings (lexer, e, block->pool);
       else
        {
-         lex_error (NULL);
+         lex_error (lexer, NULL);
          return false;
        }
       if (count == 0)
        return false;
-      if (token != '/' && token != '.') 
+      if (lex_token (lexer) != '/' && lex_token (lexer) != '.') 
         {
-          lex_error (NULL);
+          lex_error (lexer, NULL);
           return false;
         }
 
@@ -200,9 +200,9 @@
          return false;
        }
 
-      lex_match ('/');
+      lex_match (lexer, '/');
     }
-  while (token != '.');
+  while (lex_token (lexer) != '.');
 
   return true;
 }
@@ -265,7 +265,7 @@
 /* Read all the lines we are going to substitute, inside the DO
    REPEAT...END REPEAT block. */
 static bool
-parse_lines (struct repeat_block *block) 
+parse_lines (struct lexer *lexer, struct repeat_block *block) 
 {
   char *previous_file_name;
   struct line_list **last_line;
@@ -284,7 +284,7 @@
       struct string cur_line_copy;
       bool dot;
 
-      if (! lex_get_line_raw ())
+      if (! lex_get_line_raw (lexer))
         return false;
 
       /* If the current file has changed then record the fact. */
@@ -293,7 +293,7 @@
           || !strcmp (cur_file_name, previous_file_name))
         previous_file_name = pool_strdup (block->pool, cur_file_name);
 
-      ds_init_string (&cur_line_copy, lex_entire_line_ds () );
+      ds_init_string (&cur_line_copy, lex_entire_line_ds (lexer) );
       ds_rtrim (&cur_line_copy, ss_cstr (CC_SPACES));
       dot = ds_chomp (&cur_line_copy, get_endcmd ());
 
@@ -303,7 +303,7 @@
         {
         if (nesting_level-- == 0)
           {
-            lex_discard_line ();
+            lex_discard_line (lexer);
            ds_destroy (&cur_line_copy);
             return true;
           } 
@@ -321,7 +321,7 @@
       ds_destroy (&cur_line_copy);
     }
 
-  lex_discard_line ();
+  lex_discard_line (lexer);
   return true;
 }
 
@@ -347,11 +347,13 @@
 
 /* Parses a set of ids for DO REPEAT. */
 static int
-parse_ids (const struct dictionary *dict, struct repeat_entry *e, struct pool 
*pool)
+parse_ids (struct lexer *lexer, const struct dictionary *dict, 
+          struct repeat_entry *e, struct pool *pool)
 {
   size_t n = 0;
   e->type = VAR_NAMES;
-  return parse_mixed_vars_pool (dict, pool, &e->replacement, &n, PV_NONE) ? n 
: 0;
+  return parse_mixed_vars_pool (lexer, dict, pool, 
+                               &e->replacement, &n, PV_NONE) ? n : 0;
 }
 
 /* Adds STRING to E's list of replacements, which has *USED
@@ -370,7 +372,7 @@
 
 /* Parses a list of numbers for DO REPEAT. */
 static int
-parse_numbers (struct repeat_entry *e, struct pool *pool)
+parse_numbers (struct lexer *lexer, struct repeat_entry *e, struct pool *pool)
 {
   size_t used = 0;
   size_t allocated = 0;
@@ -383,23 +385,23 @@
       long a, b, i;
 
       /* Parse A TO B into a, b. */
-      if (!lex_force_int ())
+      if (!lex_force_int (lexer))
        return 0;
-      a = lex_integer ();
+      a = lex_integer (lexer);
 
-      lex_get ();
-      if (token == T_TO)
+      lex_get (lexer);
+      if (lex_token (lexer) == T_TO)
        {
-         lex_get ();
-         if (!lex_force_int ())
+         lex_get (lexer);
+         if (!lex_force_int (lexer))
            return 0;
-         b = lex_integer ();
+         b = lex_integer (lexer);
           if (b < a) 
             {
               msg (SE, _("%ld TO %ld is an invalid range."), a, b);
               return 0;
             }
-         lex_get ();
+         lex_get (lexer);
        }
       else
         b = a;
@@ -409,16 +411,16 @@
                          e, pool, &used, &allocated);
 
 
-      lex_match (',');
+      lex_match (lexer, ',');
     }
-  while (token != '/' && token != '.');
+  while (lex_token (lexer) != '/' && lex_token (lexer) != '.');
 
   return used;
 }
 
 /* Parses a list of strings for DO REPEAT. */
 int
-parse_strings (struct repeat_entry *e, struct pool *pool)
+parse_strings (struct lexer *lexer, struct repeat_entry *e, struct pool *pool)
 {
   size_t used = 0;
   size_t allocated = 0;
@@ -430,26 +432,26 @@
     {
       char *string;
       
-      if (token != T_STRING)
+      if (lex_token (lexer) != T_STRING)
        {
          msg (SE, _("String expected."));
          return 0;
        }
 
-      string = lex_token_representation ();
+      string = lex_token_representation (lexer);
       pool_register (pool, free, string);
       add_replacement (string, e, pool, &used, &allocated);
 
-      lex_get ();
-      lex_match (',');
+      lex_get (lexer);
+      lex_match (lexer, ',');
     }
-  while (token != '/' && token != '.');
+  while (lex_token (lexer) != '/' && lex_token (lexer) != '.');
 
   return used;
 }
 
 int
-cmd_end_repeat (struct dataset *ds UNUSED)
+cmd_end_repeat (struct lexer *lexer UNUSED, struct dataset *ds UNUSED)
 {
   msg (SE, _("No matching DO REPEAT."));
   return CMD_CASCADING_FAILURE;

Index: language/control/temporary.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/control/temporary.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- language/control/temporary.c        26 Oct 2006 06:16:36 -0000      1.6
+++ language/control/temporary.c        11 Nov 2006 23:10:00 -0000      1.7
@@ -41,12 +41,12 @@
 
 /* Parses the TEMPORARY command. */
 int
-cmd_temporary (struct dataset *ds)
+cmd_temporary (struct lexer *lexer, struct dataset *ds)
 {
   if (!proc_in_temporary_transformations (ds))
     proc_start_temporary_transformations (ds);
   else
     msg (SE, _("This command may only appear once between "
                "procedures and procedure-like commands."));
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }

Index: language/data-io/data-list.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/data-list.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -b -r1.24 -r1.25
--- language/data-io/data-list.c        11 Nov 2006 19:30:59 -0000      1.24
+++ language/data-io/data-list.c        11 Nov 2006 23:10:00 -0000      1.25
@@ -104,9 +104,9 @@
 
 static const struct case_source_class data_list_source_class;
 
-static bool parse_fixed (struct dictionary *dict, 
+static bool parse_fixed (struct lexer *, struct dictionary *dict, 
                         struct pool *tmp_pool, struct data_list_pgm *);
-static bool parse_free (struct dictionary *dict, 
+static bool parse_free (struct lexer *, struct dictionary *dict, 
                        struct pool *tmp_pool, struct data_list_pgm *);
 static void dump_fixed_table (const struct ll_list *,
                               const struct file_handle *, int record_cnt);
@@ -117,7 +117,7 @@
 static trns_proc_func data_list_trns_proc;
 
 int
-cmd_data_list (struct dataset *ds)
+cmd_data_list (struct lexer *lexer, struct dataset *ds)
 {
   struct dictionary *dict = dataset_dict (ds);
   struct data_list_pgm *dls;
@@ -141,34 +141,34 @@
 
   tmp_pool = pool_create_subpool (dls->pool);
 
-  while (token != '/')
+  while (lex_token (lexer) != '/')
     {
-      if (lex_match_id ("FILE"))
+      if (lex_match_id (lexer, "FILE"))
        {
-         lex_match ('=');
-         fh = fh_parse (FH_REF_FILE | FH_REF_INLINE);
+         lex_match (lexer, '=');
+         fh = fh_parse (lexer, FH_REF_FILE | FH_REF_INLINE);
          if (fh == NULL)
            goto error;
        }
-      else if (lex_match_id ("RECORDS"))
+      else if (lex_match_id (lexer, "RECORDS"))
        {
-         lex_match ('=');
-         lex_match ('(');
-         if (!lex_force_int ())
+         lex_match (lexer, '=');
+         lex_match (lexer, '(');
+         if (!lex_force_int (lexer))
            goto error;
-         dls->record_cnt = lex_integer ();
-         lex_get ();
-         lex_match (')');
+         dls->record_cnt = lex_integer (lexer);
+         lex_get (lexer);
+         lex_match (lexer, ')');
        }
-      else if (lex_match_id ("SKIP"))
+      else if (lex_match_id (lexer, "SKIP"))
        {
-         lex_match ('=');
-         if (!lex_force_int ())
+         lex_match (lexer, '=');
+         if (!lex_force_int (lexer))
            goto error;
-         dls->skip_records = lex_integer ();
-         lex_get ();
+         dls->skip_records = lex_integer (lexer);
+         lex_get (lexer);
        }
-      else if (lex_match_id ("END"))
+      else if (lex_match_id (lexer, "END"))
        {
          if (dls->end)
            {
@@ -176,32 +176,32 @@
              goto error;
            }
          
-         lex_match ('=');
-         if (!lex_force_id ())
+         lex_match (lexer, '=');
+         if (!lex_force_id (lexer))
            goto error;
-         dls->end = dict_lookup_var (dataset_dict (ds), tokid);
+         dls->end = dict_lookup_var (dataset_dict (ds), lex_tokid (lexer));
          if (!dls->end) 
-            dls->end = dict_create_var_assert (dataset_dict (ds), tokid, 0);
-         lex_get ();
+            dls->end = dict_create_var_assert (dataset_dict (ds), lex_tokid 
(lexer), 0);
+         lex_get (lexer);
        }
-      else if (token == T_ID)
+      else if (lex_token (lexer) == T_ID)
        {
-          if (lex_match_id ("NOTABLE"))
+          if (lex_match_id (lexer, "NOTABLE"))
             table = 0;
-          else if (lex_match_id ("TABLE"))
+          else if (lex_match_id (lexer, "TABLE"))
             table = 1;
           else 
             {
               int type;
-              if (lex_match_id ("FIXED"))
+              if (lex_match_id (lexer, "FIXED"))
                 type = DLS_FIXED;
-              else if (lex_match_id ("FREE"))
+              else if (lex_match_id (lexer, "FREE"))
                 type = DLS_FREE;
-              else if (lex_match_id ("LIST"))
+              else if (lex_match_id (lexer, "LIST"))
                 type = DLS_LIST;
               else 
                 {
-                  lex_error (NULL);
+                  lex_error (lexer, NULL);
                   goto error;
                 }
 
@@ -214,35 +214,35 @@
              dls->type = type;
 
               if ((dls->type == DLS_FREE || dls->type == DLS_LIST)
-                  && lex_match ('(')) 
+                  && lex_match (lexer, '(')) 
                 {
-                  while (!lex_match (')'))
+                  while (!lex_match (lexer, ')'))
                     {
                       int delim;
 
-                      if (lex_match_id ("TAB"))
+                      if (lex_match_id (lexer, "TAB"))
                         delim = '\t';
-                      else if (token == T_STRING && ds_length (&tokstr) == 1)
+                      else if (lex_token (lexer) == T_STRING && ds_length 
(lex_tokstr (lexer)) == 1)
                        {
-                         delim = ds_first (&tokstr);
-                         lex_get ();
+                         delim = ds_first (lex_tokstr (lexer));
+                         lex_get (lexer);
                        }
                       else 
                         {
-                          lex_error (NULL);
+                          lex_error (lexer, NULL);
                           goto error;
                         }
 
                       ds_put_char (&dls->delims, delim);
 
-                      lex_match (',');
+                      lex_match (lexer, ',');
                     }
                 }
             }
         }
       else
        {
-         lex_error (NULL);
+         lex_error (lexer, NULL);
          goto error;
        }
     }
@@ -255,11 +255,11 @@
   if (table == -1)
     table = dls->type != DLS_FREE;
 
-  ok = (dls->type == DLS_FIXED ? parse_fixed : parse_free) (dict, tmp_pool, 
dls);
+  ok = (dls->type == DLS_FIXED ? parse_fixed : parse_free) (lexer, dict, 
tmp_pool, dls);
   if (!ok)
     goto error;
 
-  if (lex_end_of_command () != CMD_SUCCESS)
+  if (lex_end_of_command (lexer) != CMD_SUCCESS)
     goto error;
 
   if (table)
@@ -270,7 +270,7 @@
        dump_free_table (dls, fh);
     }
 
-  dls->reader = dfm_open_reader (fh);
+  dls->reader = dfm_open_reader (fh, lexer);
   if (dls->reader == NULL)
     goto error;
 
@@ -295,14 +295,14 @@
    needed once parsing is complete.  Returns true only if
    successful. */
 static bool
-parse_fixed (struct dictionary *dict, 
+parse_fixed (struct lexer *lexer, struct dictionary *dict, 
             struct pool *tmp_pool, struct data_list_pgm *dls)
 {
   int last_nonempty_record;
   int record = 0;
   int column = 1;
 
-  while (token != '.')
+  while (lex_token (lexer) != '.')
     {
       char **names;
       size_t name_cnt, name_idx;
@@ -310,9 +310,10 @@
       size_t format_cnt;
 
       /* Parse everything. */
-      if (!parse_record_placement (&record, &column)
-          || !parse_DATA_LIST_vars_pool (tmp_pool, &names, &name_cnt, PV_NONE)
-          || !parse_var_placements (tmp_pool, name_cnt, true,
+      if (!parse_record_placement (lexer, &record, &column)
+          || !parse_DATA_LIST_vars_pool (lexer, tmp_pool, 
+                                        &names, &name_cnt, PV_NONE)
+          || !parse_var_placements (lexer, tmp_pool, name_cnt, true,
                                     &formats, &format_cnt))
         return false;
 
@@ -447,30 +448,32 @@
    them to DLS.  Uses TMP_POOL for data that is not needed once
    parsing is complete.  Returns true only if successful. */
 static bool
-parse_free (struct dictionary *dict, struct pool *tmp_pool, struct 
data_list_pgm *dls)
+parse_free (struct lexer *lexer, struct dictionary *dict, struct pool 
*tmp_pool, 
+               struct data_list_pgm *dls)
 {
-  lex_get ();
-  while (token != '.')
+  lex_get (lexer);
+  while (lex_token (lexer) != '.')
     {
       struct fmt_spec input, output;
       char **name;
       size_t name_cnt;
       size_t i;
 
-      if (!parse_DATA_LIST_vars_pool (tmp_pool, &name, &name_cnt, PV_NONE))
+      if (!parse_DATA_LIST_vars_pool (lexer, tmp_pool, 
+                                     &name, &name_cnt, PV_NONE))
        return 0;
 
-      if (lex_match ('('))
+      if (lex_match (lexer, '('))
        {
-         if (!parse_format_specifier (&input)
+         if (!parse_format_specifier (lexer, &input)
               || !fmt_check_input (&input)
-              || !lex_force_match (')')) 
+              || !lex_force_match (lexer, ')')) 
             return NULL;
          output = fmt_for_output_from_input (&input);
        }
       else
        {
-         lex_match ('*');
+         lex_match (lexer, '*');
           input = fmt_for_input (FMT_F, 8, 0);
          output = *get_format ();
        }

Index: language/data-io/data-reader.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/data-reader.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- language/data-io/data-reader.c      28 Oct 2006 08:31:23 -0000      1.15
+++ language/data-io/data-reader.c      11 Nov 2006 23:10:00 -0000      1.16
@@ -64,6 +64,7 @@
     FILE *file;                 /* Associated file. */
     size_t pos;                 /* Offset in line of current character. */
     unsigned eof_cnt;           /* # of attempts to advance past EOF. */
+    struct lexer *lexer;        /* The lexer reading the file */
   };
 
 /* Closes reader R opened by dfm_open_reader(). */
@@ -111,7 +112,7 @@
    file between BEGIN FILE and END FILE.  Returns a reader if
    successful, or a null pointer otherwise. */
 struct dfm_reader *
-dfm_open_reader (struct file_handle *fh)
+dfm_open_reader (struct file_handle *fh, struct lexer *lexer)
 {
   struct dfm_reader *r;
   void **rp;
@@ -124,6 +125,7 @@
   
   r = xmalloc (sizeof *r);
   r->fh = fh;
+  r->lexer = lexer ;
   ds_init_empty (&r->line);
   ds_init_empty (&r->scratch);
   r->flags = DFM_ADVANCE;
@@ -163,14 +165,14 @@
     {
       r->flags |= DFM_SAW_BEGIN_DATA;
 
-      while (token == '.')
-        lex_get ();
-      if (!lex_force_match_id ("BEGIN") || !lex_force_match_id ("DATA"))
+      while (lex_token (r->lexer) == '.')
+        lex_get (r->lexer);
+      if (!lex_force_match_id (r->lexer, "BEGIN") || !lex_force_match_id 
(r->lexer, "DATA"))
         return false;
       getl_set_prompt_style (GETL_PROMPT_DATA);
     }
       
-  if (!lex_get_line_raw ())
+  if (!lex_get_line_raw (r->lexer))
     {
       msg (SE, _("Unexpected end-of-file while reading data in BEGIN "
                  "DATA.  This probably indicates "
@@ -180,14 +182,14 @@
       return false;
     }
 
-  if (ds_length (lex_entire_line_ds() ) >= 8
-      && !strncasecmp (lex_entire_line (), "end data", 8))
+  if (ds_length (lex_entire_line_ds (r->lexer) ) >= 8
+      && !strncasecmp (lex_entire_line (r->lexer), "end data", 8))
     {
-      lex_discard_line ();
+      lex_discard_line (r->lexer);
       return false;
     }
 
-  ds_assign_string (&r->line, lex_entire_line_ds () );
+  ds_assign_string (&r->line, lex_entire_line_ds (r->lexer) );
 
   return true;
 }
@@ -260,7 +262,7 @@
     {
       r->flags &= ~DFM_ADVANCE;
 
-      if (r->eof_cnt == 0 && read_record (r)) 
+      if (r->eof_cnt == 0 && read_record (r) ) 
         {
           r->pos = 0;
           return 0; 
@@ -424,7 +426,7 @@
 
 /* Perform BEGIN DATA...END DATA as a procedure in itself. */
 int
-cmd_begin_data (struct dataset *ds)
+cmd_begin_data (struct lexer *lexer, struct dataset *ds)
 {
   struct dfm_reader *r;
   bool ok;
@@ -437,7 +439,7 @@
     }
 
   /* Open inline file. */
-  r = dfm_open_reader (fh_inline_file ());
+  r = dfm_open_reader (fh_inline_file (), lexer);
   r->flags |= DFM_SAW_BEGIN_DATA;
 
   /* Input procedure reads from inline file. */

Index: language/data-io/data-reader.h
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/data-reader.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- language/data-io/data-reader.h      9 Jun 2006 22:51:24 -0000       1.2
+++ language/data-io/data-reader.h      11 Nov 2006 23:10:00 -0000      1.3
@@ -31,9 +31,10 @@
 
 struct file_handle;
 struct string;
+struct lexer;
 
 /* Input. */
-struct dfm_reader *dfm_open_reader (struct file_handle *);
+struct dfm_reader *dfm_open_reader (struct file_handle *, struct lexer *);
 void dfm_close_reader (struct dfm_reader *);
 bool dfm_reader_error (const struct dfm_reader *);
 unsigned dfm_eof (struct dfm_reader *);

Index: language/data-io/file-handle.h
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/file-handle.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- language/data-io/file-handle.h      15 Mar 2006 03:29:10 -0000      1.2
+++ language/data-io/file-handle.h      11 Nov 2006 23:10:00 -0000      1.3
@@ -26,6 +26,7 @@
 #include <stddef.h>
 #include <data/file-handle-def.h>
 
-struct file_handle *fh_parse (enum fh_referent);
+struct lexer ;
+struct file_handle *fh_parse (struct lexer *, enum fh_referent);
 
 #endif /* !file_handle.h */

Index: language/data-io/file-handle.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/file-handle.q,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- language/data-io/file-handle.q      26 Oct 2006 06:16:36 -0000      1.8
+++ language/data-io/file-handle.q      11 Nov 2006 23:10:00 -0000      1.9
@@ -51,7 +51,7 @@
 /* (functions) */
 
 int
-cmd_file_handle (struct dataset *ds)
+cmd_file_handle (struct lexer *lexer, struct dataset *ds)
 {
   char handle_name[LONG_NAME_LEN + 1];
   struct fh_properties properties = *fh_default_properties ();
@@ -59,9 +59,9 @@
   struct cmd_file_handle cmd;
   struct file_handle *handle;
 
-  if (!lex_force_id ())
+  if (!lex_force_id (lexer))
     return CMD_CASCADING_FAILURE;
-  str_copy_trunc (handle_name, sizeof handle_name, tokid);
+  str_copy_trunc (handle_name, sizeof handle_name, lex_tokid (lexer));
 
   handle = fh_from_name (handle_name);
   if (handle != NULL)
@@ -72,19 +72,19 @@
       return CMD_CASCADING_FAILURE;
     }
 
-  lex_get ();
-  if (!lex_force_match ('/'))
+  lex_get (lexer);
+  if (!lex_force_match (lexer, '/'))
     return CMD_CASCADING_FAILURE;
 
-  if (!parse_file_handle (ds, &cmd, NULL))
+  if (!parse_file_handle (lexer, ds, &cmd, NULL))
     return CMD_CASCADING_FAILURE;
 
-  if (lex_end_of_command () != CMD_SUCCESS)
+  if (lex_end_of_command (lexer) != CMD_SUCCESS)
     goto lossage;
 
   if (cmd.s_name == NULL && cmd.mode != FH_SCRATCH)
     {
-      lex_sbc_missing ("NAME");
+      lex_sbc_missing (lexer, "NAME");
       goto lossage;
     }
 
@@ -127,13 +127,13 @@
 }
 
 int
-cmd_close_file_handle (struct dataset *ds UNUSED) 
+cmd_close_file_handle (struct lexer *lexer, struct dataset *ds UNUSED) 
 {
   struct file_handle *handle;
 
-  if (!lex_force_id ())
+  if (!lex_force_id (lexer))
     return CMD_CASCADING_FAILURE;
-  handle = fh_from_name (tokid);
+  handle = fh_from_name (lex_tokid (lexer));
   if (handle == NULL)
     return CMD_CASCADING_FAILURE;
 
@@ -164,39 +164,39 @@
    file handle are restricted to those in REFERENT_MASK.  Returns
    the file handle when successful, a null pointer on failure. */
 struct file_handle *
-fh_parse (enum fh_referent referent_mask)
+fh_parse (struct lexer *lexer, enum fh_referent referent_mask)
 {
   struct file_handle *handle;
 
-  if (lex_match_id ("INLINE")) 
+  if (lex_match_id (lexer, "INLINE")) 
     handle = fh_inline_file ();
   else 
     {
-      if (token != T_ID && token != T_STRING)
+      if (lex_token (lexer) != T_ID && lex_token (lexer) != T_STRING)
         {
-          lex_error (_("expecting a file name or handle name"));
+          lex_error (lexer, _("expecting a file name or handle name"));
           return NULL;
         }
 
       handle = NULL;
-      if (token == T_ID) 
-        handle = fh_from_name (tokid);
+      if (lex_token (lexer) == T_ID) 
+        handle = fh_from_name (lex_tokid (lexer));
       if (handle == NULL) 
-        handle = fh_from_file_name (ds_cstr (&tokstr)); 
+        handle = fh_from_file_name (ds_cstr (lex_tokstr (lexer))); 
       if (handle == NULL)
         {
-          if (token != T_ID || tokid[0] != '#' || get_syntax () != ENHANCED) 
+          if (lex_token (lexer) != T_ID || lex_tokid (lexer)[0] != '#' || 
get_syntax () != ENHANCED) 
             {
-              char *file_name = ds_cstr (&tokstr);
+              char *file_name = ds_cstr (lex_tokstr (lexer));
               char *handle_name = xasprintf ("\"%s\"", file_name);
               handle = fh_create_file (handle_name, file_name,
                                        fh_default_properties ());
               free (handle_name);
             }
           else
-            handle = fh_create_scratch (tokid);
+            handle = fh_create_scratch (lex_tokid (lexer));
         }
-      lex_get ();
+      lex_get (lexer);
     }
 
   if (!(fh_get_referent (handle) & referent_mask)) 

Index: language/data-io/get.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/get.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- language/data-io/get.c      3 Nov 2006 04:53:51 -0000       1.20
+++ language/data-io/get.c      11 Nov 2006 23:10:00 -0000      1.21
@@ -60,7 +60,7 @@
                       const struct ccase *, struct ccase *);
 static void destroy_case_map (struct case_map *);
 
-static bool parse_dict_trim (struct dictionary *);
+static bool parse_dict_trim (struct lexer *, struct dictionary *);
 
 /* Reading system and portable files. */
 
@@ -85,7 +85,7 @@
 
 /* Parses a GET or IMPORT command. */
 static int
-parse_read_command (struct dataset *ds, enum reader_command type)
+parse_read_command (struct lexer *lexer, struct dataset *ds, enum 
reader_command type)
 {
   struct case_reader_pgm *pgm = NULL;
   struct file_handle *fh = NULL;
@@ -93,27 +93,27 @@
 
   for (;;)
     {
-      lex_match ('/');
+      lex_match (lexer, '/');
 
-      if (lex_match_id ("FILE") || token == T_STRING)
+      if (lex_match_id (lexer, "FILE") || lex_token (lexer) == T_STRING)
        {
-         lex_match ('=');
+         lex_match (lexer, '=');
 
-         fh = fh_parse (FH_REF_FILE | FH_REF_SCRATCH);
+         fh = fh_parse (lexer, FH_REF_FILE | FH_REF_SCRATCH);
          if (fh == NULL)
             goto error;
        }
-      else if (type == IMPORT_CMD && lex_match_id ("TYPE"))
+      else if (type == IMPORT_CMD && lex_match_id (lexer, "TYPE"))
        {
-         lex_match ('=');
+         lex_match (lexer, '=');
 
-         if (lex_match_id ("COMM"))
+         if (lex_match_id (lexer, "COMM"))
            type = PFM_COMM;
-         else if (lex_match_id ("TAPE"))
+         else if (lex_match_id (lexer, "TAPE"))
            type = PFM_TAPE;
          else
            {
-             lex_error (_("expecting COMM or TAPE"));
+             lex_error (lexer, _("expecting COMM or TAPE"));
               goto error;
            }
        }
@@ -123,7 +123,7 @@
   
   if (fh == NULL) 
     {
-      lex_sbc_missing ("FILE");
+      lex_sbc_missing (lexer, "FILE");
       goto error;
     }
               
@@ -140,10 +140,10 @@
   
   start_case_map (dict);
 
-  while (token != '.')
+  while (lex_token (lexer) != '.')
     {
-      lex_match ('/');
-      if (!parse_dict_trim (dict))
+      lex_match (lexer, '/');
+      if (!parse_dict_trim (lexer, dict))
         goto error;
     }
 
@@ -227,16 +227,16 @@
 
 /* GET. */
 int
-cmd_get (struct dataset *ds) 
+cmd_get (struct lexer *lexer, struct dataset *ds) 
 {
-  return parse_read_command (ds, GET_CMD);
+  return parse_read_command (lexer, ds, GET_CMD);
 }
 
 /* IMPORT. */
 int
-cmd_import (struct dataset *ds) 
+cmd_import (struct lexer *lexer, struct dataset *ds) 
 {
-  return parse_read_command (ds, IMPORT_CMD);
+  return parse_read_command (lexer, ds, IMPORT_CMD);
 }
 
 /* Writing system and portable files. */ 
@@ -290,7 +290,7 @@
 
    On failure, returns a null pointer. */
 static struct case_writer *
-parse_write_command (struct dataset *ds, 
+parse_write_command (struct lexer *lexer, struct dataset *ds, 
                     enum writer_type writer_type,
                      enum command_type command_type,
                      bool *retain_unselected)
@@ -327,10 +327,10 @@
   start_case_map (dict);
   dict_delete_scratch_vars (dict);
 
-  lex_match ('/');
+  lex_match (lexer, '/');
   for (;;)
     {
-      if (lex_match_id ("OUTFILE"))
+      if (lex_match_id (lexer, "OUTFILE"))
        {
           if (handle != NULL) 
             {
@@ -338,88 +338,88 @@
               goto error; 
             }
           
-         lex_match ('=');
+         lex_match (lexer, '=');
       
-         handle = fh_parse (FH_REF_FILE | FH_REF_SCRATCH);
+         handle = fh_parse (lexer, FH_REF_FILE | FH_REF_SCRATCH);
          if (handle == NULL)
            goto error;
        }
-      else if (lex_match_id ("NAMES"))
+      else if (lex_match_id (lexer, "NAMES"))
         print_short_names = true;
-      else if (lex_match_id ("PERMISSIONS")) 
+      else if (lex_match_id (lexer, "PERMISSIONS")) 
         {
           bool cw;
           
-          lex_match ('=');
-          if (lex_match_id ("READONLY"))
+          lex_match (lexer, '=');
+          if (lex_match_id (lexer, "READONLY"))
             cw = false;
-          else if (lex_match_id ("WRITEABLE"))
+          else if (lex_match_id (lexer, "WRITEABLE"))
             cw = true;
           else
             {
-              lex_error (_("expecting %s or %s"), "READONLY", "WRITEABLE");
+              lex_error (lexer, _("expecting %s or %s"), "READONLY", 
"WRITEABLE");
               goto error;
             }
           sysfile_opts.create_writeable = porfile_opts.create_writeable = cw;
         }
-      else if (command_type == PROC_CMD && lex_match_id ("UNSELECTED")) 
+      else if (command_type == PROC_CMD && lex_match_id (lexer, "UNSELECTED")) 
         {
-          lex_match ('=');
-          if (lex_match_id ("RETAIN"))
+          lex_match (lexer, '=');
+          if (lex_match_id (lexer, "RETAIN"))
             *retain_unselected = true;
-          else if (lex_match_id ("DELETE"))
+          else if (lex_match_id (lexer, "DELETE"))
             *retain_unselected = false;
           else
             {
-              lex_error (_("expecting %s or %s"), "RETAIN", "DELETE");
+              lex_error (lexer, _("expecting %s or %s"), "RETAIN", "DELETE");
               goto error;
             }
         }
-      else if (writer_type == SYSFILE_WRITER && lex_match_id ("COMPRESSED"))
+      else if (writer_type == SYSFILE_WRITER && lex_match_id (lexer, 
"COMPRESSED"))
        sysfile_opts.compress = true;
-      else if (writer_type == SYSFILE_WRITER && lex_match_id ("UNCOMPRESSED"))
+      else if (writer_type == SYSFILE_WRITER && lex_match_id (lexer, 
"UNCOMPRESSED"))
        sysfile_opts.compress = false;
-      else if (writer_type == SYSFILE_WRITER && lex_match_id ("VERSION"))
+      else if (writer_type == SYSFILE_WRITER && lex_match_id (lexer, 
"VERSION"))
        {
-         lex_match ('=');
-         if (!lex_force_int ())
+         lex_match (lexer, '=');
+         if (!lex_force_int (lexer))
             goto error;
-          sysfile_opts.version = lex_integer ();
-          lex_get ();
+          sysfile_opts.version = lex_integer (lexer);
+          lex_get (lexer);
        }
-      else if (writer_type == PORFILE_WRITER && lex_match_id ("TYPE")) 
+      else if (writer_type == PORFILE_WRITER && lex_match_id (lexer, "TYPE")) 
         {
-          lex_match ('=');
-          if (lex_match_id ("COMMUNICATIONS"))
+          lex_match (lexer, '=');
+          if (lex_match_id (lexer, "COMMUNICATIONS"))
             porfile_opts.type = PFM_COMM;
-          else if (lex_match_id ("TAPE"))
+          else if (lex_match_id (lexer, "TAPE"))
             porfile_opts.type = PFM_TAPE;
           else
             {
-              lex_error (_("expecting %s or %s"), "COMM", "TAPE");
+              lex_error (lexer, _("expecting %s or %s"), "COMM", "TAPE");
               goto error;
             }
         }
-      else if (writer_type == PORFILE_WRITER && lex_match_id ("DIGITS")) 
+      else if (writer_type == PORFILE_WRITER && lex_match_id (lexer, 
"DIGITS")) 
         {
-          lex_match ('=');
-          if (!lex_force_int ())
+          lex_match (lexer, '=');
+          if (!lex_force_int (lexer))
             goto error;
-          porfile_opts.digits = lex_integer ();
-          lex_get ();
+          porfile_opts.digits = lex_integer (lexer);
+          lex_get (lexer);
         }
-      else if (!parse_dict_trim (dict))
+      else if (!parse_dict_trim (lexer, dict))
         goto error;
       
-      if (!lex_match ('/'))
+      if (!lex_match (lexer, '/'))
        break;
     }
-  if (lex_end_of_command () != CMD_SUCCESS)
+  if (lex_end_of_command (lexer) != CMD_SUCCESS)
     goto error;
 
   if (handle == NULL) 
     {
-      lex_sbc_missing ("OUTFILE");
+      lex_sbc_missing (lexer, "OUTFILE");
       goto error;
     }
 
@@ -474,14 +474,14 @@
 
 /* Parses and performs the SAVE or EXPORT procedure. */
 static int
-parse_output_proc (struct dataset *ds, enum writer_type writer_type)
+parse_output_proc (struct lexer *lexer, struct dataset *ds, enum writer_type 
writer_type)
 {
   bool retain_unselected;
   struct variable *saved_filter_variable;
   struct case_writer *aw;
   bool ok;
 
-  aw = parse_write_command (ds, writer_type, PROC_CMD, &retain_unselected);
+  aw = parse_write_command (lexer, ds, writer_type, PROC_CMD, 
&retain_unselected);
   if (aw == NULL) 
     return CMD_CASCADING_FAILURE;
 
@@ -504,15 +504,15 @@
 }
 
 int
-cmd_save (struct dataset *ds) 
+cmd_save (struct lexer *lexer, struct dataset *ds) 
 {
-  return parse_output_proc (ds, SYSFILE_WRITER);
+  return parse_output_proc (lexer, ds, SYSFILE_WRITER);
 }
 
 int
-cmd_export (struct dataset *ds) 
+cmd_export (struct lexer *lexer, struct dataset *ds) 
 {
-  return parse_output_proc (ds, PORFILE_WRITER);
+  return parse_output_proc (lexer, ds, PORFILE_WRITER);
 }
 
 /* XSAVE and XEXPORT. */
@@ -528,10 +528,10 @@
 
 /* Parses the XSAVE or XEXPORT transformation command. */
 static int
-parse_output_trns (struct dataset *ds, enum writer_type writer_type) 
+parse_output_trns (struct lexer *lexer, struct dataset *ds, enum writer_type 
writer_type) 
 {
   struct output_trns *t = xmalloc (sizeof *t);
-  t->aw = parse_write_command (ds, writer_type, XFORM_CMD, NULL);
+  t->aw = parse_write_command (lexer, ds, writer_type, XFORM_CMD, NULL);
   if (t->aw == NULL) 
     {
       free (t);
@@ -569,50 +569,50 @@
 
 /* XSAVE command. */
 int
-cmd_xsave (struct dataset *ds) 
+cmd_xsave (struct lexer *lexer, struct dataset *ds) 
 {
-  return parse_output_trns (ds, SYSFILE_WRITER);
+  return parse_output_trns (lexer, ds, SYSFILE_WRITER);
 }
 
 /* XEXPORT command. */
 int
-cmd_xexport (struct dataset *ds) 
+cmd_xexport (struct lexer *lexer, struct dataset *ds) 
 {
-  return parse_output_trns (ds, PORFILE_WRITER);
+  return parse_output_trns (lexer, ds, PORFILE_WRITER);
 }
 
-static bool rename_variables (struct dictionary *dict);
-static bool drop_variables (struct dictionary *dict);
-static bool keep_variables (struct dictionary *dict);
+static bool rename_variables (struct lexer *lexer, struct dictionary *dict);
+static bool drop_variables (struct lexer *, struct dictionary *dict);
+static bool keep_variables (struct lexer *, struct dictionary *dict);
 
 /* Commands that read and write system files share a great deal
    of common syntactic structure for rearranging and dropping
    variables.  This function parses this syntax and modifies DICT
    appropriately.  Returns true on success, false on failure. */
 static bool
-parse_dict_trim (struct dictionary *dict)
+parse_dict_trim (struct lexer *lexer, struct dictionary *dict)
 {
-  if (lex_match_id ("MAP")) 
+  if (lex_match_id (lexer, "MAP")) 
     {
       /* FIXME. */
       return true;
     }
-  else if (lex_match_id ("DROP"))
-    return drop_variables (dict);
-  else if (lex_match_id ("KEEP"))
-    return keep_variables (dict);
-  else if (lex_match_id ("RENAME"))
-    return rename_variables (dict);
+  else if (lex_match_id (lexer, "DROP"))
+    return drop_variables (lexer, dict);
+  else if (lex_match_id (lexer, "KEEP"))
+    return keep_variables (lexer, dict);
+  else if (lex_match_id (lexer, "RENAME"))
+    return rename_variables (lexer, dict);
   else
     {
-      lex_error (_("expecting a valid subcommand"));
+      lex_error (lexer, _("expecting a valid subcommand"));
       return false;
     }
 }
 
 /* Parses and performs the RENAME subcommand of GET and SAVE. */
 static bool
-rename_variables (struct dictionary *dict)
+rename_variables (struct lexer *lexer, struct dictionary *dict)
 {
   size_t i;
 
@@ -625,29 +625,29 @@
 
   int group;
 
-  lex_match ('=');
-  if (token != '(')
+  lex_match (lexer, '=');
+  if (lex_token (lexer) != '(')
     {
       struct variable *v;
 
-      v = parse_variable (dict);
+      v = parse_variable (lexer, dict);
       if (v == NULL)
        return 0;
-      if (!lex_force_match ('=')
-         || !lex_force_id ())
+      if (!lex_force_match (lexer, '=')
+         || !lex_force_id (lexer))
        return 0;
-      if (dict_lookup_var (dict, tokid) != NULL)
+      if (dict_lookup_var (dict, lex_tokid (lexer)) != NULL)
        {
          msg (SE, _("Cannot rename %s as %s because there already exists "
                     "a variable named %s.  To rename variables with "
                     "overlapping names, use a single RENAME subcommand "
                     "such as \"/RENAME (A=B)(B=C)(C=A)\", or equivalently, "
-                    "\"/RENAME (A B C=B C A)\"."), v->name, tokid, tokid);
+                    "\"/RENAME (A B C=B C A)\"."), v->name, lex_tokid (lexer), 
lex_tokid (lexer));
          return 0;
        }
       
-      dict_rename_var (dict, v, tokid);
-      lex_get ();
+      dict_rename_var (dict, v, lex_tokid (lexer));
+      lex_get (lexer);
       return 1;
     }
 
@@ -655,18 +655,18 @@
   v = NULL;
   new_names = 0;
   group = 1;
-  while (lex_match ('('))
+  while (lex_match (lexer, '('))
     {
       size_t old_nv = nv;
 
-      if (!parse_variables (dict, &v, &nv, PV_NO_DUPLICATE | PV_APPEND))
+      if (!parse_variables (lexer, dict, &v, &nv, PV_NO_DUPLICATE | PV_APPEND))
        goto done;
-      if (!lex_match ('='))
+      if (!lex_match (lexer, '='))
        {
          msg (SE, _("`=' expected after variable list."));
          goto done;
        }
-      if (!parse_DATA_LIST_vars (&new_names, &nn, PV_APPEND | PV_NO_SCRATCH))
+      if (!parse_DATA_LIST_vars (lexer, &new_names, &nn, PV_APPEND | 
PV_NO_SCRATCH))
        goto done;
       if (nn != nv)
        {
@@ -676,7 +676,7 @@
               (unsigned) (nv - old_nv), (unsigned) (nn - old_nv), group);
          goto done;
        }
-      if (!lex_force_match (')'))
+      if (!lex_force_match (lexer, ')'))
        goto done;
       group++;
     }
@@ -700,13 +700,13 @@
 /* Parses and performs the DROP subcommand of GET and SAVE.
    Returns true if successful, false on failure.*/
 static bool
-drop_variables (struct dictionary *dict)
+drop_variables (struct lexer *lexer, struct dictionary *dict)
 {
   struct variable **v;
   size_t nv;
 
-  lex_match ('=');
-  if (!parse_variables (dict, &v, &nv, PV_NONE))
+  lex_match (lexer, '=');
+  if (!parse_variables (lexer, dict, &v, &nv, PV_NONE))
     return false;
   dict_delete_vars (dict, v, nv);
   free (v);
@@ -722,14 +722,14 @@
 /* Parses and performs the KEEP subcommand of GET and SAVE.
    Returns true if successful, false on failure.*/
 static bool
-keep_variables (struct dictionary *dict)
+keep_variables (struct lexer *lexer, struct dictionary *dict)
 {
   struct variable **v;
   size_t nv;
   size_t i;
 
-  lex_match ('=');
-  if (!parse_variables (dict, &v, &nv, PV_NONE))
+  lex_match (lexer, '=');
+  if (!parse_variables (lexer, dict, &v, &nv, PV_NONE))
     return false;
 
   /* Move the specified variables to the beginning. */
@@ -810,7 +810,7 @@
 
 /* Parse and execute the MATCH FILES command. */
 int
-cmd_match_files (struct dataset *ds)
+cmd_match_files (struct lexer *lexer, struct dataset *ds)
 {
   struct mtf_proc mtf;
   struct mtf_file *first_table = NULL;
@@ -833,22 +833,22 @@
   mtf.seq_nums = NULL;
   dict_set_case_limit (mtf.dict, dict_get_case_limit (dataset_dict (ds)));
 
-  lex_match ('/');
-  while (token == T_ID
-         && (lex_id_match ("FILE", tokid) || lex_id_match ("TABLE", tokid)))
+  lex_match (lexer, '/');
+  while (lex_token (lexer) == T_ID
+         && (lex_id_match ("FILE", lex_tokid (lexer)) || lex_id_match 
("TABLE", lex_tokid (lexer))))
     {
       struct mtf_file *file = xmalloc (sizeof *file);
 
-      if (lex_match_id ("FILE"))
+      if (lex_match_id (lexer, "FILE"))
         file->type = MTF_FILE;
-      else if (lex_match_id ("TABLE"))
+      else if (lex_match_id (lexer, "TABLE"))
         {
           file->type = MTF_TABLE;
           saw_table = true;
         }
       else
         NOT_REACHED ();
-      lex_match ('=');
+      lex_match (lexer, '=');
 
       file->by = NULL;
       file->handle = NULL;
@@ -883,7 +883,7 @@
           first_table->prev = file;
         }
 
-      if (lex_match ('*'))
+      if (lex_match (lexer, '*'))
         {
           file->handle = NULL;
           file->reader = NULL;
@@ -913,7 +913,7 @@
         }
       else
         {
-          file->handle = fh_parse (FH_REF_FILE | FH_REF_SCRATCH);
+          file->handle = fh_parse (lexer, FH_REF_FILE | FH_REF_SCRATCH);
           if (file->handle == NULL)
             goto error;
 
@@ -924,18 +924,18 @@
           case_create (&file->input, dict_get_next_value_idx (file->dict));
         }
 
-      while (lex_match ('/'))
-        if (lex_match_id ("RENAME")) 
+      while (lex_match (lexer, '/'))
+        if (lex_match_id (lexer, "RENAME")) 
           {
-            if (!rename_variables (file->dict))
+            if (!rename_variables (lexer, file->dict))
               goto error; 
           }
-        else if (lex_match_id ("IN"))
+        else if (lex_match_id (lexer, "IN"))
           {
-            lex_match ('=');
-            if (token != T_ID)
+            lex_match (lexer, '=');
+            if (lex_token (lexer) != T_ID)
               {
-                lex_error (NULL);
+                lex_error (lexer, NULL);
                 goto error;
               }
 
@@ -945,17 +945,17 @@
                            "TABLE."));
                 goto error;
               }
-            file->in_name = xstrdup (tokid);
-            lex_get ();
+            file->in_name = xstrdup (lex_tokid (lexer));
+            lex_get (lexer);
             saw_in = true;
           }
 
       mtf_merge_dictionary (mtf.dict, file);
     }
   
-  while (token != '.')
+  while (lex_token (lexer) != '.')
     {
-      if (lex_match (T_BY))
+      if (lex_match (lexer, T_BY))
        {
           struct variable **by;
           
@@ -965,8 +965,8 @@
              goto error;
            }
              
-         lex_match ('=');
-         if (!parse_variables (mtf.dict, &by, &mtf.by_cnt,
+         lex_match (lexer, '=');
+         if (!parse_variables (lexer, mtf.dict, &by, &mtf.by_cnt,
                                PV_NO_DUPLICATE | PV_NO_SCRATCH))
            goto error;
 
@@ -991,7 +991,7 @@
             }
           free (by);
        }
-      else if (lex_match_id ("FIRST")) 
+      else if (lex_match_id (lexer, "FIRST")) 
         {
           if (mtf.first[0] != '\0')
             {
@@ -999,13 +999,13 @@
               goto error;
             }
              
-         lex_match ('=');
-          if (!lex_force_id ())
+         lex_match (lexer, '=');
+          if (!lex_force_id (lexer))
             goto error;
-          strcpy (mtf.first, tokid);
-          lex_get ();
+          strcpy (mtf.first, lex_tokid (lexer));
+          lex_get (lexer);
         }
-      else if (lex_match_id ("LAST")) 
+      else if (lex_match_id (lexer, "LAST")) 
         {
           if (mtf.last[0] != '\0')
             {
@@ -1013,35 +1013,35 @@
               goto error;
             }
              
-         lex_match ('=');
-          if (!lex_force_id ())
+         lex_match (lexer, '=');
+          if (!lex_force_id (lexer))
             goto error;
-          strcpy (mtf.last, tokid);
-          lex_get ();
+          strcpy (mtf.last, lex_tokid (lexer));
+          lex_get (lexer);
         }
-      else if (lex_match_id ("MAP"))
+      else if (lex_match_id (lexer, "MAP"))
        {
          /* FIXME. */
        }
-      else if (lex_match_id ("DROP")) 
+      else if (lex_match_id (lexer, "DROP")) 
         {
-          if (!drop_variables (mtf.dict))
+          if (!drop_variables (lexer, mtf.dict))
             goto error;
         }
-      else if (lex_match_id ("KEEP")) 
+      else if (lex_match_id (lexer, "KEEP")) 
         {
-          if (!keep_variables (mtf.dict))
+          if (!keep_variables (lexer, mtf.dict))
             goto error;
         }
       else
        {
-         lex_error (NULL);
+         lex_error (lexer, NULL);
          goto error;
        }
 
-      if (!lex_match ('/') && token != '.') 
+      if (!lex_match (lexer, '/') && lex_token (lexer) != '.') 
         {
-          lex_end_of_command ();
+          lex_end_of_command (lexer);
           goto error;
         }
     }

Index: language/data-io/inpt-pgm.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/inpt-pgm.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -b -r1.16 -r1.17
--- language/data-io/inpt-pgm.c 26 Oct 2006 06:16:36 -0000      1.16
+++ language/data-io/inpt-pgm.c 11 Nov 2006 23:10:00 -0000      1.17
@@ -103,15 +103,15 @@
 }
 
 int
-cmd_input_program (struct dataset *ds)
+cmd_input_program (struct lexer *lexer, struct dataset *ds)
 {
   struct input_program_pgm *inp;
   size_t i;
   bool saw_END_CASE = false;
 
   discard_variables (ds);
-  if (token != '.')
-    return lex_end_of_command ();
+  if (lex_token (lexer) != '.')
+    return lex_end_of_command (lexer);
 
   inp = xmalloc (sizeof *inp);
   inp->trns_chain = NULL;
@@ -120,7 +120,7 @@
   inside_input_program = true;
   for (;;) 
     {
-      enum cmd_result result = cmd_parse (ds, CMD_STATE_INPUT_PROGRAM);
+      enum cmd_result result = cmd_parse (lexer, ds, CMD_STATE_INPUT_PROGRAM);
       if (result == CMD_END_INPUT_PROGRAM)
         break;
       else if (result == CMD_END_CASE) 
@@ -181,7 +181,7 @@
 }
 
 int
-cmd_end_input_program (struct dataset *ds UNUSED)
+cmd_end_input_program (struct lexer *lexer UNUSED, struct dataset *ds UNUSED)
 {
   assert (in_input_program ());
   return CMD_END_INPUT_PROGRAM; 
@@ -288,12 +288,12 @@
   };
 
 int
-cmd_end_case (struct dataset *ds UNUSED)
+cmd_end_case (struct lexer *lexer, struct dataset *ds UNUSED)
 {
   assert (in_input_program ());
-  if (token == '.')
+  if (lex_token (lexer) == '.')
     return CMD_END_CASE;
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Sends the current case as the source's output. */
@@ -319,7 +319,7 @@
 
 /* Parses REREAD command. */
 int
-cmd_reread (struct dataset *ds)
+cmd_reread (struct lexer *lexer, struct dataset *ds)
 {
   struct file_handle *fh;       /* File to be re-read. */
   struct expression *e;         /* Expression for column to set. */
@@ -327,11 +327,11 @@
 
   fh = fh_get_default_handle ();
   e = NULL;
-  while (token != '.')
+  while (lex_token (lexer) != '.')
     {
-      if (lex_match_id ("COLUMN"))
+      if (lex_match_id (lexer, "COLUMN"))
        {
-         lex_match ('=');
+         lex_match (lexer, '=');
          
          if (e)
            {
@@ -340,14 +340,14 @@
              return CMD_CASCADING_FAILURE;
            }
          
-         e = expr_parse (ds, EXPR_NUMBER);
+         e = expr_parse (lexer, ds, EXPR_NUMBER);
          if (!e)
            return CMD_CASCADING_FAILURE;
        }
-      else if (lex_match_id ("FILE"))
+      else if (lex_match_id (lexer, "FILE"))
        {
-         lex_match ('=');
-          fh = fh_parse (FH_REF_FILE | FH_REF_INLINE);
+         lex_match (lexer, '=');
+          fh = fh_parse (lexer, FH_REF_FILE | FH_REF_INLINE);
          if (fh == NULL)
            {
              expr_free (e);
@@ -356,13 +356,13 @@
        }
       else
        {
-         lex_error (NULL);
+         lex_error (lexer, NULL);
          expr_free (e);
        }
     }
 
   t = xmalloc (sizeof *t);
-  t->reader = dfm_open_reader (fh);
+  t->reader = dfm_open_reader (fh, lexer);
   t->column = e;
   add_transformation (ds, reread_trns_proc, reread_trns_free, t);
 
@@ -405,13 +405,13 @@
 
 /* Parses END FILE command. */
 int
-cmd_end_file (struct dataset *ds)
+cmd_end_file (struct lexer *lexer, struct dataset *ds)
 {
   assert (in_input_program ());
 
   add_transformation (ds, end_file_trns_proc, NULL, NULL);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Executes an END FILE transformation. */

Index: language/data-io/list.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/list.q,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- language/data-io/list.q     5 Nov 2006 05:20:53 -0000       1.19
+++ language/data-io/list.q     11 Nov 2006 23:10:00 -0000      1.20
@@ -130,12 +130,12 @@
     
 /* Parses and executes the LIST procedure. */
 int
-cmd_list (struct dataset *ds)
+cmd_list (struct lexer *lexer, struct dataset *ds)
 {
   struct variable casenum_var;
   bool ok;
 
-  if (!parse_list (ds, &cmd, NULL))
+  if (!parse_list (lexer, ds, &cmd, NULL))
     return CMD_FAILURE;
   
   /* Fill in defaults. */

Index: language/data-io/matrix-data.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/matrix-data.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -b -r1.16 -r1.17
--- language/data-io/matrix-data.c      3 Nov 2006 04:53:51 -0000       1.16
+++ language/data-io/matrix-data.c      11 Nov 2006 23:10:00 -0000      1.17
@@ -170,11 +170,11 @@
                                             const void *pb);
 static bool read_matrices_without_rowtype (struct dataset *ds, struct 
matrix_data_pgm *);
 static bool read_matrices_with_rowtype (struct dataset *ds, struct 
matrix_data_pgm *);
-static int string_to_content_type (char *, int *);
+static int string_to_content_type (const char *, int *);
 static void attach_mxd_aux (struct variable *, int var_type, int sub_type);
 
 int
-cmd_matrix_data (struct dataset *ds)
+cmd_matrix_data (struct lexer *lexer, struct dataset *ds)
 {
   struct pool *pool;
   struct matrix_data_pgm *mx;
@@ -204,11 +204,11 @@
   mx->n_contents = 0;
   mx->n_continuous = 0;
   mx->first_continuous = 0;
-  while (token != '.')
+  while (lex_token (lexer) != '.')
     {
-      lex_match ('/');
+      lex_match (lexer, '/');
 
-      if (lex_match_id ("VARIABLES"))
+      if (lex_match_id (lexer, "VARIABLES"))
        {
          char **v;
          size_t nv;
@@ -220,8 +220,8 @@
            }
          seen |= 1;
          
-         lex_match ('=');
-         if (!parse_DATA_LIST_vars (&v, &nv, PV_NO_DUPLICATE))
+         lex_match (lexer, '=');
+         if (!parse_DATA_LIST_vars (lexer, &v, &nv, PV_NO_DUPLICATE))
            goto lossage;
          
          {
@@ -262,43 +262,43 @@
                                                  "ROWTYPE_", 8);
           attach_mxd_aux (mx->rowtype_, MXD_ROWTYPE, 0);
        }
-      else if (lex_match_id ("FILE"))
+      else if (lex_match_id (lexer, "FILE"))
        {
-         lex_match ('=');
-         fh = fh_parse (FH_REF_FILE | FH_REF_INLINE);
+         lex_match (lexer, '=');
+         fh = fh_parse (lexer, FH_REF_FILE | FH_REF_INLINE);
          if (fh == NULL)
            goto lossage;
        }
-      else if (lex_match_id ("FORMAT"))
+      else if (lex_match_id (lexer, "FORMAT"))
        {
-         lex_match ('=');
+         lex_match (lexer, '=');
 
-         while (token == T_ID)
+         while (lex_token (lexer) == T_ID)
            {
-             if (lex_match_id ("LIST"))
+             if (lex_match_id (lexer, "LIST"))
                mx->fmt = LIST;
-             else if (lex_match_id ("FREE"))
+             else if (lex_match_id (lexer, "FREE"))
                mx->fmt = FREE;
-             else if (lex_match_id ("LOWER"))
+             else if (lex_match_id (lexer, "LOWER"))
                mx->section = LOWER;
-             else if (lex_match_id ("UPPER"))
+             else if (lex_match_id (lexer, "UPPER"))
                mx->section = UPPER;
-             else if (lex_match_id ("FULL"))
+             else if (lex_match_id (lexer, "FULL"))
                mx->section = FULL;
-             else if (lex_match_id ("DIAGONAL"))
+             else if (lex_match_id (lexer, "DIAGONAL"))
                mx->diag = DIAGONAL;
-             else if (lex_match_id ("NODIAGONAL"))
+             else if (lex_match_id (lexer, "NODIAGONAL"))
                mx->diag = NODIAGONAL;
              else 
                {
-                 lex_error (_("in FORMAT subcommand"));
+                 lex_error (lexer, _("in FORMAT subcommand"));
                  goto lossage;
                }
            }
        }
-      else if (lex_match_id ("SPLIT"))
+      else if (lex_match_id (lexer, "SPLIT"))
        {
-         lex_match ('=');
+         lex_match (lexer, '=');
 
          if (seen & 2)
            {
@@ -307,17 +307,17 @@
            }
          seen |= 2;
          
-         if (token != T_ID)
+         if (lex_token (lexer) != T_ID)
            {
-             lex_error (_("in SPLIT subcommand"));
+             lex_error (lexer, _("in SPLIT subcommand"));
              goto lossage;
            }
          
-         if (dict_lookup_var (dataset_dict (ds), tokid) == NULL
-             && (lex_look_ahead () == '.' || lex_look_ahead () == '/'))
+         if (dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) == NULL
+             && (lex_look_ahead (lexer) == '.' || lex_look_ahead (lexer) == 
'/'))
            {
-             if (!strcasecmp (tokid, "ROWTYPE_")
-                  || !strcasecmp (tokid, "VARNAME_"))
+             if (!strcasecmp (lex_tokid (lexer), "ROWTYPE_")
+                  || !strcasecmp (lex_tokid (lexer), "VARNAME_"))
                {
                  msg (SE, _("Split variable may not be named ROWTYPE_ "
                             "or VARNAME_."));
@@ -325,9 +325,9 @@
                }
 
              mx->single_split = dict_create_var_assert (dataset_dict (ds),
-                                                         tokid, 0);
+                                                         lex_tokid (lexer), 0);
               attach_mxd_aux (mx->single_split, MXD_CONTINUOUS, 0);
-             lex_get ();
+             lex_get (lexer);
 
               dict_set_split_vars (dataset_dict (ds), &mx->single_split, 1);
            }
@@ -336,7 +336,8 @@
              struct variable **split;
              size_t n;
 
-             if (!parse_variables (dataset_dict (ds), &split, &n, 
PV_NO_DUPLICATE))
+             if (!parse_variables (lexer, dataset_dict (ds), 
+                                   &split, &n, PV_NO_DUPLICATE))
                goto lossage;
 
               dict_set_split_vars (dataset_dict (ds), split, n);
@@ -354,7 +355,7 @@
                if (mv->var_type != MXD_CONTINUOUS)
                  {
                    msg (SE, _("Split variable %s is already another type."),
-                        tokid);
+                        lex_tokid (lexer));
                    goto lossage;
                  }
                 var_clear_aux (split[i]);
@@ -362,9 +363,9 @@
               }
          }
        }
-      else if (lex_match_id ("FACTORS"))
+      else if (lex_match_id (lexer, "FACTORS"))
        {
-         lex_match ('=');
+         lex_match (lexer, '=');
          
          if (seen & 4)
            {
@@ -373,7 +374,7 @@
            }
          seen |= 4;
 
-         if (!parse_variables (dataset_dict (ds), &mx->factors, &mx->n_factors,
+         if (!parse_variables (lexer, dataset_dict (ds), &mx->factors, 
&mx->n_factors,
                                 PV_NONE))
            goto lossage;
          
@@ -388,7 +389,7 @@
                if (mv->var_type != MXD_CONTINUOUS)
                  {
                    msg (SE, _("Factor variable %s is already another type."),
-                        tokid);
+                        lex_tokid (lexer));
                    goto lossage;
                  }
                 var_clear_aux (v);
@@ -396,9 +397,9 @@
              }
          }
        }
-      else if (lex_match_id ("CELLS"))
+      else if (lex_match_id (lexer, "CELLS"))
        {
-         lex_match ('=');
+         lex_match (lexer, '=');
          
          if (mx->cells != -1)
            {
@@ -406,18 +407,18 @@
              goto lossage;
            }
 
-         if (!lex_is_integer () || lex_integer () < 1)
+         if (!lex_is_integer (lexer) || lex_integer (lexer) < 1)
            {
-             lex_error (_("expecting positive integer"));
+             lex_error (lexer, _("expecting positive integer"));
              goto lossage;
            }
 
-         mx->cells = lex_integer ();
-         lex_get ();
+         mx->cells = lex_integer (lexer);
+         lex_get (lexer);
        }
-      else if (lex_match_id ("N"))
+      else if (lex_match_id (lexer, "N"))
        {
-         lex_match ('=');
+         lex_match (lexer, '=');
 
          if (mx->pop_n != -1)
            {
@@ -425,16 +426,16 @@
              goto lossage;
            }
 
-         if (!lex_is_integer () || lex_integer () < 1)
+         if (!lex_is_integer (lexer) || lex_integer (lexer) < 1)
            {
-             lex_error (_("expecting positive integer"));
+             lex_error (lexer, _("expecting positive integer"));
              goto lossage;
            }
 
-         mx->pop_n = lex_integer ();
-         lex_get ();
+         mx->pop_n = lex_integer (lexer);
+         lex_get (lexer);
        }
-      else if (lex_match_id ("CONTENTS"))
+      else if (lex_match_id (lexer, "CONTENTS"))
        {
          int inside_parens = 0;
          unsigned collide = 0;
@@ -447,7 +448,7 @@
            }
          seen |= 8;
 
-         lex_match ('=');
+         lex_match (lexer, '=');
          
          {
            int i;
@@ -458,7 +459,7 @@
 
          for (;;)
            {
-             if (lex_match ('('))
+             if (lex_match (lexer, '('))
                {
                  if (inside_parens)
                    {
@@ -468,7 +469,7 @@
                  inside_parens = 1;
                  item = LPAREN;
                }
-             else if (lex_match (')'))
+             else if (lex_match (lexer, ')'))
                {
                  if (!inside_parens)
                    {
@@ -488,20 +489,20 @@
                  int content_type;
                  int collide_index;
                  
-                 if (token != T_ID)
+                 if (lex_token (lexer) != T_ID)
                    {
-                     lex_error (_("in CONTENTS subcommand"));
+                     lex_error (lexer, _("in CONTENTS subcommand"));
                      goto lossage;
                    }
 
-                 content_type = string_to_content_type (tokid,
+                 content_type = string_to_content_type (lex_tokid (lexer),
                                                         &collide_index);
                  if (content_type == -1)
                    {
-                     lex_error (_("in CONTENTS subcommand"));
+                     lex_error (lexer, _("in CONTENTS subcommand"));
                      goto lossage;
                    }
-                 lex_get ();
+                 lex_get (lexer);
 
                  if (collide & (1 << collide_index))
                    {
@@ -516,7 +517,7 @@
                }
              mx->contents[mx->n_contents++] = item;
 
-             if (token == '/' || token == '.')
+             if (lex_token (lexer) == '/' || lex_token (lexer) == '.')
                break;
            }
 
@@ -529,14 +530,14 @@
        }
       else 
        {
-         lex_error (NULL);
+         lex_error (lexer, NULL);
          goto lossage;
        }
     }
   
-  if (token != '.')
+  if (lex_token (lexer) != '.')
     {
-      lex_error (_("expecting end of command"));
+      lex_error (lexer, _("expecting end of command"));
       goto lossage;
     }
   
@@ -623,7 +624,7 @@
       goto lossage;
     }
 
-  mx->reader = dfm_open_reader (fh);
+  mx->reader = dfm_open_reader (fh, lexer);
   if (mx->reader == NULL)
     goto lossage;
 
@@ -651,7 +652,7 @@
    as a bit-index) which can be used for determining whether a related
    statistic has already been used. */
 static int
-string_to_content_type (char *s, int *collide)
+string_to_content_type (const char *s, int *collide)
 {
   static const struct
     {

Index: language/data-io/placement-parser.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/placement-parser.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- language/data-io/placement-parser.c 3 Nov 2006 04:53:51 -0000       1.2
+++ language/data-io/placement-parser.c 11 Nov 2006 23:10:00 -0000      1.3
@@ -44,9 +44,9 @@
     PRS_TYPE_NEW_REC            /* Next record. */
   };
 
-static bool fixed_parse_columns (struct pool *, size_t var_cnt, bool for_input,
+static bool fixed_parse_columns (struct lexer *, struct pool *, size_t 
var_cnt, bool for_input,
                                  struct fmt_spec **, size_t *);
-static bool fixed_parse_fortran (struct pool *, bool for_input,
+static bool fixed_parse_fortran (struct lexer *l, struct pool *, bool 
for_input,
                                  struct fmt_spec **, size_t *);
 
 /* Parses Fortran-like or column-based specifications for placing
@@ -65,18 +65,18 @@
    Uses POOL for allocation.  When the caller is finished
    interpreting *FORMATS, POOL may be destroyed. */
 bool
-parse_var_placements (struct pool *pool, size_t var_cnt, bool for_input,
+parse_var_placements (struct lexer *lexer, struct pool *pool, size_t var_cnt, 
bool for_input,
                       struct fmt_spec **formats, size_t *format_cnt) 
 {
   assert (var_cnt > 0);
-  if (lex_is_number ())
-    return fixed_parse_columns (pool, var_cnt, for_input, formats, format_cnt);
-  else if (lex_match ('(')) 
+  if (lex_is_number (lexer))
+    return fixed_parse_columns (lexer, pool, var_cnt, for_input, formats, 
format_cnt);
+  else if (lex_match (lexer, '(')) 
     {
       size_t assignment_cnt;
       size_t i;
 
-      if (!fixed_parse_fortran (pool, for_input, formats, format_cnt))
+      if (!fixed_parse_fortran (lexer, pool, for_input, formats, format_cnt))
         return false; 
 
       assignment_cnt = 0;
@@ -103,14 +103,14 @@
 
 /* Implements parse_var_placements for column-based formats. */
 static bool
-fixed_parse_columns (struct pool *pool, size_t var_cnt, bool for_input,
+fixed_parse_columns (struct lexer *lexer, struct pool *pool, size_t var_cnt, 
bool for_input,
                      struct fmt_spec **formats, size_t *format_cnt)
 {
   struct fmt_spec format;
   int fc, lc;
   size_t i;
 
-  if (!parse_column_range (&fc, &lc, NULL))
+  if ( !parse_column_range (lexer, &fc, &lc, NULL) )
     return false;
 
   /* Divide columns evenly. */    
@@ -124,28 +124,28 @@
     }
 
   /* Format specifier. */
-  if (lex_match ('('))
+  if (lex_match (lexer, '('))
     {
       /* Get format type. */
-      if (token == T_ID)
+      if (lex_token (lexer) == T_ID)
        {
-         if (!parse_format_specifier_name (&format.type))
+         if (!parse_format_specifier_name (lexer, &format.type))
             return false;
-         lex_match (',');
+         lex_match (lexer, ',');
        }
       else
        format.type = FMT_F;
 
       /* Get decimal places. */
-      if (lex_is_integer ())
+      if (lex_is_integer (lexer))
        {
-         format.d = lex_integer ();
-         lex_get ();
+         format.d = lex_integer (lexer);
+         lex_get (lexer);
        }
       else
        format.d = 0;
 
-      if (!lex_force_match (')'))
+      if (!lex_force_match (lexer, ')'))
        return false;
     }
   else
@@ -167,14 +167,14 @@
 
 /* Implements parse_var_placements for Fortran-like formats. */
 static bool
-fixed_parse_fortran (struct pool *pool, bool for_input,
+fixed_parse_fortran (struct lexer *lexer, struct pool *pool, bool for_input,
                      struct fmt_spec **formats, size_t *format_cnt)
 {
   size_t formats_allocated = 0;
   size_t formats_used = 0;
 
   *formats = NULL;
-  while (!lex_match (')'))
+  while (!lex_match (lexer, ')'))
     {
       struct fmt_spec f;
       struct fmt_spec *new_formats;
@@ -183,19 +183,19 @@
       size_t formats_needed;
       
       /* Parse count. */
-      if (lex_is_integer ())
+      if (lex_is_integer (lexer))
        {
-         count = lex_integer ();
-         lex_get ();
+         count = lex_integer (lexer);
+         lex_get (lexer);
        }
       else
        count = 1;
 
       /* Parse format specifier. */
-      if (lex_match ('('))
+      if (lex_match (lexer, '('))
         {
           /* Call ourselves recursively to handle parentheses. */
-          if (!fixed_parse_fortran (pool, for_input,
+          if (!fixed_parse_fortran (lexer, pool, for_input,
                                     &new_formats, &new_format_cnt))
             return false;
         }
@@ -203,13 +203,13 @@
         {
           new_formats = &f;
           new_format_cnt = 1;
-          if (lex_match ('/'))
+          if (lex_match (lexer, '/'))
             f.type = PRS_TYPE_NEW_REC;
           else
             {
               char type[FMT_TYPE_LEN_MAX + 1];
               
-              if (!parse_abstract_format_specifier (type, &f.w, &f.d))
+              if (!parse_abstract_format_specifier (lexer, type, &f.w, &f.d))
                 return false;
 
               if (!strcasecmp (type, "T")) 
@@ -254,7 +254,7 @@
           formats_used += new_format_cnt;
         }
 
-      lex_match (',');
+      lex_match (lexer, ',');
     }
 
   *format_cnt = formats_used;
@@ -299,27 +299,27 @@
    successful, false if the syntax was invalid or the values
    specified did not make sense. */
 bool
-parse_column_range (int *first_column, int *last_column,
+parse_column_range (struct lexer *lexer, int *first_column, int *last_column,
                     bool *range_specified) 
 {
   /* First column. */
-  if (!lex_force_int ())
+  if (!lex_force_int (lexer))
     return false;
-  *first_column = lex_integer ();
+  *first_column = lex_integer (lexer);
   if (*first_column < 1)
     {
       msg (SE, _("Column positions for fields must be positive."));
       return false;
     }
-  lex_get ();
+  lex_get (lexer);
 
   /* Last column. */
-  lex_negative_to_dash ();
-  if (lex_match ('-'))
+  lex_negative_to_dash (lexer);
+  if (lex_match (lexer, '-'))
     {
-      if (!lex_force_int ())
+      if (!lex_force_int (lexer))
        return false;
-      *last_column = lex_integer ();
+      *last_column = lex_integer (lexer);
       if (*last_column < 1)
        {
          msg (SE, _("Column positions for fields must be positive."));
@@ -334,7 +334,7 @@
 
       if (range_specified)
         *range_specified = true;
-      lex_get ();
+      lex_get (lexer);
     }
   else 
     {
@@ -354,23 +354,23 @@
 
    Returns true if successful, false on syntax error. */
 bool
-parse_record_placement (int *record, int *column) 
+parse_record_placement (struct lexer *lexer, int *record, int *column) 
 {
-  while (lex_match ('/'))
+  while (lex_match (lexer, '/'))
     {
-      if (lex_is_integer ())
+      if (lex_is_integer (lexer))
         {
-          if (lex_integer () <= *record)
+          if (lex_integer (lexer) <= *record)
             {
               msg (SE, _("The record number specified, %ld, is at or "
                          "before the previous record, %d.  Data "
                          "fields must be listed in order of "
                          "increasing record number."),
-                   lex_integer (), *record);
+                   lex_integer (lexer), *record);
               return false;
             }
-          *record = lex_integer ();
-          lex_get ();
+          *record = lex_integer (lexer);
+          lex_get (lexer);
         }
       else
         (*record)++;

Index: language/data-io/placement-parser.h
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/placement-parser.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- language/data-io/placement-parser.h 3 Nov 2006 04:53:51 -0000       1.2
+++ language/data-io/placement-parser.h 11 Nov 2006 23:10:00 -0000      1.3
@@ -25,13 +25,14 @@
 
 struct fmt_spec;
 struct pool;
+struct lexer;
 
-bool parse_record_placement (int *record, int *column);
-bool parse_var_placements (struct pool *, size_t var_cnt, bool for_input,
+bool parse_record_placement (struct lexer *, int *record, int *column);
+bool parse_var_placements (struct lexer *, struct pool *, size_t var_cnt, bool 
for_input,
                            struct fmt_spec **, size_t *format_cnt);
 bool execute_placement_format (const struct fmt_spec *,
                                int *record, int *column);
-bool parse_column_range (int *first_column, int *last_column,
+bool parse_column_range (struct lexer *, int *first_column, int *last_column,
                          bool *range_specified);
 
 #endif /* language/data-io/placement-parser.h */

Index: language/data-io/print-space.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/print-space.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- language/data-io/print-space.c      1 Nov 2006 02:22:35 -0000       1.6
+++ language/data-io/print-space.c      11 Nov 2006 23:10:00 -0000      1.7
@@ -47,32 +47,32 @@
 static trns_free_func print_space_trns_free;
 
 int
-cmd_print_space (struct dataset *ds)
+cmd_print_space (struct lexer *lexer, struct dataset *ds)
 {
   struct print_space_trns *trns;
   struct file_handle *handle;
   struct expression *expr;
   struct dfm_writer *writer;
 
-  if (lex_match_id ("OUTFILE"))
+  if (lex_match_id (lexer, "OUTFILE"))
     {
-      lex_match ('=');
+      lex_match (lexer, '=');
 
-      handle = fh_parse (FH_REF_FILE);
+      handle = fh_parse (lexer, FH_REF_FILE);
       if (handle == NULL)
        return CMD_FAILURE;
-      lex_get ();
+      lex_get (lexer);
     }
   else
     handle = NULL;
 
-  if (token != '.')
+  if (lex_token (lexer) != '.')
     {
-      expr = expr_parse (ds, EXPR_NUMBER);
-      if (token != '.')
+      expr = expr_parse (lexer, ds, EXPR_NUMBER);
+      if (lex_token (lexer) != '.')
        {
          expr_free (expr);
-         lex_error (_("expecting end of command"));
+         lex_error (lexer, _("expecting end of command"));
          return CMD_FAILURE;
        }
     }

Index: language/data-io/print.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/data-io/print.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- language/data-io/print.c    5 Nov 2006 05:20:53 -0000       1.19
+++ language/data-io/print.c    11 Nov 2006 23:10:00 -0000      1.20
@@ -96,11 +96,11 @@
     WRITE
   };
 
-static int internal_cmd_print (struct dataset *ds, 
+static int internal_cmd_print (struct lexer *, struct dataset *ds, 
                               enum which_formats, bool eject);
 static trns_proc_func print_trns_proc;
 static trns_free_func print_trns_free;
-static bool parse_specs (struct pool *tmp_pool, struct print_trns *,
+static bool parse_specs (struct lexer *, struct pool *tmp_pool, struct 
print_trns *,
                         struct dictionary *dict, enum which_formats);
 static void dump_table (struct print_trns *, const struct file_handle *);
 
@@ -108,28 +108,28 @@
 
 /* Parses PRINT command. */
 int
-cmd_print (struct dataset *ds)
+cmd_print (struct lexer *lexer, struct dataset *ds)
 {
-  return internal_cmd_print (ds, PRINT, false);
+  return internal_cmd_print (lexer, ds, PRINT, false);
 }
 
 /* Parses PRINT EJECT command. */
 int
-cmd_print_eject (struct dataset *ds)
+cmd_print_eject (struct lexer *lexer, struct dataset *ds)
 {
-  return internal_cmd_print (ds, PRINT, true);
+  return internal_cmd_print (lexer, ds, PRINT, true);
 }
 
 /* Parses WRITE command. */
 int
-cmd_write (struct dataset *ds)
+cmd_write (struct lexer *lexer, struct dataset *ds)
 {
-  return internal_cmd_print (ds, WRITE, false);
+  return internal_cmd_print (lexer, ds, WRITE, false);
 }
 
 /* Parses the output commands. */
 static int
-internal_cmd_print (struct dataset *ds, 
+internal_cmd_print (struct lexer *lexer, struct dataset *ds, 
                    enum which_formats which_formats, bool eject)
 {
   bool print_table = 0;
@@ -149,33 +149,33 @@
   tmp_pool = pool_create_subpool (trns->pool);
 
   /* Parse the command options. */
-  while (token != '/' && token != '.')
+  while (lex_token (lexer) != '/' && lex_token (lexer) != '.')
     {
-      if (lex_match_id ("OUTFILE"))
+      if (lex_match_id (lexer, "OUTFILE"))
        {
-         lex_match ('=');
+         lex_match (lexer, '=');
 
-         fh = fh_parse (FH_REF_FILE);
+         fh = fh_parse (lexer, FH_REF_FILE);
          if (fh == NULL)
            goto error;
        }
-      else if (lex_match_id ("RECORDS"))
+      else if (lex_match_id (lexer, "RECORDS"))
        {
-         lex_match ('=');
-         lex_match ('(');
-         if (!lex_force_int ())
+         lex_match (lexer, '=');
+         lex_match (lexer, '(');
+         if (!lex_force_int (lexer))
            goto error;
-         trns->record_cnt = lex_integer ();
-         lex_get ();
-         lex_match (')');
+         trns->record_cnt = lex_integer (lexer);
+         lex_get (lexer);
+         lex_match (lexer, ')');
        }
-      else if (lex_match_id ("TABLE"))
+      else if (lex_match_id (lexer, "TABLE"))
        print_table = true;
-      else if (lex_match_id ("NOTABLE"))
+      else if (lex_match_id (lexer, "NOTABLE"))
        print_table = false;
       else
        {
-         lex_error (_("expecting a valid subcommand"));
+         lex_error (lexer, _("expecting a valid subcommand"));
          goto error;
        }
     }
@@ -185,10 +185,10 @@
   trns->include_prefix = which_formats == PRINT && fh != NULL;
 
   /* Parse variables and strings. */
-  if (!parse_specs (tmp_pool, trns, dataset_dict (ds), which_formats))
+  if (!parse_specs (lexer, tmp_pool, trns, dataset_dict (ds), which_formats))
     goto error;
 
-  if (lex_end_of_command () != CMD_SUCCESS)
+  if (lex_end_of_command (lexer) != CMD_SUCCESS)
     goto error;
 
   if (fh != NULL)
@@ -214,9 +214,9 @@
   return CMD_FAILURE;
 }
 
-static bool parse_string_argument (struct print_trns *,
+static bool parse_string_argument (struct lexer *, struct print_trns *,
                                    int record, int *column);
-static bool parse_variable_argument (const struct dictionary *, 
+static bool parse_variable_argument (struct lexer *, const struct dictionary 
*, 
                                     struct print_trns *,
                                      struct pool *tmp_pool,
                                      int *record, int *column,
@@ -226,35 +226,35 @@
    PRINT, PRINT EJECT, or WRITE command into the prt structure.
    Returns success. */
 static bool
-parse_specs (struct pool *tmp_pool, struct print_trns *trns,
+parse_specs (struct lexer *lexer, struct pool *tmp_pool, struct print_trns 
*trns,
             struct dictionary *dict, 
              enum which_formats which_formats)
 {
   int record = 0;
   int column = 1;
 
-  if (token == '.') 
+  if (lex_token (lexer) == '.') 
     {
       trns->record_cnt = 1;
       return true;
     }
 
-  while (token != '.')
+  while (lex_token (lexer) != '.')
     {
       bool ok;
 
-      if (!parse_record_placement (&record, &column))
+      if (!parse_record_placement (lexer, &record, &column))
         return false;
 
-      if (token == T_STRING)
-       ok = parse_string_argument (trns, record, &column);
+      if (lex_token (lexer) == T_STRING)
+       ok = parse_string_argument (lexer, trns, record, &column);
       else
-       ok = parse_variable_argument (dict, trns, tmp_pool, &record, &column,
+       ok = parse_variable_argument (lexer, dict, trns, tmp_pool, &record, 
&column,
                                       which_formats);
       if (!ok)
        return 0;
 
-      lex_match (',');
+      lex_match (lexer, ',');
     }
 
   if (trns->record_cnt != 0 && trns->record_cnt != record)
@@ -268,23 +268,23 @@
 
 /* Parses a string argument to the PRINT commands.  Returns success. */
 static bool
-parse_string_argument (struct print_trns *trns, int record, int *column)
+parse_string_argument (struct lexer *lexer, struct print_trns *trns, int 
record, int *column)
 {
   struct prt_out_spec *spec = pool_alloc (trns->pool, sizeof *spec);
   spec->type = PRT_LITERAL;
   spec->record = record;
   spec->first_column = *column;
-  ds_init_string (&spec->string, &tokstr);
+  ds_init_string (&spec->string, lex_tokstr (lexer));
   ds_register_pool (&spec->string, trns->pool);
-  lex_get ();
+  lex_get (lexer);
 
   /* Parse the included column range. */
-  if (lex_is_number ())
+  if (lex_is_number (lexer))
     {
       int first_column, last_column;
       bool range_specified;
 
-      if (!parse_column_range (&first_column, &last_column, &range_specified)) 
+      if (!parse_column_range (lexer, &first_column, &last_column, 
&range_specified)) 
         return false; 
 
       spec->first_column = first_column;
@@ -301,7 +301,7 @@
    to fixed_parse_compatible() or fixed_parse_fortran() as appropriate.
    Returns success. */
 static bool
-parse_variable_argument (const struct dictionary *dict,
+parse_variable_argument (struct lexer *lexer, const struct dictionary *dict,
                         struct print_trns *trns, struct pool *tmp_pool,
                          int *record, int *column,
                          enum which_formats which_formats)
@@ -312,12 +312,13 @@
   size_t format_cnt;
   bool add_space;
   
-  if (!parse_variables_pool (tmp_pool, dict, &vars, &var_cnt, PV_DUPLICATE))
+  if (!parse_variables_pool (lexer, tmp_pool, dict, 
+                            &vars, &var_cnt, PV_DUPLICATE))
     return false;
 
-  if (lex_is_number () || token == '(')
+  if (lex_is_number (lexer) || lex_token (lexer) == '(')
     {
-      if (!parse_var_placements (tmp_pool, var_cnt, false,
+      if (!parse_var_placements (lexer, tmp_pool, var_cnt, false,
                                  &formats, &format_cnt))
         return false;
       add_space = false;
@@ -326,7 +327,7 @@
     {
       size_t i;
 
-      lex_match ('*');
+      lex_match (lexer, '*');
       
       formats = pool_nmalloc (tmp_pool, var_cnt, sizeof *formats);
       format_cnt = var_cnt;

Index: language/dictionary/apply-dictionary.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/apply-dictionary.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- language/dictionary/apply-dictionary.c      26 Oct 2006 06:16:36 -0000      
1.9
+++ language/dictionary/apply-dictionary.c      11 Nov 2006 23:10:00 -0000      
1.10
@@ -39,7 +39,7 @@
 
 /* Parses and executes APPLY DICTIONARY. */
 int
-cmd_apply_dictionary (struct dataset *ds)
+cmd_apply_dictionary (struct lexer *lexer, struct dataset *ds)
 {
   struct file_handle *handle;
   struct any_reader *reader;
@@ -49,9 +49,9 @@
 
   int i;
   
-  lex_match_id ("FROM");
-  lex_match ('=');
-  handle = fh_parse (FH_REF_FILE | FH_REF_SCRATCH);
+  lex_match_id (lexer, "FROM");
+  lex_match (lexer, '=');
+  handle = fh_parse (lexer, FH_REF_FILE | FH_REF_SCRATCH);
   if (!handle)
     return CMD_FAILURE;
 
@@ -136,5 +136,5 @@
   
   any_reader_close (reader);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }

Index: language/dictionary/formats.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/formats.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- language/dictionary/formats.c       3 Nov 2006 04:53:51 -0000       1.12
+++ language/dictionary/formats.c       11 Nov 2006 23:10:00 -0000      1.13
@@ -42,28 +42,28 @@
     FORMATS_WRITE = 002
   };
 
-static int internal_cmd_formats (struct dataset *ds, int);
+static int internal_cmd_formats (struct lexer *, struct dataset *ds, int);
 
 int
-cmd_print_formats (struct dataset *ds)
+cmd_print_formats (struct lexer *lexer, struct dataset *ds)
 {
-  return internal_cmd_formats (ds, FORMATS_PRINT);
+  return internal_cmd_formats (lexer, ds, FORMATS_PRINT);
 }
 
 int
-cmd_write_formats (struct dataset *ds)
+cmd_write_formats (struct lexer *lexer, struct dataset *ds)
 {
-  return internal_cmd_formats (ds, FORMATS_WRITE);
+  return internal_cmd_formats (lexer, ds, FORMATS_WRITE);
 }
 
 int
-cmd_formats (struct dataset *ds)
+cmd_formats (struct lexer *lexer, struct dataset *ds)
 {
-  return internal_cmd_formats (ds, FORMATS_PRINT | FORMATS_WRITE);
+  return internal_cmd_formats (lexer, ds, FORMATS_PRINT | FORMATS_WRITE);
 }
 
 static int
-internal_cmd_formats (struct dataset *ds, int which)
+internal_cmd_formats (struct lexer *lexer, struct dataset *ds, int which)
 {
   /* Variables. */
   struct variable **v;
@@ -80,24 +80,24 @@
 
   for (;;)
     {
-      if (token == '.')
+      if (lex_token (lexer) == '.')
        break;
 
-      if (!parse_variables (dataset_dict (ds), &v, &cv, PV_NUMERIC))
+      if (!parse_variables (lexer, dataset_dict (ds), &v, &cv, PV_NUMERIC))
        return CMD_FAILURE;
       type = v[0]->type;
 
-      if (!lex_match ('('))
+      if (!lex_match (lexer, '('))
        {
          msg (SE, _("`(' expected after variable list."));
          goto fail;
        }
-      if (!parse_format_specifier (&f)
+      if (!parse_format_specifier (lexer, &f)
           || !fmt_check_output (&f)
           || !fmt_check_type_compat (&f, NUMERIC))
        goto fail;
 
-      if (!lex_match (')'))
+      if (!lex_match (lexer, ')'))
        {
          msg (SE, _("`)' expected after output format."));
          goto fail;

Index: language/dictionary/missing-values.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/missing-values.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- language/dictionary/missing-values.c        3 Nov 2006 04:53:51 -0000       
1.10
+++ language/dictionary/missing-values.c        11 Nov 2006 23:10:00 -0000      
1.11
@@ -37,7 +37,7 @@
 #define _(msgid) gettext (msgid)
 
 int
-cmd_missing_values (struct dataset *ds)
+cmd_missing_values (struct lexer *lexer, struct dataset *ds)
 {
   struct variable **v;
   size_t nv;
@@ -45,23 +45,23 @@
   int retval = CMD_FAILURE;
   bool deferred_errors = false;
 
-  while (token != '.')
+  while (lex_token (lexer) != '.')
     {
       size_t i;
 
-      if (!parse_variables (dataset_dict (ds), &v, &nv, PV_NONE)) 
+      if (!parse_variables (lexer, dataset_dict (ds), &v, &nv, PV_NONE)) 
         goto done;
 
-      if (!lex_match ('('))
+      if (!lex_match (lexer, '('))
         {
-          lex_error (_("expecting `('"));
+          lex_error (lexer, _("expecting `('"));
           goto done;
         }
 
       for (i = 0; i < nv; i++)
         mv_init (&v[i]->miss, v[i]->width);
 
-      if (!lex_match (')')) 
+      if (!lex_match (lexer, ')')) 
         {
           struct missing_values mv;
 
@@ -79,12 +79,12 @@
           if (v[0]->type == NUMERIC) 
             {
               mv_init (&mv, 0);
-              while (!lex_match (')'))
+              while (!lex_match (lexer, ')'))
                 {
                   double x, y;
                   bool ok;
 
-                  if (!parse_num_range (&x, &y, &v[0]->print))
+                  if (!parse_num_range (lexer, &x, &y, &v[0]->print))
                     goto done;
                   
                   ok = (x == y
@@ -93,35 +93,40 @@
                   if (!ok)
                     deferred_errors = true;
 
-                  lex_match (',');
+                  lex_match (lexer, ',');
                 }
             }
           else 
             {
+             struct string value;
+
               mv_init (&mv, MAX_SHORT_STRING);
-              while (!lex_match (')')) 
+              while (!lex_match (lexer, ')')) 
                 {
-                  if (!lex_force_string ())
+                  if (!lex_force_string (lexer))
                     {
                       deferred_errors = true;
                       break;
                     }
 
-                  if (ds_length (&tokstr) > MAX_SHORT_STRING) 
+                 ds_init_string (&value, lex_tokstr (lexer));
+
+                  if (ds_length (&value) > MAX_SHORT_STRING) 
                     {
-                      ds_truncate (&tokstr, MAX_SHORT_STRING);
+                      ds_truncate (&value, MAX_SHORT_STRING);
                       msg (SE, _("Truncating missing value to short string "
                                  "length (%d characters)."),
                            MAX_SHORT_STRING);
                     }
                   else
-                    ds_rpad (&tokstr, MAX_SHORT_STRING, ' ');
+                    ds_rpad (&value, MAX_SHORT_STRING, ' ');
 
-                  if (!mv_add_str (&mv, ds_data (&tokstr)))
+                  if (!mv_add_str (&mv, ds_data (&value)))
                     deferred_errors = true;
+                 ds_destroy (&value);
 
-                  lex_get ();
-                  lex_match (',');
+                  lex_get (lexer);
+                  lex_match (lexer, ',');
                 }
             }
           
@@ -142,11 +147,11 @@
             }
         }
 
-      lex_match ('/');
+      lex_match (lexer, '/');
       free (v);
       v = NULL;
     }
-  retval = lex_end_of_command ();
+  retval = lex_end_of_command (lexer);
   
  done:
   free (v);

Index: language/dictionary/modify-variables.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/modify-variables.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- language/dictionary/modify-variables.c      29 Oct 2006 09:51:36 -0000      
1.11
+++ language/dictionary/modify-variables.c      11 Nov 2006 23:10:00 -0000      
1.12
@@ -78,7 +78,7 @@
 
 /* Performs MODIFY VARS command. */
 int
-cmd_modify_vars (struct dataset *ds)
+cmd_modify_vars (struct lexer *lexer, struct dataset *ds)
 {
   /* Bits indicated whether we've already encountered a subcommand of
      this type. */
@@ -105,10 +105,10 @@
   vm.drop_cnt = 0;
 
   /* Parse each subcommand. */
-  lex_match ('/');
+  lex_match (lexer, '/');
   for (;;)
     {
-      if (lex_match_id ("REORDER"))
+      if (lex_match_id (lexer, "REORDER"))
        {
          struct variable **v = NULL;
          size_t nv = 0;
@@ -120,21 +120,21 @@
            }
          already_encountered |= 1;
 
-         lex_match ('=');
+         lex_match (lexer, '=');
          do
            {
               struct ordering ordering;
              size_t prev_nv = nv;
 
              ordering.forward = ordering.positional = 1;
-             if (lex_match_id ("FORWARD"));
-             else if (lex_match_id ("BACKWARD"))
+             if (lex_match_id (lexer, "FORWARD"));
+             else if (lex_match_id (lexer, "BACKWARD"))
                ordering.forward = 0;
-             if (lex_match_id ("POSITIONAL"));
-             else if (lex_match_id ("ALPHA"))
+             if (lex_match_id (lexer, "POSITIONAL"));
+             else if (lex_match_id (lexer, "ALPHA"))
                ordering.positional = 0;
 
-             if (lex_match (T_ALL) || token == '/' || token == '.')
+             if (lex_match (lexer, T_ALL) || lex_token (lexer) == '/' || 
lex_token (lexer) == '.')
                {
                  if (prev_nv != 0)
                    {
@@ -146,19 +146,19 @@
                }
              else
                {
-                 if (!lex_match ('('))
+                 if (!lex_match (lexer, '('))
                    {
                      msg (SE, _("`(' expected on REORDER subcommand."));
                      free (v);
                      goto done;
                    }
-                 if (!parse_variables (dataset_dict (ds), &v, &nv,
+                 if (!parse_variables (lexer, dataset_dict (ds), &v, &nv,
                                        PV_APPEND | PV_NO_DUPLICATE))
                    {
                      free (v);
                      goto done;
                    }
-                 if (!lex_match (')'))
+                 if (!lex_match (lexer, ')'))
                    {
                      msg (SE, _("`)' expected following variable names on "
                           "REORDER subcommand."));
@@ -169,12 +169,12 @@
              sort (&v[prev_nv], nv - prev_nv, sizeof *v,
                     compare_variables_given_ordering, &ordering);
            }
-         while (token != '/' && token != '.');
+         while (lex_token (lexer) != '/' && lex_token (lexer) != '.');
 
          vm.reorder_vars = v;
           vm.reorder_cnt = nv;
        }
-      else if (lex_match_id ("RENAME"))
+      else if (lex_match_id (lexer, "RENAME"))
        {
          if (already_encountered & 2)
            {
@@ -183,27 +183,29 @@
            }
          already_encountered |= 2;
 
-         lex_match ('=');
+         lex_match (lexer, '=');
          do
            {
              size_t prev_nv_1 = vm.rename_cnt;
              size_t prev_nv_2 = vm.rename_cnt;
 
-             if (!lex_match ('('))
+             if (!lex_match (lexer, '('))
                {
                  msg (SE, _("`(' expected on RENAME subcommand."));
                  goto done;
                }
-             if (!parse_variables (dataset_dict (ds), &vm.rename_vars, 
&vm.rename_cnt,
+             if (!parse_variables (lexer, dataset_dict (ds), 
+                                   &vm.rename_vars, &vm.rename_cnt,
                                    PV_APPEND | PV_NO_DUPLICATE))
                goto done;
-             if (!lex_match ('='))
+             if (!lex_match (lexer, '='))
                {
                  msg (SE, _("`=' expected between lists of new and old 
variable "
                       "names on RENAME subcommand."));
                  goto done;
                }
-             if (!parse_DATA_LIST_vars (&vm.new_names, &prev_nv_1, PV_APPEND))
+             if (!parse_DATA_LIST_vars (lexer, &vm.new_names, 
+                                        &prev_nv_1, PV_APPEND))
                goto done;
              if (prev_nv_1 != vm.rename_cnt)
                {
@@ -216,16 +218,16 @@
                  vm.new_names = NULL;
                  goto done;
                }
-             if (!lex_match (')'))
+             if (!lex_match (lexer, ')'))
                {
                  msg (SE, _("`)' expected after variable lists on RENAME "
                       "subcommand."));
                  goto done;
                }
            }
-         while (token != '.' && token != '/');
+         while (lex_token (lexer) != '.' && lex_token (lexer) != '/');
        }
-      else if (lex_match_id ("KEEP"))
+      else if (lex_match_id (lexer, "KEEP"))
        {
          struct variable **keep_vars, **all_vars, **drop_vars;
          size_t keep_cnt, all_cnt, drop_cnt;
@@ -238,8 +240,8 @@
            }
          already_encountered |= 4;
 
-         lex_match ('=');
-         if (!parse_variables (dataset_dict (ds), &keep_vars, &keep_cnt, 
PV_NONE))
+         lex_match (lexer, '=');
+         if (!parse_variables (lexer, dataset_dict (ds), &keep_vars, 
&keep_cnt, PV_NONE))
            goto done;
 
          /* Transform the list of variables to keep into a list of
@@ -268,7 +270,7 @@
           vm.drop_vars = drop_vars;
           vm.drop_cnt = drop_cnt;
        }
-      else if (lex_match_id ("DROP"))
+      else if (lex_match_id (lexer, "DROP"))
        {
          struct variable **drop_vars;
          size_t drop_cnt;
@@ -282,13 +284,13 @@
            }
          already_encountered |= 4;
 
-         lex_match ('=');
-         if (!parse_variables (dataset_dict (ds), &drop_vars, &drop_cnt, 
PV_NONE))
+         lex_match (lexer, '=');
+         if (!parse_variables (lexer, dataset_dict (ds), &drop_vars, 
&drop_cnt, PV_NONE))
            goto done;
           vm.drop_vars = drop_vars;
           vm.drop_cnt = drop_cnt;
        }
-      else if (lex_match_id ("MAP"))
+      else if (lex_match_id (lexer, "MAP"))
        {
           struct dictionary *temp = dict_clone (dataset_dict (ds));
           int success = rearrange_dict (temp, &vm);
@@ -300,21 +302,21 @@
        }
       else
        {
-         if (token == T_ID)
-           msg (SE, _("Unrecognized subcommand name `%s'."), tokid);
+         if (lex_token (lexer) == T_ID)
+           msg (SE, _("Unrecognized subcommand name `%s'."), lex_tokid 
(lexer));
          else
            msg (SE, _("Subcommand name expected."));
          goto done;
        }
 
-      if (token == '.')
+      if (lex_token (lexer) == '.')
        break;
-      if (token != '/')
+      if (lex_token (lexer) != '/')
        {
          msg (SE, _("`/' or `.' expected."));
          goto done;
        }
-      lex_get ();
+      lex_get (lexer);
     }
 
   if (already_encountered & (1 | 4))

Index: language/dictionary/numeric.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/numeric.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- language/dictionary/numeric.c       5 Nov 2006 05:20:53 -0000       1.15
+++ language/dictionary/numeric.c       11 Nov 2006 23:10:00 -0000      1.16
@@ -37,7 +37,7 @@
 
 /* Parses the NUMERIC command. */
 int
-cmd_numeric (struct dataset *ds)
+cmd_numeric (struct lexer *lexer, struct dataset *ds)
 {
   size_t i;
 
@@ -51,13 +51,13 @@
 
   do
     {
-      if (!parse_DATA_LIST_vars (&v, &nv, PV_NONE))
+      if (!parse_DATA_LIST_vars (lexer, &v, &nv, PV_NONE))
        return CMD_FAILURE;
 
       /* Get the optional format specification. */
-      if (lex_match ('('))
+      if (lex_match (lexer, '('))
        {
-         if (!parse_format_specifier (&f))
+         if (!parse_format_specifier (lexer, &f))
            goto fail;
          if (fmt_is_string (f.type))
            {
@@ -67,7 +67,7 @@
              goto fail;
            }
 
-         if (!lex_match (')'))
+         if (!lex_match (lexer, ')'))
            {
              msg (SE, _("`)' expected after output format."));
              goto fail;
@@ -94,9 +94,9 @@
        free (v[i]);
       free (v);
     }
-  while (lex_match ('/'));
+  while (lex_match (lexer, '/'));
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 
   /* If we have an error at a point where cleanup is required,
      flow-of-control comes here. */
@@ -109,7 +109,7 @@
 
 /* Parses the STRING command. */
 int
-cmd_string (struct dataset *ds)
+cmd_string (struct lexer *lexer, struct dataset *ds)
 {
   size_t i;
 
@@ -125,12 +125,12 @@
 
   do
     {
-      if (!parse_DATA_LIST_vars (&v, &nv, PV_NONE))
+      if (!parse_DATA_LIST_vars (lexer, &v, &nv, PV_NONE))
        return CMD_FAILURE;
 
-      if (!lex_force_match ('(')
-          || !parse_format_specifier (&f)
-          || !lex_force_match (')'))
+      if (!lex_force_match (lexer, '(')
+          || !parse_format_specifier (lexer, &f)
+          || !lex_force_match (lexer, ')'))
        goto fail;
       if (!fmt_is_string (f.type))
        {
@@ -160,9 +160,9 @@
        free (v[i]);
       free (v);
     }
-  while (lex_match ('/'));
+  while (lex_match (lexer, '/'));
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 
   /* If we have an error at a point where cleanup is required,
      flow-of-control comes here. */
@@ -175,18 +175,18 @@
 
 /* Parses the LEAVE command. */
 int
-cmd_leave (struct dataset *ds)
+cmd_leave (struct lexer *lexer, struct dataset *ds)
 {
   struct variable **v;
   size_t nv;
 
   size_t i;
 
-  if (!parse_variables (dataset_dict (ds), &v, &nv, PV_NONE))
+  if (!parse_variables (lexer, dataset_dict (ds), &v, &nv, PV_NONE))
     return CMD_CASCADING_FAILURE;
   for (i = 0; i < nv; i++)
     v[i]->leave = true;
   free (v);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }

Index: language/dictionary/rename-variables.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/rename-variables.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- language/dictionary/rename-variables.c      26 Oct 2006 06:16:36 -0000      
1.7
+++ language/dictionary/rename-variables.c      11 Nov 2006 23:10:00 -0000      
1.8
@@ -38,7 +38,7 @@
 /* The code for this function is very similar to the code for the
    RENAME subcommand of MODIFY VARS. */
 int
-cmd_rename_variables (struct dataset *ds)
+cmd_rename_variables (struct lexer *lexer, struct dataset *ds)
 {
   struct variable **rename_vars = NULL;
   char **rename_new_names = NULL;
@@ -56,20 +56,20 @@
       size_t prev_nv_1 = rename_cnt;
       size_t prev_nv_2 = rename_cnt;
 
-      if (!lex_match ('('))
+      if (!lex_match (lexer, '('))
        {
          msg (SE, _("`(' expected."));
          goto lossage;
        }
-      if (!parse_variables (dataset_dict (ds), &rename_vars, &rename_cnt,
+      if (!parse_variables (lexer, dataset_dict (ds), &rename_vars, 
&rename_cnt,
                            PV_APPEND | PV_NO_DUPLICATE))
        goto lossage;
-      if (!lex_match ('='))
+      if (!lex_match (lexer, '='))
        {
          msg (SE, _("`=' expected between lists of new and old variable 
names."));
          goto lossage;
        }
-      if (!parse_DATA_LIST_vars (&rename_new_names, &prev_nv_1, PV_APPEND))
+      if (!parse_DATA_LIST_vars (lexer, &rename_new_names, &prev_nv_1, 
PV_APPEND))
        goto lossage;
       if (prev_nv_1 != rename_cnt)
        {
@@ -85,13 +85,13 @@
          rename_new_names = NULL;
          goto lossage;
        }
-      if (!lex_match (')'))
+      if (!lex_match (lexer, ')'))
        {
          msg (SE, _("`)' expected after variable names."));
          goto lossage;
        }
     }
-  while (token != '.');
+  while (lex_token (lexer) != '.');
 
   if (!dict_rename_vars (dataset_dict (ds),
                          rename_vars, rename_new_names, rename_cnt,

Index: language/dictionary/split-file.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/split-file.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- language/dictionary/split-file.c    5 Nov 2006 05:20:53 -0000       1.10
+++ language/dictionary/split-file.c    11 Nov 2006 23:10:00 -0000      1.11
@@ -42,9 +42,9 @@
 #define _(msgid) gettext (msgid)
 
 int
-cmd_split_file (struct dataset *ds)
+cmd_split_file (struct lexer *lexer, struct dataset *ds)
 {
-  if (lex_match_id ("OFF"))
+  if (lex_match_id (lexer, "OFF"))
     dict_set_split_vars (dataset_dict (ds), NULL, 0);
   else
     {
@@ -52,17 +52,17 @@
       size_t n;
 
       /* For now, ignore SEPARATE and LAYERED. */
-      (void) ( lex_match_id ("SEPARATE") || lex_match_id ("LAYERED") );
+      (void) ( lex_match_id (lexer, "SEPARATE") || lex_match_id (lexer, 
"LAYERED") );
       
-      lex_match (T_BY);
-      if (!parse_variables (dataset_dict (ds), &v, &n, PV_NO_DUPLICATE))
+      lex_match (lexer, T_BY);
+      if (!parse_variables (lexer, dataset_dict (ds), &v, &n, PV_NO_DUPLICATE))
        return CMD_CASCADING_FAILURE;
 
       dict_set_split_vars (dataset_dict (ds), v, n);
       free (v);
     }
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Dumps out the values of all the split variables for the case C. */

Index: language/dictionary/sys-file-info.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/sys-file-info.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- language/dictionary/sys-file-info.c 3 Nov 2006 04:53:51 -0000       1.13
+++ language/dictionary/sys-file-info.c 11 Nov 2006 23:10:00 -0000      1.14
@@ -78,7 +78,7 @@
 
 /* SYSFILE INFO utility. */
 int
-cmd_sysfile_info (struct dataset *ds UNUSED)
+cmd_sysfile_info (struct lexer *lexer, struct dataset *ds UNUSED)
 {
   struct file_handle *h;
   struct dictionary *d;
@@ -88,10 +88,10 @@
   int r, nr;
   int i;
 
-  lex_match_id ("FILE");
-  lex_match ('=');
+  lex_match_id (lexer, "FILE");
+  lex_match (lexer, '=');
 
-  h = fh_parse (FH_REF_FILE);
+  h = fh_parse (lexer, FH_REF_FILE);
   if (!h)
     return CMD_FAILURE;
 
@@ -170,7 +170,7 @@
 
   dict_destroy (d);
   
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* DISPLAY utility. */
@@ -181,7 +181,7 @@
 static void display_vectors (const struct dictionary *dict, int sorted);
 
 int
-cmd_display (struct dataset *ds)
+cmd_display (struct lexer *lexer, struct dataset *ds)
 {
   /* Whether to sort the list of variables alphabetically. */
   int sorted;
@@ -190,14 +190,14 @@
   size_t n;
   struct variable **vl;
 
-  if (lex_match_id ("MACROS"))
+  if (lex_match_id (lexer, "MACROS"))
     display_macros ();
-  else if (lex_match_id ("DOCUMENTS"))
+  else if (lex_match_id (lexer, "DOCUMENTS"))
     display_documents (dataset_dict (ds));
-  else if (lex_match_id ("FILE"))
+  else if (lex_match_id (lexer, "FILE"))
     {
       som_blank_line ();
-      if (!lex_force_match_id ("LABEL"))
+      if (!lex_force_match_id (lexer, "LABEL"))
        return CMD_FAILURE;
       if (dict_get_label (dataset_dict (ds)) == NULL)
        tab_output_text (TAB_LEFT,
@@ -216,12 +216,12 @@
       const char **cp;
       int as;
 
-      sorted = lex_match_id ("SORTED");
+      sorted = lex_match_id (lexer, "SORTED");
 
       for (cp = sbc; *cp; cp++)
-       if (token == T_ID && lex_id_match (*cp, tokid))
+       if (lex_token (lexer) == T_ID && lex_id_match (*cp, lex_tokid (lexer)))
          {
-           lex_get ();
+           lex_get (lexer);
            break;
          }
       as = cp - sbc;
@@ -235,13 +235,13 @@
          return CMD_SUCCESS;
        }
 
-      lex_match ('/');
-      lex_match_id ("VARIABLES");
-      lex_match ('=');
+      lex_match (lexer, '/');
+      lex_match_id (lexer, "VARIABLES");
+      lex_match (lexer, '=');
 
-      if (token != '.')
+      if (lex_token (lexer) != '.')
        {
-         if (!parse_variables (dataset_dict (ds), &vl, &n, PV_NONE))
+         if (!parse_variables (lexer, dataset_dict (ds), &vl, &n, PV_NONE))
            {
              free (vl);
              return CMD_FAILURE;
@@ -278,7 +278,7 @@
       free (vl);
     }
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 static void

Index: language/dictionary/value-labels.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/value-labels.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- language/dictionary/value-labels.c  26 Oct 2006 06:16:36 -0000      1.9
+++ language/dictionary/value-labels.c  11 Nov 2006 23:10:00 -0000      1.10
@@ -38,39 +38,40 @@
 
 /* Declarations. */
 
-static int do_value_labels (const struct dictionary *dict, int);
+static int do_value_labels (struct lexer *, 
+                           const struct dictionary *dict, int);
 static int verify_val_labs (struct variable **vars, size_t var_cnt);
 static void erase_labels (struct variable **vars, size_t var_cnt);
-static int get_label (struct variable **vars, size_t var_cnt);
+static int get_label (struct lexer *, struct variable **vars, size_t var_cnt);
 
 /* Stubs. */
 
 int
-cmd_value_labels (struct dataset *ds)
+cmd_value_labels (struct lexer *lexer, struct dataset *ds)
 {
-  return do_value_labels (dataset_dict (ds), 1);
+  return do_value_labels (lexer, dataset_dict (ds), 1);
 }
 
 int
-cmd_add_value_labels (struct dataset *ds)
+cmd_add_value_labels (struct lexer *lexer, struct dataset *ds)
 {
-  return do_value_labels (dataset_dict (ds), 0);
+  return do_value_labels (lexer, dataset_dict (ds), 0);
 }
 
 /* Do it. */
 
 static int
-do_value_labels (const struct dictionary *dict, int erase)
+do_value_labels (struct lexer *lexer, const struct dictionary *dict, int erase)
 {
   struct variable **vars; /* Variable list. */
   size_t var_cnt;         /* Number of variables. */
   int parse_err=0;        /* true if error parsing variables */
 
-  lex_match ('/');
+  lex_match (lexer, '/');
   
-  while (token != '.')
+  while (lex_token (lexer) != '.')
     {
-      parse_err = !parse_variables (dict, &vars, &var_cnt, 
+      parse_err = !parse_variables (lexer, dict, &vars, &var_cnt, 
                                    PV_SAME_TYPE) ;
       if (var_cnt < 1)
        {
@@ -81,17 +82,17 @@
         goto lossage;
       if (erase)
         erase_labels (vars, var_cnt);
-      while (token != '/' && token != '.')
-       if (!get_label (vars, var_cnt))
+      while (lex_token (lexer) != '/' && lex_token (lexer) != '.')
+       if (!get_label (lexer, vars, var_cnt))
           goto lossage;
 
-      if (token != '/')
+      if (lex_token (lexer) != '/')
        {
        free (vars);
        break;
        }
 
-      lex_get ();
+      lex_get (lexer);
 
       free (vars);
     }
@@ -99,7 +100,7 @@
   if (parse_err)
     return CMD_FAILURE;
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 
  lossage:
   free (vars);
@@ -141,54 +142,58 @@
 /* Parse all the labels for the VAR_CNT variables in VARS and add
    the specified labels to those variables.  */
 static int
-get_label (struct variable **vars, size_t var_cnt)
+get_label (struct lexer *lexer, struct variable **vars, size_t var_cnt)
 {
   /* Parse all the labels and add them to the variables. */
   do
     {
       union value value;
-      char *label;
+      struct string label;
       size_t i;
 
       /* Set value. */
       if (vars[0]->type == ALPHA)
        {
-         if (token != T_STRING)
+         if (lex_token (lexer) != T_STRING)
            {
-              lex_error (_("expecting string"));
+              lex_error (lexer, _("expecting string"));
              return 0;
            }
-         buf_copy_str_rpad (value.s, MAX_SHORT_STRING, ds_cstr (&tokstr));
+         buf_copy_str_rpad (value.s, MAX_SHORT_STRING, ds_cstr (lex_tokstr 
(lexer)));
        }
       else
        {
-         if (!lex_is_number ())
+         if (!lex_is_number (lexer))
            {
-             lex_error (_("expecting integer"));
+             lex_error (lexer, _("expecting integer"));
              return 0;
            }
-         if (!lex_is_integer ())
-           msg (SW, _("Value label `%g' is not integer."), tokval);
-         value.f = tokval;
+         if (!lex_is_integer (lexer))
+           msg (SW, _("Value label `%g' is not integer."), lex_tokval (lexer));
+         value.f = lex_tokval (lexer);
        }
-      lex_get ();
+      lex_get (lexer);
 
       /* Set label. */
-      if (!lex_force_string ())
+      if (!lex_force_string (lexer))
        return 0;
-      if (ds_length (&tokstr) > 60)
+      
+      ds_init_string (&label, lex_tokstr (lexer));
+
+      if (ds_length (&label) > 60)
        {
          msg (SW, _("Truncating value label to 60 characters."));
-         ds_truncate (&tokstr, 60);
+         ds_truncate (&label, 60);
        }
-      label = ds_cstr (&tokstr);
 
       for (i = 0; i < var_cnt; i++)
-        val_labs_replace (vars[i]->val_labs, value, label);
+        val_labs_replace (vars[i]->val_labs, value, ds_cstr (&label));
+
+      ds_destroy (&label);
 
-      lex_get ();
+      lex_get (lexer);
     }
-  while (token != '/' && token != '.');
+  while (lex_token (lexer) != '/' && lex_token (lexer) != '.');
 
   return 1;
 }

Index: language/dictionary/variable-display.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/variable-display.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- language/dictionary/variable-display.c      26 Oct 2006 06:16:36 -0000      
1.9
+++ language/dictionary/variable-display.c      11 Nov 2006 23:10:00 -0000      
1.10
@@ -36,7 +36,7 @@
    It affects nothing but GUIs
 */
 int
-cmd_variable_alignment (struct dataset *ds)
+cmd_variable_alignment (struct lexer *lexer, struct dataset *ds)
 {
   do
     {
@@ -46,16 +46,16 @@
       size_t i;
       enum alignment align;
 
-      if (!parse_variables (dataset_dict (ds), &v, &nv, PV_NONE))
+      if (!parse_variables (lexer, dataset_dict (ds), &v, &nv, PV_NONE))
         return CMD_FAILURE;
 
-      if ( lex_force_match('(') ) 
+      if ( lex_force_match (lexer, '(') ) 
        {
-         if ( lex_match_id("LEFT"))
+         if ( lex_match_id (lexer, "LEFT"))
            align = ALIGN_LEFT;
-         else if ( lex_match_id("RIGHT"))
+         else if ( lex_match_id (lexer, "RIGHT"))
            align = ALIGN_RIGHT;
-         else if ( lex_match_id("CENTER"))
+         else if ( lex_match_id (lexer, "CENTER"))
            align = ALIGN_CENTRE;
          else 
             {
@@ -63,7 +63,7 @@
               return CMD_FAILURE; 
             }
 
-         lex_force_match(')');
+         lex_force_match (lexer, ')');
        }
       else 
         {
@@ -75,12 +75,12 @@
        v[i]->alignment = align;
 
 
-      while (token == '/')
-       lex_get ();
+      while (lex_token (lexer) == '/')
+       lex_get (lexer);
       free (v);
 
     }
-  while (token != '.');
+  while (lex_token (lexer) != '.');
   return CMD_SUCCESS;
 }
 
@@ -89,7 +89,7 @@
    It affects nothing but GUIs
 */
 int
-cmd_variable_width (struct dataset *ds)
+cmd_variable_width (struct lexer *lexer, struct dataset *ds)
 {
   do
     {
@@ -97,33 +97,33 @@
       size_t nv;
       size_t i;
 
-      if (!parse_variables (dataset_dict (ds), &v, &nv, PV_NONE))
+      if (!parse_variables (lexer, dataset_dict (ds), &v, &nv, PV_NONE))
         return CMD_FAILURE;
 
-      if ( lex_force_match('(') ) 
+      if ( lex_force_match (lexer, '(') ) 
        {
-         if ( lex_force_int()) 
-           lex_get();
+         if ( lex_force_int (lexer)) 
+           lex_get (lexer);
          else
            return CMD_FAILURE;
-         lex_force_match(')');
+         lex_force_match (lexer, ')');
        }
 
       for( i = 0 ; i < nv ; ++i ) 
-         v[i]->display_width = tokval;
+         v[i]->display_width = lex_tokval (lexer);
 
-      while (token == '/')
-       lex_get ();
+      while (lex_token (lexer) == '/')
+       lex_get (lexer);
       free (v);
 
     }
-  while (token != '.');
+  while (lex_token (lexer) != '.');
   return CMD_SUCCESS;
 }
 
 /* Set variables' measurement level */
 int
-cmd_variable_level (struct dataset *ds)
+cmd_variable_level (struct lexer *lexer, struct dataset *ds)
 {
   do
     {
@@ -132,16 +132,16 @@
       enum measure level;
       size_t i;
 
-      if (!parse_variables (dataset_dict (ds), &v, &nv, PV_NONE))
+      if (!parse_variables (lexer, dataset_dict (ds), &v, &nv, PV_NONE))
         return CMD_FAILURE;
 
-      if ( lex_force_match('(') ) 
+      if ( lex_force_match (lexer, '(') ) 
        {
-         if ( lex_match_id("SCALE"))
+         if ( lex_match_id (lexer, "SCALE"))
            level = MEASURE_SCALE;
-         else if ( lex_match_id("ORDINAL"))
+         else if ( lex_match_id (lexer, "ORDINAL"))
            level = MEASURE_ORDINAL;
-         else if ( lex_match_id("NOMINAL"))
+         else if ( lex_match_id (lexer, "NOMINAL"))
            level = MEASURE_NOMINAL;
          else 
             {
@@ -149,7 +149,7 @@
               return CMD_FAILURE; 
             }
 
-         lex_force_match(')');
+         lex_force_match (lexer, ')');
        }
       else
         {
@@ -161,11 +161,11 @@
        v[i]->measure = level ;
 
 
-      while (token == '/')
-       lex_get ();
+      while (lex_token (lexer) == '/')
+       lex_get (lexer);
       free (v);
 
     }
-  while (token != '.');
+  while (lex_token (lexer) != '.');
   return CMD_SUCCESS;
 }

Index: language/dictionary/variable-label.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/variable-label.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- language/dictionary/variable-label.c        26 Oct 2006 06:16:36 -0000      
1.10
+++ language/dictionary/variable-label.c        11 Nov 2006 23:10:00 -0000      
1.11
@@ -35,42 +35,46 @@
 #define _(msgid) gettext (msgid)
 
 int
-cmd_variable_labels (struct dataset *ds)
+cmd_variable_labels (struct lexer *lexer, struct dataset *ds)
 {
   do
     {
       struct variable **v;
+      struct string label;
       size_t nv;
 
       size_t i;
 
-      if (!parse_variables (dataset_dict (ds), &v, &nv, PV_NONE))
+      if (!parse_variables (lexer, dataset_dict (ds), &v, &nv, PV_NONE))
         return CMD_FAILURE;
 
-      if (token != T_STRING)
+      if (lex_token (lexer) != T_STRING)
        {
          msg (SE, _("String expected for variable label."));
          free (v);
          return CMD_FAILURE;
        }
-      if (ds_length (&tokstr) > 255)
+
+      ds_init_string (&label, lex_tokstr (lexer) );
+      if (ds_length (&label) > 255)
        {
          msg (SW, _("Truncating variable label to 255 characters."));
-         ds_truncate (&tokstr, 255);
+         ds_truncate (&label, 255);
        }
       for (i = 0; i < nv; i++)
        {
          if (v[i]->label)
            free (v[i]->label);
-         v[i]->label = ds_xstrdup (&tokstr);
+         v[i]->label = ds_xstrdup (&label);
        }
+      ds_destroy (&label);
 
-      lex_get ();
-      while (token == '/')
-       lex_get ();
+      lex_get (lexer);
+      while (lex_token (lexer) == '/')
+       lex_get (lexer);
       free (v);
     }
-  while (token != '.');
+  while (lex_token (lexer) != '.');
   return CMD_SUCCESS;
 }
 

Index: language/dictionary/vector.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/vector.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- language/dictionary/vector.c        26 Oct 2006 06:16:36 -0000      1.9
+++ language/dictionary/vector.c        11 Nov 2006 23:10:00 -0000      1.10
@@ -37,7 +37,7 @@
 #define _(msgid) gettext (msgid)
 
 int
-cmd_vector (struct dataset *ds)
+cmd_vector (struct lexer *lexer, struct dataset *ds)
 {
   /* Just to be different, points to a set of null terminated strings
      containing the names of the vectors to be created.  The list
@@ -58,9 +58,9 @@
   do
     {
       /* Get the name(s) of the new vector(s). */
-      if (!lex_force_id ())
+      if (!lex_force_id (lexer))
        return CMD_CASCADING_FAILURE;
-      while (token == T_ID)
+      while (lex_token (lexer) == T_ID)
        {
          if (cp + 16 > endp)
            {
@@ -71,27 +71,27 @@
            }
 
          for (cp2 = cp; cp2 < cp; cp2 += strlen (cp))
-           if (!strcasecmp (cp2, tokid))
+           if (!strcasecmp (cp2, lex_tokid (lexer)))
              {
-               msg (SE, _("Vector name %s is given twice."), tokid);
+               msg (SE, _("Vector name %s is given twice."), lex_tokid 
(lexer));
                goto fail;
              }
 
-         if (dict_lookup_vector (dict, tokid))
+         if (dict_lookup_vector (dict, lex_tokid (lexer)))
            {
-             msg (SE, _("There is already a vector with name %s."), tokid);
+             msg (SE, _("There is already a vector with name %s."), lex_tokid 
(lexer));
              goto fail;
            }
 
-         cp = stpcpy (cp, tokid) + 1;
-         lex_get ();
-         lex_match (',');
+         cp = stpcpy (cp, lex_tokid (lexer)) + 1;
+         lex_get (lexer);
+         lex_match (lexer, ',');
        }
       *cp++ = 0;
 
       /* Now that we have the names it's time to check for the short
          or long forms. */
-      if (lex_match ('='))
+      if (lex_match (lexer, '='))
        {
          /* Long form. */
           struct variable **v;
@@ -106,14 +106,14 @@
              goto fail;
            }
 
-         if (!parse_variables (dict, &v, &nv,
+         if (!parse_variables (lexer, dict, &v, &nv,
                                 PV_SAME_TYPE | PV_DUPLICATE))
            goto fail;
 
           dict_create_vector (dict, vecnames, v, nv);
           free (v);
        }
-      else if (lex_match ('('))
+      else if (lex_match (lexer, '('))
        {
          int i;
 
@@ -128,16 +128,16 @@
           struct variable **v;
           int nv;
 
-         if (!lex_force_int ())
+         if (!lex_force_int (lexer))
            return CMD_CASCADING_FAILURE;
-         nv = lex_integer ();
-         lex_get ();
+         nv = lex_integer (lexer);
+         lex_get (lexer);
          if (nv <= 0)
            {
              msg (SE, _("Vectors must have at least one element."));
              goto fail;
            }
-         if (!lex_force_match (')'))
+         if (!lex_force_match (lexer, ')'))
            goto fail;
 
          /* First check that all the generated variable names
@@ -196,11 +196,11 @@
       free (vecnames);
       vecnames = NULL;
     }
-  while (lex_match ('/'));
+  while (lex_match (lexer, '/'));
 
-  if (token != '.')
+  if (lex_token (lexer) != '.')
     {
-      lex_error (_("expecting end of command"));
+      lex_error (lexer, _("expecting end of command"));
       goto fail;
     }
   return CMD_SUCCESS;

Index: language/dictionary/weight.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/dictionary/weight.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- language/dictionary/weight.c        26 Oct 2006 06:16:36 -0000      1.7
+++ language/dictionary/weight.c        11 Nov 2006 23:10:00 -0000      1.8
@@ -34,17 +34,17 @@
 #define _(msgid) gettext (msgid)
 
 int
-cmd_weight (struct dataset *ds)
+cmd_weight (struct lexer *lexer, struct dataset *ds)
 {
   struct dictionary *dict = dataset_dict (ds);
-  if (lex_match_id ("OFF"))
+  if (lex_match_id (lexer, "OFF"))
     dict_set_weight (dataset_dict (ds), NULL);
   else
     {
       struct variable *v;
 
-      lex_match (T_BY);
-      v = parse_variable (dict);
+      lex_match (lexer, T_BY);
+      v = parse_variable (lexer, dict);
       if (!v)
        return CMD_CASCADING_FAILURE;
       if (v->type == ALPHA)
@@ -61,5 +61,5 @@
       dict_set_weight (dict, v);
     }
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }

Index: language/expressions/evaluate.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/expressions/evaluate.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- language/expressions/evaluate.c     3 Nov 2006 04:53:51 -0000       1.9
+++ language/expressions/evaluate.c     11 Nov 2006 23:10:00 -0000      1.10
@@ -109,7 +109,7 @@
 #include <language/command.h>
 
 int
-cmd_debug_evaluate (struct dataset *dsother UNUSED)
+cmd_debug_evaluate (struct lexer *lexer, struct dataset *dsother UNUSED)
 {
   bool optimize = true;
   int retval = CMD_FAILURE;
@@ -124,38 +124,38 @@
   for (;;) 
     {
       struct dictionary *d = NULL;
-      if (lex_match_id ("NOOPTIMIZE"))
+      if (lex_match_id (lexer, "NOOPTIMIZE"))
         optimize = 0;
-      else if (lex_match_id ("POSTFIX"))
+      else if (lex_match_id (lexer, "POSTFIX"))
         dump_postfix = 1;
-      else if (lex_match ('('))
+      else if (lex_match (lexer, '('))
         {
           char name[LONG_NAME_LEN + 1];
           struct variable *v;
           size_t old_value_cnt;
           int width;
 
-          if (!lex_force_id ())
+          if (!lex_force_id (lexer))
             goto done;
-          strcpy (name, tokid);
+          strcpy (name, lex_tokid (lexer));
 
-          lex_get ();
-          if (!lex_force_match ('='))
+          lex_get (lexer);
+          if (!lex_force_match (lexer, '='))
             goto done;
 
-          if (lex_is_number ())
+          if (lex_is_number (lexer))
             {
               width = 0;
-              fprintf (stderr, "(%s = %.2f)", name, tokval); 
+              fprintf (stderr, "(%s = %.2f)", name, lex_tokval (lexer)); 
             }
-          else if (token == T_STRING) 
+          else if (lex_token (lexer) == T_STRING) 
             {
-              width = ds_length (&tokstr);
-              fprintf (stderr, "(%s = \"%.2s\")", name, ds_cstr (&tokstr)); 
+              width = ds_length (lex_tokstr (lexer));
+              fprintf (stderr, "(%s = \"%.2s\")", name, ds_cstr (lex_tokstr 
(lexer))); 
             }
           else
             {
-              lex_error (_("expecting number or string"));
+              lex_error (lexer, _("expecting number or string"));
               goto done;
             }
          
@@ -181,32 +181,32 @@
           else
             case_resize (c, old_value_cnt, dict_get_next_value_idx (d));
 
-          if (lex_is_number ())
-            case_data_rw (c, v->fv)->f = tokval;
+          if (lex_is_number (lexer))
+            case_data_rw (c, v->fv)->f = lex_tokval (lexer);
           else
-            memcpy (case_data_rw (c, v->fv)->s, ds_data (&tokstr),
+            memcpy (case_data_rw (c, v->fv)->s, ds_data (lex_tokstr (lexer)),
                     v->width);
-          lex_get ();
+          lex_get (lexer);
 
-          if (!lex_force_match (')'))
+          if (!lex_force_match (lexer, ')'))
             goto done;
         }
       else 
         break;
     }
-  if (token != '/') 
+  if (lex_token (lexer) != '/') 
     {
-      lex_force_match ('/');
+      lex_force_match (lexer, '/');
       goto done;
     }
 
   if ( ds != NULL ) 
     fprintf(stderr, "; ");
-  fprintf (stderr, "%s => ", lex_rest_of_line (NULL));
-  lex_get ();
+  fprintf (stderr, "%s => ", lex_rest_of_line (lexer, NULL));
+  lex_get (lexer);
 
-  expr = expr_parse_any (ds, optimize);
-  if (!expr || lex_end_of_command () != CMD_SUCCESS)
+  expr = expr_parse_any (lexer, ds, optimize);
+  if (!expr || lex_end_of_command (lexer) != CMD_SUCCESS)
     {
       if (expr != NULL)
         expr_free (expr);

Index: language/expressions/parse.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/expressions/parse.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- language/expressions/parse.c        3 Nov 2006 04:53:51 -0000       1.17
+++ language/expressions/parse.c        11 Nov 2006 23:10:00 -0000      1.18
@@ -45,7 +45,7 @@
 /* Declarations. */
 
 /* Recursive descent parser in order of increasing precedence. */
-typedef union any_node *parse_recursively_func (struct expression *);
+typedef union any_node *parse_recursively_func (struct lexer *, struct 
expression *);
 static parse_recursively_func parse_or, parse_and, parse_not;
 static parse_recursively_func parse_rel, parse_add, parse_mul;
 static parse_recursively_func parse_neg, parse_exp;
@@ -73,7 +73,7 @@
    Returns the new expression if successful or a null pointer
    otherwise. */
 struct expression *
-expr_parse (struct dataset *ds, enum expr_type type) 
+expr_parse (struct lexer *lexer, struct dataset *ds, enum expr_type type) 
 {
   union any_node *n;
   struct expression *e;
@@ -81,7 +81,7 @@
   assert (type == EXPR_NUMBER || type == EXPR_STRING || type == EXPR_BOOLEAN);
 
   e = expr_create (ds);
-  n = parse_or (e);
+  n = parse_or (lexer, e);
   if (n != NULL && type_check (e, &n, type))
     return finish_expression (expr_optimize (n, e), e);
   else
@@ -95,11 +95,12 @@
    expr_parse(), and sets up so that destroying POOL will free
    the expression as well. */
 struct expression *
-expr_parse_pool (struct pool *pool,
+expr_parse_pool (struct lexer *lexer, 
+                struct pool *pool,
                 struct dataset *ds, 
                  enum expr_type type) 
 {
-  struct expression *e = expr_parse (ds, type);
+  struct expression *e = expr_parse (lexer, ds, type);
   if (e != NULL)
     pool_add_subpool (pool, e->expr_pool);
   return e;
@@ -114,13 +115,13 @@
 }
 
 struct expression *
-expr_parse_any (struct dataset *ds, bool optimize)
+expr_parse_any (struct lexer *lexer, struct dataset *ds, bool optimize)
 {
   union any_node *n;
   struct expression *e;
 
   e = expr_create (ds);
-  n = parse_or (e);
+  n = parse_or (lexer, e);
   if (n == NULL)
     {
       expr_free (e);
@@ -469,7 +470,7 @@
    On failure, returns false and, if OPERATOR is non-null, sets
    *OPERATOR to a null pointer. */
 static bool
-match_operator (const struct operator ops[], size_t op_cnt,
+match_operator (struct lexer *lexer, const struct operator ops[], size_t 
op_cnt,
                 const struct operator **operator) 
 {
   const struct operator *op;
@@ -477,8 +478,8 @@
   for (op = ops; op < ops + op_cnt; op++)
     {
       if (op->token == '-')
-        lex_negative_to_dash ();
-      if (lex_match (op->token)) 
+        lex_negative_to_dash (lexer);
+      if (lex_match (lexer, op->token)) 
         {
           if (operator != NULL)
             *operator = op;
@@ -529,7 +530,7 @@
    is non-null, then it will be issued as a warning if more than
    one operator/operand pair is parsed. */
 static union any_node *
-parse_binary_operators (struct expression *e, union any_node *node,
+parse_binary_operators (struct lexer *lexer, struct expression *e, union 
any_node *node,
                         const struct operator ops[], size_t op_cnt,
                         parse_recursively_func *parse_next_level,
                         const char *chain_warning)
@@ -542,7 +543,7 @@
   if (node == NULL)
     return node;
 
-  for (op_count = 0; match_operator (ops, op_cnt, &operator); op_count++)
+  for (op_count = 0; match_operator (lexer, ops, op_cnt, &operator); 
op_count++)
     {
       union any_node *rhs;
 
@@ -552,7 +553,7 @@
 
       /* Parse the right-hand side and coerce to type
          OPERAND_TYPE. */
-      rhs = parse_next_level (e);
+      rhs = parse_next_level (lexer, e);
       if (!type_coercion (e, operand_type, &rhs, operator->name))
         return NULL;
       node = expr_allocate_binary (e, operator->type, node, rhs);
@@ -565,7 +566,7 @@
 }
 
 static union any_node *
-parse_inverting_unary_operator (struct expression *e,
+parse_inverting_unary_operator (struct lexer *lexer, struct expression *e,
                                 const struct operator *op,
                                 parse_recursively_func *parse_next_level) 
 {
@@ -575,10 +576,10 @@
   check_operator (op, 1, get_operand_type (op));
 
   op_count = 0;
-  while (match_operator (op, 1, NULL))
+  while (match_operator (lexer, op, 1, NULL))
     op_count++;
 
-  node = parse_next_level (e);
+  node = parse_next_level (lexer, e);
   if (op_count > 0
       && type_coercion (e, get_operand_type (op), &node, op->name)
       && op_count % 2 != 0)
@@ -589,36 +590,37 @@
 
 /* Parses the OR level. */
 static union any_node *
-parse_or (struct expression *e)
+parse_or (struct lexer *lexer, struct expression *e)
 {
   static const struct operator op = 
     { T_OR, OP_OR, "logical disjunction (\"OR\")" };
   
-  return parse_binary_operators (e, parse_and (e), &op, 1, parse_and, NULL);
+  return parse_binary_operators (lexer, e, parse_and (lexer, e), &op, 1, 
parse_and, NULL);
 }
 
 /* Parses the AND level. */
 static union any_node *
-parse_and (struct expression *e)
+parse_and (struct lexer *lexer, struct expression *e)
 {
   static const struct operator op = 
     { T_AND, OP_AND, "logical conjunction (\"AND\")" };
   
-  return parse_binary_operators (e, parse_not (e), &op, 1, parse_not, NULL);
+  return parse_binary_operators (lexer, e, parse_not (lexer, e), 
+                                &op, 1, parse_not, NULL);
 }
 
 /* Parses the NOT level. */
 static union any_node *
-parse_not (struct expression *e)
+parse_not (struct lexer *lexer, struct expression *e)
 {
   static const struct operator op
     = { T_NOT, OP_NOT, "logical negation (\"NOT\")" };
-  return parse_inverting_unary_operator (e, &op, parse_rel);
+  return parse_inverting_unary_operator (lexer, e, &op, parse_rel);
 }
 
 /* Parse relational operators. */
 static union any_node *
-parse_rel (struct expression *e)
+parse_rel (struct lexer *lexer, struct expression *e)
 {
   const char *chain_warning = 
     _("Chaining relational operators (e.g. \"a < b < c\") will "
@@ -628,7 +630,7 @@
       "If chaining is really intended, parentheses will disable "
       "this warning (e.g. \"(a < b) < c\".)");
 
-  union any_node *node = parse_add (e);
+  union any_node *node = parse_add (lexer, e);
 
   if (node == NULL)
     return NULL;
@@ -649,7 +651,8 @@
             { T_NE, OP_NE, "numeric inequality (\"<>\")" },
           };
 
-        return parse_binary_operators (e, node, ops, sizeof ops / sizeof *ops,
+        return parse_binary_operators (lexer, e, node, ops, 
+                                      sizeof ops / sizeof *ops,
                                        parse_add, chain_warning);
       }
       
@@ -666,7 +669,8 @@
             { T_NE, OP_NE_STRING, "string inequality (\"<>\")" },
           };
 
-        return parse_binary_operators (e, node, ops, sizeof ops / sizeof *ops,
+        return parse_binary_operators (lexer, e, node, ops, 
+                                      sizeof ops / sizeof *ops,
                                        parse_add, chain_warning);
       }
       
@@ -677,7 +681,7 @@
 
 /* Parses the addition and subtraction level. */
 static union any_node *
-parse_add (struct expression *e)
+parse_add (struct lexer *lexer, struct expression *e)
 {
   static const struct operator ops[] = 
     {
@@ -685,14 +689,14 @@
       { '-', OP_SUB, "subtraction (\"-\")" },
     };
   
-  return parse_binary_operators (e, parse_mul (e),
+  return parse_binary_operators (lexer, e, parse_mul (lexer, e),
                                  ops, sizeof ops / sizeof *ops,
                                  parse_mul, NULL);
 }
 
 /* Parses the multiplication and division level. */
 static union any_node *
-parse_mul (struct expression *e)
+parse_mul (struct lexer *lexer, struct expression *e)
 {
   static const struct operator ops[] = 
     {
@@ -700,21 +704,21 @@
       { '/', OP_DIV, "division (\"/\")" },
     };
   
-  return parse_binary_operators (e, parse_neg (e),
+  return parse_binary_operators (lexer, e, parse_neg (lexer, e),
                                  ops, sizeof ops / sizeof *ops,
                                  parse_neg, NULL);
 }
 
 /* Parses the unary minus level. */
 static union any_node *
-parse_neg (struct expression *e)
+parse_neg (struct lexer *lexer, struct expression *e)
 {
   static const struct operator op = { '-', OP_NEG, "negation (\"-\")" };
-  return parse_inverting_unary_operator (e, &op, parse_exp);
+  return parse_inverting_unary_operator (lexer, e, &op, parse_exp);
 }
 
 static union any_node *
-parse_exp (struct expression *e)
+parse_exp (struct lexer *lexer, struct expression *e)
 {
   static const struct operator op = 
     { T_EXP, OP_POW, "exponentiation (\"**\")" };
@@ -725,17 +729,17 @@
       "That is, \"a**b**c\" equals \"(a**b)**c\", not as \"a**(b**c)\".  "
       "To disable this warning, insert parentheses.");
 
-  return parse_binary_operators (e, parse_primary (e), &op, 1,
+  return parse_binary_operators (lexer, e, parse_primary (lexer, e), &op, 1,
                                  parse_primary, chain_warning);
 }
 
 /* Parses system variables. */
 static union any_node *
-parse_sysvar (struct expression *e)
+parse_sysvar (struct lexer *lexer, struct expression *e)
 {
-  if (lex_match_id ("$CASENUM"))
+  if (lex_match_id (lexer, "$CASENUM"))
     return expr_allocate_nullary (e, OP_CASENUM);
-  else if (lex_match_id ("$DATE"))
+  else if (lex_match_id (lexer, "$DATE"))
     {
       static const char *months[12] =
         {
@@ -753,13 +757,13 @@
 
       return expr_allocate_string_buffer (e, temp_buf, strlen (temp_buf));
     }
-  else if (lex_match_id ("$TRUE"))
+  else if (lex_match_id (lexer, "$TRUE"))
     return expr_allocate_boolean (e, 1.0);
-  else if (lex_match_id ("$FALSE"))
+  else if (lex_match_id (lexer, "$FALSE"))
     return expr_allocate_boolean (e, 0.0);
-  else if (lex_match_id ("$SYSMIS"))
+  else if (lex_match_id (lexer, "$SYSMIS"))
     return expr_allocate_number (e, SYSMIS);
-  else if (lex_match_id ("$JDATE"))
+  else if (lex_match_id (lexer, "$JDATE"))
     {
       time_t time = time_of_last_procedure (e->ds);
       struct tm *tm = localtime (&time);
@@ -767,7 +771,7 @@
                                                        tm->tm_mon + 1,
                                                        tm->tm_mday));
     }
-  else if (lex_match_id ("$TIME"))
+  else if (lex_match_id (lexer, "$TIME"))
     {
       time_t time = time_of_last_procedure (e->ds);
       struct tm *tm = localtime (&time);
@@ -779,45 +783,45 @@
                                    + tm->tm_min * 60.
                                    + tm->tm_sec);
     }
-  else if (lex_match_id ("$LENGTH"))
+  else if (lex_match_id (lexer, "$LENGTH"))
     return expr_allocate_number (e, get_viewlength ());
-  else if (lex_match_id ("$WIDTH"))
+  else if (lex_match_id (lexer, "$WIDTH"))
     return expr_allocate_number (e, get_viewwidth ());
   else
     {
-      msg (SE, _("Unknown system variable %s."), tokid);
+      msg (SE, _("Unknown system variable %s."), lex_tokid (lexer));
       return NULL;
     }
 }
 
 /* Parses numbers, varnames, etc. */
 static union any_node *
-parse_primary (struct expression *e)
+parse_primary (struct lexer *lexer, struct expression *e)
 {
-  switch (token)
+  switch (lex_token (lexer))
     {
     case T_ID:
-      if (lex_look_ahead () == '(') 
+      if (lex_look_ahead (lexer) == '(') 
         {
           /* An identifier followed by a left parenthesis may be
              a vector element reference.  If not, it's a function
              call. */
-          if (e->ds != NULL && dict_lookup_vector (dataset_dict (e->ds), 
tokid) != NULL) 
-            return parse_vector_element (e);
+          if (e->ds != NULL && dict_lookup_vector (dataset_dict (e->ds), 
lex_tokid (lexer)) != NULL) 
+            return parse_vector_element (lexer, e);
           else
-            return parse_function (e);
+            return parse_function (lexer, e);
         }
-      else if (tokid[0] == '$')
+      else if (lex_tokid (lexer)[0] == '$')
         {
           /* $ at the beginning indicates a system variable. */
-          return parse_sysvar (e);
+          return parse_sysvar (lexer, e);
         }
-      else if (e->ds != NULL && dict_lookup_var (dataset_dict (e->ds), tokid))
+      else if (e->ds != NULL && dict_lookup_var (dataset_dict (e->ds), 
lex_tokid (lexer)))
         {
           /* It looks like a user variable.
              (It could be a format specifier, but we'll assume
              it's a variable unless proven otherwise. */
-          return allocate_unary_variable (e, parse_variable (dataset_dict 
(e->ds)));
+          return allocate_unary_variable (e, parse_variable (lexer, 
dataset_dict (e->ds)));
         }
       else 
         {
@@ -826,14 +830,14 @@
           bool ok;
           
           msg_disable ();
-          ok = parse_format_specifier (&fmt);
+          ok = parse_format_specifier (lexer, &fmt);
           msg_enable ();
 
           if (ok)
             return expr_allocate_format (e, &fmt);
 
           /* All attempts failed. */
-          msg (SE, _("Unknown identifier %s."), tokid);
+          msg (SE, _("Unknown identifier %s."), lex_tokid (lexer));
           return NULL;
         }
       break;
@@ -841,40 +845,40 @@
     case T_POS_NUM: 
     case T_NEG_NUM: 
       {
-        union any_node *node = expr_allocate_number (e, tokval);
-        lex_get ();
+        union any_node *node = expr_allocate_number (e, lex_tokval (lexer) );
+        lex_get (lexer);
         return node; 
       }
 
     case T_STRING:
       {
         union any_node *node = expr_allocate_string_buffer (
-          e, ds_cstr (&tokstr), ds_length (&tokstr));
-       lex_get ();
+          e, ds_cstr (lex_tokstr (lexer) ), ds_length (lex_tokstr (lexer) ));
+       lex_get (lexer);
        return node;
       }
 
     case '(':
       {
         union any_node *node;
-       lex_get ();
-       node = parse_or (e);
-       if (node != NULL && !lex_match (')'))
+       lex_get (lexer);
+       node = parse_or (lexer, e);
+       if (node != NULL && !lex_match (lexer, ')'))
          {
-           lex_error (_("expecting `)'"));
+           lex_error (lexer, _("expecting `)'"));
             return NULL;
          }
         return node;
       }
 
     default:
-      lex_error (_("in expression"));
+      lex_error (lexer, _("in expression"));
       return NULL;
     }
 }
 
 static union any_node *
-parse_vector_element (struct expression *e)
+parse_vector_element (struct lexer *lexer, struct expression *e)
 {
   const struct vector *vector;
   union any_node *element;
@@ -882,19 +886,19 @@
   /* Find vector, skip token.
      The caller must already have verified that the current token
      is the name of a vector. */
-  vector = dict_lookup_vector (dataset_dict (e->ds), tokid);
+  vector = dict_lookup_vector (dataset_dict (e->ds), lex_tokid (lexer));
   assert (vector != NULL);
-  lex_get ();
+  lex_get (lexer);
 
   /* Skip left parenthesis token.
      The caller must have verified that the lookahead is a left
      parenthesis. */
-  assert (token == '(');
-  lex_get ();
+  assert (lex_token (lexer) == '(');
+  lex_get (lexer);
 
-  element = parse_or (e);
+  element = parse_or (lexer, e);
   if (!type_coercion (e, OP_number, &element, "vector indexing")
-      || !lex_match (')'))
+      || !lex_match (lexer, ')'))
     return NULL;
 
   return expr_allocate_binary (e, (vector->var[0]->type == NUMERIC
@@ -1155,7 +1159,7 @@
 }
 
 static union any_node *
-parse_function (struct expression *e)
+parse_function (struct lexer *lexer, struct expression *e)
 {
   int min_valid;
   const struct operation *f, *first, *last;
@@ -1168,17 +1172,17 @@
 
   union any_node *n;
 
-  ds_init_string (&func_name, &tokstr);
-  min_valid = extract_min_valid (ds_cstr (&tokstr));
-  if (!lookup_function (ds_cstr (&tokstr), &first, &last)) 
+  ds_init_string (&func_name, lex_tokstr (lexer));
+  min_valid = extract_min_valid (ds_cstr (lex_tokstr (lexer)));
+  if (!lookup_function (ds_cstr (lex_tokstr (lexer)), &first, &last)) 
     {
-      msg (SE, _("No function or vector named %s."), ds_cstr (&tokstr));
+      msg (SE, _("No function or vector named %s."), ds_cstr (lex_tokstr 
(lexer)));
       ds_destroy (&func_name);
       return NULL;
     }
 
-  lex_get ();
-  if (!lex_force_match ('(')) 
+  lex_get (lexer);
+  if (!lex_force_match (lexer, '(')) 
     {
       ds_destroy (&func_name);
       return NULL; 
@@ -1186,16 +1190,16 @@
   
   args = NULL;
   arg_cnt = arg_cap = 0;
-  if (token != ')')
+  if (lex_token (lexer) != ')')
     for (;;)
       {
-        if (token == T_ID && lex_look_ahead () == 'T')
+        if (lex_token (lexer) == T_ID && lex_look_ahead (lexer) == 'T')
           {
             struct variable **vars;
             size_t var_cnt;
             size_t i;
 
-            if (!parse_variables (dataset_dict (e->ds), &vars, &var_cnt, 
PV_SINGLE))
+            if (!parse_variables (lexer, dataset_dict (e->ds), &vars, 
&var_cnt, PV_SINGLE))
               goto fail;
             for (i = 0; i < var_cnt; i++)
               add_arg (&args, &arg_cnt, &arg_cap,
@@ -1204,17 +1208,17 @@
           }
         else
           {
-            union any_node *arg = parse_or (e);
+            union any_node *arg = parse_or (lexer, e);
             if (arg == NULL)
               goto fail;
 
             add_arg (&args, &arg_cnt, &arg_cap, arg);
           }
-        if (lex_match (')'))
+        if (lex_match (lexer, ')'))
           break;
-        else if (!lex_match (','))
+        else if (!lex_match (lexer, ','))
           {
-            lex_error (_("expecting `,' or `)' invoking %s function"),
+            lex_error (lexer, _("expecting `,' or `)' invoking %s function"),
                        first->name);
             goto fail;
           }

Index: language/expressions/private.h
===================================================================
RCS file: /sources/pspp/pspp/src/language/expressions/private.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- language/expressions/private.h      26 Oct 2006 06:16:36 -0000      1.6
+++ language/expressions/private.h      11 Nov 2006 23:10:00 -0000      1.7
@@ -168,7 +168,7 @@
     struct pool *eval_pool;     /* Pool for evaluation temporaries. */
   };
 
-struct expression *expr_parse_any (struct dataset *,  bool optimize);
+struct expression *expr_parse_any (struct lexer *lexer, struct dataset *,  
bool optimize);
 void expr_debug_print_postfix (const struct expression *);
 
 union any_node *expr_optimize (union any_node *, struct expression *);

Index: language/expressions/public.h
===================================================================
RCS file: /sources/pspp/pspp/src/language/expressions/public.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- language/expressions/public.h       26 Oct 2006 06:16:36 -0000      1.2
+++ language/expressions/public.h       11 Nov 2006 23:10:00 -0000      1.3
@@ -36,9 +36,11 @@
 struct pool;
 union value;
 struct dataset ;
+struct lexer ;
 
-struct expression *expr_parse (struct dataset *, enum expr_type);
-struct expression *expr_parse_pool (struct pool *,
+struct expression *expr_parse (struct lexer *lexer, struct dataset *, enum 
expr_type);
+struct expression *expr_parse_pool (struct lexer *, 
+                                   struct pool *,
                                    struct dataset *,
                                     enum expr_type);
 void expr_free (struct expression *);

Index: language/lexer/ChangeLog
===================================================================
RCS file: /sources/pspp/pspp/src/language/lexer/ChangeLog,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -b -r1.16 -r1.17
--- language/lexer/ChangeLog    1 Nov 2006 02:12:25 -0000       1.16
+++ language/lexer/ChangeLog    11 Nov 2006 23:10:00 -0000      1.17
@@ -1,3 +1,12 @@
+Sun Nov 12 06:34:06 WST 2006 John Darrrington <address@hidden>
+
+       * format-parser.c format-parser.h lexer.c lexer.h q2c.c range-parser.c
+         range-parser.h subcommand-list.c variable-parser.c
+         variable-parser.h:
+
+       Encapsulated the lexer into an object, and updated everything
+       accordingly.
+
 Tue Oct 31 18:09:32 2006  Ben Pfaff  <address@hidden>
 
        * range-parser.c (parse_number): Fix error message.

Index: language/lexer/format-parser.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/lexer/format-parser.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- language/lexer/format-parser.c      3 Nov 2006 04:53:51 -0000       1.6
+++ language/lexer/format-parser.c      11 Nov 2006 23:10:00 -0000      1.7
@@ -47,18 +47,18 @@
    format.  Both width and decimals are considered optional.  If
    missing, *WIDTH or *DECIMALS or both will be set to 0. */
 bool
-parse_abstract_format_specifier (char type[FMT_TYPE_LEN_MAX + 1],
+parse_abstract_format_specifier (struct lexer *lexer, char 
type[FMT_TYPE_LEN_MAX + 1],
                                  int *width, int *decimals) 
 {
   struct substring s;
   struct substring type_ss, width_ss, decimals_ss;
   bool has_decimals;
 
-  if (token != T_ID)
+  if (lex_token (lexer) != T_ID)
     goto error;
 
   /* Extract pieces. */
-  s = ds_ss (&tokstr);
+  s = ds_ss (lex_tokstr (lexer));
   ss_get_chars (&s, ss_span (s, ss_cstr (CC_LETTERS)), &type_ss);
   ss_get_chars (&s, ss_span (s, ss_cstr (CC_DIGITS)), &width_ss);
   if (ss_match_char (&s, '.')) 
@@ -85,11 +85,11 @@
   *width = strtol (ss_data (width_ss), NULL, 10);
   *decimals = has_decimals ? strtol (ss_data (decimals_ss), NULL, 10) : 0;
 
-  lex_get ();
+  lex_get (lexer);
   return true;
 
  error:
-  lex_error (_("expecting valid format specifier"));
+  lex_error (lexer, _("expecting valid format specifier"));
   return false;
 }
 
@@ -99,11 +99,11 @@
    check_output_specifier() on the parsed format as
    necessary.  */
 bool
-parse_format_specifier (struct fmt_spec *format)
+parse_format_specifier (struct lexer *lexer, struct fmt_spec *format)
 {
   char type[FMT_TYPE_LEN_MAX + 1];
 
-  if (!parse_abstract_format_specifier (type, &format->w, &format->d))
+  if (!parse_abstract_format_specifier (lexer, type, &format->w, &format->d))
     return false;
 
   if (!fmt_from_name (type, &format->type))
@@ -118,18 +118,18 @@
 /* Parses a token containing just the name of a format type and
    returns true if successful. */
 bool
-parse_format_specifier_name (enum fmt_type *type) 
+parse_format_specifier_name (struct lexer *lexer, enum fmt_type *type) 
 {
-  if (token != T_ID) 
+  if (lex_token (lexer) != T_ID) 
     {
-      lex_error (_("expecting format type"));
+      lex_error (lexer, _("expecting format type"));
       return false;
     }
-  if (!fmt_from_name (ds_cstr (&tokstr), type))
+  if (!fmt_from_name (ds_cstr (lex_tokstr (lexer)), type))
     {
-      msg (SE, _("Unknown format type \"%s\"."), ds_cstr (&tokstr));
+      msg (SE, _("Unknown format type \"%s\"."), ds_cstr (lex_tokstr (lexer)));
       return false;
     }
-  lex_get ();
+  lex_get (lexer);
   return true;
 }

Index: language/lexer/format-parser.h
===================================================================
RCS file: /sources/pspp/pspp/src/language/lexer/format-parser.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- language/lexer/format-parser.h      5 Nov 2006 05:20:53 -0000       1.3
+++ language/lexer/format-parser.h      11 Nov 2006 23:10:00 -0000      1.4
@@ -24,9 +24,12 @@
 
 #include <data/format.h>
 
-bool parse_abstract_format_specifier (char type[FMT_TYPE_LEN_MAX + 1],
+
+struct lexer;
+
+bool parse_abstract_format_specifier (struct lexer *, char 
type[FMT_TYPE_LEN_MAX + 1],
                                       int *width, int *decimals);
-bool parse_format_specifier (struct fmt_spec *);
-bool parse_format_specifier_name (enum fmt_type *type);
+bool parse_format_specifier (struct lexer *, struct fmt_spec *);
+bool parse_format_specifier_name (struct lexer *, enum fmt_type *type);
 
 #endif /* language/lexer/format-parser.h. */

Index: language/lexer/lexer.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/lexer/lexer.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- language/lexer/lexer.c      28 Oct 2006 08:31:23 -0000      1.11
+++ language/lexer/lexer.c      11 Nov 2006 23:10:00 -0000      1.12
@@ -45,38 +45,34 @@
 #define DUMP_TOKENS 1
 */
 
+struct lexer 
+{
+  struct string line_buffer;
 
-/* Current token. */
-int token;
+  bool (*read_line) (struct string *, bool *);
 
-/* T_POS_NUM, T_NEG_NUM: the token's value. */
-double tokval;
+  int token;      /* Current token. */
+  double tokval;  /* T_POS_NUM, T_NEG_NUM: the token's value. */
 
-/* T_ID: the identifier. */
-char tokid[LONG_NAME_LEN + 1];
+  char tokid [LONG_NAME_LEN + 1];   /* T_ID: the identifier. */
 
-/* T_ID, T_STRING: token string value.
-   For T_ID, this is not truncated as is tokid. */
-struct string tokstr;
+  struct string tokstr;   /* T_ID, T_STRING: token string value.
+                           For T_ID, this is not truncated as is 
+                           tokid. */
 
-/* Static variables. */
+  char *prog; /* Pointer to next token in line_buffer. */
+  bool dot;   /* True only if this line ends with a terminal dot. */
+  bool eof;   /* True only if the last token returned was T_STOP. */
 
-/* Pointer to next token in line_buffer. */
-static char *prog;
+  int put_token ; /* If nonzero, next token returned by lex_get().
+                   Used only in exceptional circumstances. */
 
-/* True only if this line ends with a terminal dot. */
-static bool dot;
+  struct string put_tokstr;
+  double put_tokval;
+};
 
-/* True only if the last token returned was T_STOP. */
-static bool eof;
 
-/* If nonzero, next token returned by lex_get().
-   Used only in exceptional circumstances. */
-static int put_token;
-static struct string put_tokstr;
-static double put_tokval;
-
-static int parse_id (void);
+static int parse_id (struct lexer *);
 
 /* How a string represents its contents. */
 enum string_type 
@@ -87,7 +83,7 @@
     HEX_STRING          /* Hexadecimal digits. */
   };
 
-static int parse_string (enum string_type);
+static int parse_string (struct lexer *, enum string_type);
 
 #if DUMP_TOKENS
 static void dump_token (void);
@@ -95,66 +91,68 @@
 
 /* Initialization. */
 
-static struct string line_buffer;
-
-static bool (*lex_read_line) (struct string *, bool *);
-
 /* Initializes the lexer. */
-void
-lex_init (bool (*read_line_func) (struct string *, bool *))
+struct lexer *
+lex_create (bool (*read_line_func) (struct string *, bool *))
 {
-  ds_init_empty (&tokstr);
-  ds_init_empty (&put_tokstr);
-  ds_init_empty (&line_buffer);
-  lex_read_line = read_line_func;
+  struct lexer *lexer = xzalloc (sizeof (*lexer));
+
+  ds_init_empty (&lexer->tokstr);
+  ds_init_empty (&lexer->put_tokstr);
+  ds_init_empty (&lexer->line_buffer);
+  lexer->read_line = read_line_func;
 
-  if (!lex_get_line ())
-    eof = true;
+  if (!lex_get_line (lexer))
+    lexer->eof = true;
+
+  return lexer;
 }
 
 void
-lex_done (void)
+lex_destroy (struct lexer *lexer)
 {
-  ds_destroy (&put_tokstr);
-  ds_destroy (&tokstr);
-  ds_destroy (&line_buffer);
+  ds_destroy (&lexer->put_tokstr);
+  ds_destroy (&lexer->tokstr);
+  ds_destroy (&lexer->line_buffer);
+
+  free (lexer);
 }
 
 
 /* Common functions. */
 
-/* Copies put_token, put_tokstr, put_tokval into token, tokstr,
+/* Copies put_token, lexer->put_tokstr, put_tokval into token, tokstr,
    tokval, respectively, and sets tokid appropriately. */
 static void
-restore_token (void) 
+restore_token (struct lexer *lexer) 
 {
-  assert (put_token != 0);
-  token = put_token;
-  ds_assign_string (&tokstr, &put_tokstr);
-  str_copy_trunc (tokid, sizeof tokid, ds_cstr (&tokstr));
-  tokval = put_tokval;
-  put_token = 0;
+  assert (lexer->put_token != 0);
+  lexer->token = lexer->put_token;
+  ds_assign_string (&lexer->tokstr, &lexer->put_tokstr);
+  str_copy_trunc (lexer->tokid, sizeof lexer->tokid, ds_cstr (&lexer->tokstr));
+  lexer->tokval = lexer->put_tokval;
+  lexer->put_token = 0;
 }
 
-/* Copies token, tokstr, tokval into put_token, put_tokstr,
-   put_tokval respectively. */
+/* Copies token, tokstr, lexer->tokval into lexer->put_token, put_tokstr,
+   put_lexer->tokval respectively. */
 static void
-save_token (void) 
+save_token (struct lexer *lexer) 
 {
-  put_token = token;
-  ds_assign_string (&put_tokstr, &tokstr);
-  put_tokval = tokval;
+  lexer->put_token = lexer->token;
+  ds_assign_string (&lexer->put_tokstr, &lexer->tokstr);
+  lexer->put_tokval = lexer->tokval;
 }
 
 /* Parses a single token, setting appropriate global variables to
    indicate the token's attributes. */
 void
-lex_get (void)
+lex_get (struct lexer *lexer)
 {
   /* If a token was pushed ahead, return it. */
-  if (put_token)
+  if (lexer->put_token)
     {
-      restore_token ();
+      restore_token (lexer);
 #if DUMP_TOKENS
       dump_token ();
 #endif
@@ -165,41 +163,41 @@
   for (;;)
     {
       /* Skip whitespace. */
-      if (eof) 
+      if (lexer->eof) 
         {
-          token = T_STOP;
+          lexer->token = T_STOP;
           return;
         }
 
       for (;;)
        {
-         while (isspace ((unsigned char) *prog))
-           prog++;
-         if (*prog)
+         while (isspace ((unsigned char) *lexer->prog))
+           lexer->prog++;
+         if (*lexer->prog)
            break;
 
-         if (dot)
+         if (lexer->dot)
            {
-             dot = 0;
-             token = '.';
+             lexer->dot = 0;
+             lexer->token = '.';
 #if DUMP_TOKENS
              dump_token ();
 #endif
              return;
            }
-         else if (!lex_get_line ())
+         else if (!lex_get_line (lexer))
            {
-             eof = true;
-             token = T_STOP;
+             lexer->eof = true;
+             lexer->token = T_STOP;
 #if DUMP_TOKENS
              dump_token ();
 #endif
              return;
            }
 
-         if (put_token)
+         if (lexer->put_token)
            {
-              restore_token ();
+              restore_token (lexer);
 #if DUMP_TOKENS
              dump_token ();
 #endif
@@ -209,9 +207,9 @@
 
 
       /* Actually parse the token. */
-      ds_clear (&tokstr);
+      ds_clear (&lexer->tokstr);
       
-      switch (*prog)
+      switch (*lexer->prog)
        {
        case '-': case '.':
        case '0': case '1': case '2': case '3': case '4':
@@ -226,151 +224,151 @@
               want it as a number.  When the syntax calls for a `-'
               token, lex_negative_to_dash() must be used to break
               negative numbers into two tokens. */
-           if (*prog == '-')
+           if (*lexer->prog == '-')
              {
-               ds_put_char (&tokstr, *prog++);
-               while (isspace ((unsigned char) *prog))
-                 prog++;
+               ds_put_char (&lexer->tokstr, *lexer->prog++);
+               while (isspace ((unsigned char) *lexer->prog))
+                 lexer->prog++;
 
-               if (!isdigit ((unsigned char) *prog) && *prog != '.')
+               if (!isdigit ((unsigned char) *lexer->prog) && *lexer->prog != 
'.')
                  {
-                   token = '-';
+                   lexer->token = '-';
                    break;
                  }
-                token = T_NEG_NUM;
+                lexer->token = T_NEG_NUM;
              }
             else 
-              token = T_POS_NUM;
+              lexer->token = T_POS_NUM;
                 
            /* Parse the number, copying it into tokstr. */
-           while (isdigit ((unsigned char) *prog))
-             ds_put_char (&tokstr, *prog++);
-           if (*prog == '.')
-             {
-               ds_put_char (&tokstr, *prog++);
-               while (isdigit ((unsigned char) *prog))
-                 ds_put_char (&tokstr, *prog++);
-             }
-           if (*prog == 'e' || *prog == 'E')
-             {
-               ds_put_char (&tokstr, *prog++);
-               if (*prog == '+' || *prog == '-')
-                 ds_put_char (&tokstr, *prog++);
-               while (isdigit ((unsigned char) *prog))
-                 ds_put_char (&tokstr, *prog++);
+           while (isdigit ((unsigned char) *lexer->prog))
+             ds_put_char (&lexer->tokstr, *lexer->prog++);
+           if (*lexer->prog == '.')
+             {
+               ds_put_char (&lexer->tokstr, *lexer->prog++);
+               while (isdigit ((unsigned char) *lexer->prog))
+                 ds_put_char (&lexer->tokstr, *lexer->prog++);
+             }
+           if (*lexer->prog == 'e' || *lexer->prog == 'E')
+             {
+               ds_put_char (&lexer->tokstr, *lexer->prog++);
+               if (*lexer->prog == '+' || *lexer->prog == '-')
+                 ds_put_char (&lexer->tokstr, *lexer->prog++);
+               while (isdigit ((unsigned char) *lexer->prog))
+                 ds_put_char (&lexer->tokstr, *lexer->prog++);
              }
 
            /* Parse as floating point. */
-           tokval = strtod (ds_cstr (&tokstr), &tail);
+           lexer->tokval = strtod (ds_cstr (&lexer->tokstr), &tail);
            if (*tail)
              {
                msg (SE, _("%s does not form a valid number."),
-                    ds_cstr (&tokstr));
-               tokval = 0.0;
+                    ds_cstr (&lexer->tokstr));
+               lexer->tokval = 0.0;
 
-               ds_clear (&tokstr);
-               ds_put_char (&tokstr, '0');
+               ds_clear (&lexer->tokstr);
+               ds_put_char (&lexer->tokstr, '0');
              }
 
            break;
          }
 
        case '\'': case '"':
-         token = parse_string (CHARACTER_STRING);
+         lexer->token = parse_string (lexer, CHARACTER_STRING);
          break;
 
        case '(': case ')': case ',': case '=': case '+': case '/':
-         token = *prog++;
+         lexer->token = *lexer->prog++;
          break;
 
        case '*':
-         if (*++prog == '*')
+         if (*++lexer->prog == '*')
            {
-             prog++;
-             token = T_EXP;
+             lexer->prog++;
+             lexer->token = T_EXP;
            }
          else
-           token = '*';
+           lexer->token = '*';
          break;
 
        case '<':
-         if (*++prog == '=')
+         if (*++lexer->prog == '=')
            {
-             prog++;
-             token = T_LE;
+             lexer->prog++;
+             lexer->token = T_LE;
            }
-         else if (*prog == '>')
+         else if (*lexer->prog == '>')
            {
-             prog++;
-             token = T_NE;
+             lexer->prog++;
+             lexer->token = T_NE;
            }
          else
-           token = T_LT;
+           lexer->token = T_LT;
          break;
 
        case '>':
-         if (*++prog == '=')
+         if (*++lexer->prog == '=')
            {
-             prog++;
-             token = T_GE;
+             lexer->prog++;
+             lexer->token = T_GE;
            }
          else
-           token = T_GT;
+           lexer->token = T_GT;
          break;
 
        case '~':
-         if (*++prog == '=')
+         if (*++lexer->prog == '=')
            {
-             prog++;
-             token = T_NE;
+             lexer->prog++;
+             lexer->token = T_NE;
            }
          else
-           token = T_NOT;
+           lexer->token = T_NOT;
          break;
 
        case '&':
-         prog++;
-         token = T_AND;
+         lexer->prog++;
+         lexer->token = T_AND;
          break;
 
        case '|':
-         prog++;
-         token = T_OR;
+         lexer->prog++;
+         lexer->token = T_OR;
          break;
 
         case 'b': case 'B':
-          if (prog[1] == '\'' || prog[1] == '"')
-            token = parse_string (BINARY_STRING);
+          if (lexer->prog[1] == '\'' || lexer->prog[1] == '"')
+            lexer->token = parse_string (lexer, BINARY_STRING);
           else
-            token = parse_id ();
+            lexer->token = parse_id (lexer);
           break;
           
         case 'o': case 'O':
-          if (prog[1] == '\'' || prog[1] == '"')
-            token = parse_string (OCTAL_STRING);
+          if (lexer->prog[1] == '\'' || lexer->prog[1] == '"')
+            lexer->token = parse_string (lexer, OCTAL_STRING);
           else
-            token = parse_id ();
+            lexer->token = parse_id (lexer);
           break;
           
         case 'x': case 'X':
-          if (prog[1] == '\'' || prog[1] == '"')
-            token = parse_string (HEX_STRING);
+          if (lexer->prog[1] == '\'' || lexer->prog[1] == '"')
+            lexer->token = parse_string (lexer, HEX_STRING);
           else
-            token = parse_id ();
+            lexer->token = parse_id (lexer);
           break;
           
        default:
-          if (lex_is_id1 (*prog)) 
+          if (lex_is_id1 (*lexer->prog)) 
             {
-              token = parse_id ();
+              lexer->token = parse_id (lexer);
               break; 
             }
           else
             {
-              if (isgraph ((unsigned char) *prog))
-                msg (SE, _("Bad character in input: `%c'."), *prog++);
+              if (isgraph ((unsigned char) *lexer->prog))
+                msg (SE, _("Bad character in input: `%c'."), *lexer->prog++);
               else
-                msg (SE, _("Bad character in input: `\\%o'."), *prog++);
+                msg (SE, _("Bad character in input: `\\%o'."), *lexer->prog++);
               continue; 
             }
         }
@@ -386,14 +384,14 @@
    tokstr.
    Returns the correct token type. */
 static int
-parse_id (void) 
+parse_id (struct lexer *lexer) 
 {
-  const char *start = prog;
-  prog = lex_skip_identifier (start);
+  const char *start = lexer->prog;
+  lexer->prog = lex_skip_identifier (start);
 
-  ds_put_substring (&tokstr, ss_buffer (start, prog - start));
-  str_copy_trunc (tokid, sizeof tokid, ds_cstr (&tokstr));
-  return lex_id_to_token (ds_cstr (&tokstr), ds_length (&tokstr));
+  ds_put_substring (&lexer->tokstr, ss_buffer (start, lexer->prog - start));
+  str_copy_trunc (lexer->tokid, sizeof lexer->tokid, ds_cstr (&lexer->tokstr));
+  return lex_id_to_token (ds_cstr (&lexer->tokstr), ds_length 
(&lexer->tokstr));
 }
 
 /* Reports an error to the effect that subcommand SBC may only be
@@ -407,23 +405,23 @@
 /* Reports an error to the effect that subcommand SBC is
    missing. */
 void
-lex_sbc_missing (const char *sbc) 
+lex_sbc_missing (struct lexer *lexer, const char *sbc) 
 {
-  lex_error (_("missing required subcommand %s"), sbc);
+  lex_error (lexer, _("missing required subcommand %s"), sbc);
 }
 
 /* Prints a syntax error message containing the current token and
    given message MESSAGE (if non-null). */
 void
-lex_error (const char *message, ...)
+lex_error (struct lexer *lexer, const char *message, ...)
 {
   char *token_rep;
   char where[128];
 
-  token_rep = lex_token_representation ();
-  if (token == T_STOP)
+  token_rep = lex_token_representation (lexer);
+  if (lexer->token == T_STOP)
     strcpy (where, "end of file");
-  else if (token == '.')
+  else if (lexer->token == '.')
     strcpy (where, "end of command");
   else
     snprintf (where, sizeof where, "`%s'", token_rep);
@@ -449,11 +447,11 @@
    If not, flags a syntax error and returns an error command
    completion code. */
 int
-lex_end_of_command (void)
+lex_end_of_command (struct lexer *lexer)
 {
-  if (token != '.')
+  if (lexer->token != '.')
     {
-      lex_error (_("expecting end of command"));
+      lex_error (lexer, _("expecting end of command"));
       return CMD_FAILURE;
     }
   else
@@ -464,38 +462,38 @@
 
 /* Returns true if the current token is a number. */
 bool
-lex_is_number (void) 
+lex_is_number (struct lexer *lexer) 
 {
-  return token == T_POS_NUM || token == T_NEG_NUM;
+  return lexer->token == T_POS_NUM || lexer->token == T_NEG_NUM;
 }
 
 /* Returns the value of the current token, which must be a
    floating point number. */
 double
-lex_number (void)
+lex_number (struct lexer *lexer)
 {
-  assert (lex_is_number ());
-  return tokval;
+  assert (lex_is_number (lexer));
+  return lexer->tokval;
 }
 
 /* Returns true iff the current token is an integer. */
 bool
-lex_is_integer (void)
+lex_is_integer (struct lexer *lexer)
 {
-  return (lex_is_number ()
-         && tokval != NOT_LONG
-         && tokval >= LONG_MIN
-         && tokval <= LONG_MAX
-         && floor (tokval) == tokval);
+  return (lex_is_number (lexer)
+         && lexer->tokval != NOT_LONG
+         && lexer->tokval >= LONG_MIN
+         && lexer->tokval <= LONG_MAX
+         && floor (lexer->tokval) == lexer->tokval);
 }
 
 /* Returns the value of the current token, which must be an
    integer. */
 long
-lex_integer (void)
+lex_integer (struct lexer *lexer)
 {
-  assert (lex_is_integer ());
-  return tokval;
+  assert (lex_is_integer (lexer));
+  return lexer->tokval;
 }
   
 /* Token matching functions. */
@@ -503,11 +501,11 @@
 /* If TOK is the current token, skips it and returns true
    Otherwise, returns false. */
 bool
-lex_match (int t)
+lex_match (struct lexer *lexer, int t)
 {
-  if (token == t)
+  if (lexer->token == t)
     {
-      lex_get ();
+      lex_get (lexer);
       return true;
     }
   else
@@ -519,11 +517,11 @@
    letters.
    Otherwise, returns false. */
 bool
-lex_match_id (const char *s)
+lex_match_id (struct lexer *lexer, const char *s)
 {
-  if (token == T_ID && lex_id_match (s, tokid))
+  if (lexer->token == T_ID && lex_id_match (s, lexer->tokid))
     {
-      lex_get ();
+      lex_get (lexer);
       return true;
     }
   else
@@ -533,11 +531,11 @@
 /* If the current token is integer N, skips it and returns true.
    Otherwise, returns false. */
 bool
-lex_match_int (int x)
+lex_match_int (struct lexer *lexer, int x)
 {
-  if (lex_is_integer () && lex_integer () == x)
+  if (lex_is_integer (lexer) && lex_integer (lexer) == x)
     {
-      lex_get ();
+      lex_get (lexer);
       return true;
     }
   else
@@ -550,16 +548,16 @@
    nonzero.
    Otherwise, reports an error and returns zero. */
 bool
-lex_force_match_id (const char *s)
+lex_force_match_id (struct lexer *lexer, const char *s)
 {
-  if (token == T_ID && lex_id_match (s, tokid))
+  if (lexer->token == T_ID && lex_id_match (s, lexer->tokid))
     {
-      lex_get ();
+      lex_get (lexer);
       return true;
     }
   else
     {
-      lex_error (_("expecting `%s'"), s);
+      lex_error (lexer, _("expecting `%s'"), s);
       return false;
     }
 }
@@ -567,16 +565,16 @@
 /* If the current token is T, skips the token.  Otherwise, reports an
    error and returns from the current function with return value false. */
 bool
-lex_force_match (int t)
+lex_force_match (struct lexer *lexer, int t)
 {
-  if (token == t)
+  if (lexer->token == t)
     {
-      lex_get ();
+      lex_get (lexer);
       return true;
     }
   else
     {
-      lex_error (_("expecting `%s'"), lex_token_name (t));
+      lex_error (lexer, _("expecting `%s'"), lex_token_name (t));
       return false;
     }
 }
@@ -584,13 +582,13 @@
 /* If this token is a string, does nothing and returns true.
    Otherwise, reports an error and returns false. */
 bool
-lex_force_string (void)
+lex_force_string (struct lexer *lexer)
 {
-  if (token == T_STRING)
+  if (lexer->token == T_STRING)
     return true;
   else
     {
-      lex_error (_("expecting string"));
+      lex_error (lexer, _("expecting string"));
       return false;
     }
 }
@@ -598,13 +596,13 @@
 /* If this token is an integer, does nothing and returns true.
    Otherwise, reports an error and returns false. */
 bool
-lex_force_int (void)
+lex_force_int (struct lexer *lexer)
 {
-  if (lex_is_integer ())
+  if (lex_is_integer (lexer))
     return true;
   else
     {
-      lex_error (_("expecting integer"));
+      lex_error (lexer, _("expecting integer"));
       return false;
     }
 }
@@ -612,30 +610,27 @@
 /* If this token is a number, does nothing and returns true.
    Otherwise, reports an error and returns false. */
 bool
-lex_force_num (void)
+lex_force_num (struct lexer *lexer)
 {
-  if (lex_is_number ())
+  if (lex_is_number (lexer))
     return true;
-  else
-    {
-      lex_error (_("expecting number"));
+
+  lex_error (lexer, _("expecting number"));
       return false;
-    }
 }
        
 /* If this token is an identifier, does nothing and returns true.
    Otherwise, reports an error and returns false. */
 bool
-lex_force_id (void)
+lex_force_id (struct lexer *lexer)
 {
-  if (token == T_ID)
+  if (lexer->token == T_ID)
     return true;
-  else
-    {
-      lex_error (_("expecting identifier"));
+
+  lex_error (lexer, _("expecting identifier"));
       return false;
-    }
 }
+
 /* Weird token functions. */
 
 /* Returns the first character of the next token, except that if the
@@ -645,76 +640,76 @@
    alphanumeric return value doesn't guarantee an ID token, it could
    also be a reserved-word token. */
 int
-lex_look_ahead (void)
+lex_look_ahead (struct lexer *lexer)
 {
-  if (put_token)
-    return put_token;
+  if (lexer->put_token)
+    return lexer->put_token;
 
   for (;;)
     {
-      if (eof)
+      if (lexer->eof)
         return 0;
 
       for (;;)
        {
-         while (isspace ((unsigned char) *prog))
-           prog++;
-         if (*prog)
+         while (isspace ((unsigned char) *lexer->prog))
+           lexer->prog++;
+         if (*lexer->prog)
            break;
 
-         if (dot)
+         if (lexer->dot)
            return '.';
-         else if (!lex_get_line ())
+         else if (!lex_get_line (lexer))
             return 0;
 
-         if (put_token) 
-           return put_token;
+         if (lexer->put_token) 
+           return lexer->put_token;
        }
 
-      if ((toupper ((unsigned char) *prog) == 'X'
-          || toupper ((unsigned char) *prog) == 'B'
-           || toupper ((unsigned char) *prog) == 'O')
-         && (prog[1] == '\'' || prog[1] == '"'))
+      if ((toupper ((unsigned char) *lexer->prog) == 'X'
+          || toupper ((unsigned char) *lexer->prog) == 'B'
+           || toupper ((unsigned char) *lexer->prog) == 'O')
+         && (lexer->prog[1] == '\'' || lexer->prog[1] == '"'))
        return '\'';
 
-      return *prog;
+      return *lexer->prog;
     }
 }
 
 /* Makes the current token become the next token to be read; the
    current token is set to T. */
 void
-lex_put_back (int t)
+lex_put_back (struct lexer *lexer, int t)
 {
-  save_token ();
-  token = t;
+  save_token (lexer);
+  lexer->token = t;
 }
 
 /* Makes the current token become the next token to be read; the
    current token is set to the identifier ID. */
 void
-lex_put_back_id (const char *id)
+lex_put_back_id (struct lexer *lexer, const char *id)
 {
   assert (lex_id_to_token (id, strlen (id)) == T_ID);
-  save_token ();
-  token = T_ID;
-  ds_assign_cstr (&tokstr, id);
-  str_copy_trunc (tokid, sizeof tokid, ds_cstr (&tokstr));
+  save_token (lexer);
+  lexer->token = T_ID;
+  ds_assign_cstr (&lexer->tokstr, id);
+  str_copy_trunc (lexer->tokid, sizeof lexer->tokid, ds_cstr (&lexer->tokstr));
 }
 
 /* Weird line processing functions. */
 
 /* Returns the entire contents of the current line. */
 const char *
-lex_entire_line (void)
+lex_entire_line (struct lexer *lexer)
 {
-  return ds_cstr (&line_buffer);
+  return ds_cstr (&lexer->line_buffer);
 }
 
 const struct string *
-lex_entire_line_ds (void)
+lex_entire_line_ds (struct lexer *lexer)
 {
-  return &line_buffer;
+  return &lexer->line_buffer;
 }
 
 /* As lex_entire_line(), but only returns the part of the current line
@@ -722,22 +717,22 @@
    If END_DOT is non-null, stores nonzero into *END_DOT if the line
    ends with a terminal dot, or zero if it doesn't. */
 const char *
-lex_rest_of_line (int *end_dot)
+lex_rest_of_line (struct lexer *lexer, int *end_dot)
 {
   if (end_dot)
-    *end_dot = dot;
-  return prog;
+    *end_dot = lexer->dot;
+  return lexer->prog;
 }
 
 /* Causes the rest of the current input line to be ignored for
    tokenization purposes. */
 void
-lex_discard_line (void)
+lex_discard_line (struct lexer *lexer)
 {
-  ds_cstr (&line_buffer);  /* Ensures ds_end points to something valid */
-  prog = ds_end (&line_buffer);
-  dot = false;
-  put_token = 0;
+  ds_cstr (&lexer->line_buffer);  /* Ensures ds_end points to something valid 
*/
+  lexer->prog = ds_end (&lexer->line_buffer);
+  lexer->dot = false;
+  lexer->put_token = 0;
 }
 
 
@@ -749,15 +744,15 @@
    the user doesn't want to finish typing a command that will be
    ignored anyway. */
 void
-lex_discard_rest_of_command (void) 
+lex_discard_rest_of_command (struct lexer *lexer) 
 {
   if (!getl_is_interactive ())
     {
-      while (token != T_STOP && token != '.')
-       lex_get ();
+      while (lexer->token != T_STOP && lexer->token != '.')
+       lex_get (lexer);
     }
   else 
-    lex_discard_line (); 
+    lex_discard_line (lexer); 
 }
 
 /* Weird line reading functions. */
@@ -812,29 +807,29 @@
 
 /* Reads a line, without performing any preprocessing */
 bool 
-lex_get_line_raw (void)
+lex_get_line_raw (struct lexer *lexer)
 {
   bool dummy;
-  return lex_read_line (&line_buffer, &dummy);
+  return lexer->read_line (&lexer->line_buffer, &dummy);
 }
 
 /* Reads a line for use by the tokenizer, and preprocesses it by
    removing comments, stripping trailing whitespace and the
    terminal dot, and removing leading indentors. */
 bool
-lex_get_line (void)
+lex_get_line (struct lexer *lexer)
 {
-  struct string *line = &line_buffer;
+  struct string *line = &lexer->line_buffer;
   bool interactive;
 
-  if (!lex_read_line (line, &interactive))
+  if (!lexer->read_line (line, &interactive))
     return false;
 
   strip_comments (line);
   ds_rtrim (line, ss_cstr (CC_SPACES));
   
   /* Check for and remove terminal dot. */
-  dot = (ds_chomp (line, get_endcmd ())
+  lexer->dot = (ds_chomp (line, get_endcmd ())
          || (ds_is_empty (line) && get_nulline ()));
   
   /* Strip leading indentors or insert a terminal dot (unless the
@@ -846,10 +841,10 @@
       if (first == '+' || first == '-')
        *ds_data (line) = ' ';
       else if (first != EOF && !isspace (first))
-       put_token = '.';
+       lexer->put_token = '.';
     }
 
-  prog = ds_cstr (line);
+  lexer->prog = ds_cstr (line);
 
   return true;
 }
@@ -876,16 +871,16 @@
 /* Returns an ASCII representation of the current token as a
    malloc()'d string. */
 char *
-lex_token_representation (void)
+lex_token_representation (struct lexer *lexer)
 {
   char *token_rep;
   
-  switch (token)
+  switch (lexer->token)
     {
     case T_ID:
     case T_POS_NUM:
     case T_NEG_NUM:
-      return ds_xstrdup (&tokstr);
+      return ds_xstrdup (&lexer->tokstr);
       break;
 
     case T_STRING:
@@ -893,14 +888,14 @@
        int hexstring = 0;
        char *sp, *dp;
 
-       for (sp = ds_cstr (&tokstr); sp < ds_end (&tokstr); sp++)
+       for (sp = ds_cstr (&lexer->tokstr); sp < ds_end (&lexer->tokstr); sp++)
          if (!isprint ((unsigned char) *sp))
            {
              hexstring = 1;
              break;
            }
              
-       token_rep = xmalloc (2 + ds_length (&tokstr) * 2 + 1 + 1);
+       token_rep = xmalloc (2 + ds_length (&lexer->tokstr) * 2 + 1 + 1);
 
        dp = token_rep;
        if (hexstring)
@@ -908,14 +903,14 @@
        *dp++ = '\'';
 
        if (!hexstring)
-         for (sp = ds_cstr (&tokstr); *sp; )
+         for (sp = ds_cstr (&lexer->tokstr); *sp; )
            {
              if (*sp == '\'')
                *dp++ = '\'';
              *dp++ = (unsigned char) *sp++;
            }
        else
-         for (sp = ds_cstr (&tokstr); sp < ds_end (&tokstr); sp++)
+         for (sp = ds_cstr (&lexer->tokstr); sp < ds_end (&lexer->tokstr); 
sp++)
            {
              *dp++ = (((unsigned char) *sp) >> 4)["0123456789ABCDEF"];
              *dp++ = (((unsigned char) *sp) & 15)["0123456789ABCDEF"];
@@ -936,12 +931,12 @@
       return xstrdup ("**");
 
     default:
-      if (token >= T_FIRST_KEYWORD && token <= T_LAST_KEYWORD)
-       return xstrdup (keywords [token - T_FIRST_KEYWORD]);
+      if (lexer->token >= T_FIRST_KEYWORD && lexer->token <= T_LAST_KEYWORD)
+       return xstrdup (keywords [lexer->token - T_FIRST_KEYWORD]);
       else
        {
          token_rep = xmalloc (2);
-         token_rep[0] = token;
+         token_rep[0] = lexer->token;
          token_rep[1] = '\0';
          return token_rep;
        }
@@ -957,44 +952,44 @@
    of syntax then this function is called to rip it off of a
    number. */
 void
-lex_negative_to_dash (void)
+lex_negative_to_dash (struct lexer *lexer)
 {
-  if (token == T_NEG_NUM)
+  if (lexer->token == T_NEG_NUM)
     {
-      token = T_POS_NUM;
-      tokval = -tokval;
-      ds_assign_substring (&tokstr, ds_substr (&tokstr, 1, SIZE_MAX));
-      save_token ();
-      token = '-';
+      lexer->token = T_POS_NUM;
+      lexer->tokval = -lexer->tokval;
+      ds_assign_substring (&lexer->tokstr, ds_substr (&lexer->tokstr, 1, 
SIZE_MAX));
+      save_token (lexer);
+      lexer->token = '-';
     }
 }
    
 /* We're not at eof any more. */
 void
-lex_reset_eof (void)
+lex_reset_eof (struct lexer *lexer)
 {
-  eof = false;
+  lexer->eof = false;
 }
 
 /* Skip a COMMENT command. */
 void
-lex_skip_comment (void)
+lex_skip_comment (struct lexer *lexer)
 {
   for (;;)
     {
-      if (!lex_get_line ()) 
+      if (!lex_get_line (lexer)) 
         {
-          put_token = T_STOP;
-          eof = true;
+          lexer->put_token = T_STOP;
+          lexer->eof = true;
           return;
         }
       
-      if (put_token == '.')
+      if (lexer->put_token == '.')
        break;
 
-      ds_cstr (&line_buffer); /* Ensures ds_end will point to a valid char */
-      prog = ds_end (&line_buffer);
-      if (dot)
+      ds_cstr (&lexer->line_buffer); /* Ensures ds_end will point to a valid 
char */
+      lexer->prog = ds_end (&lexer->line_buffer);
+      if (lexer->dot)
        break;
     }
 }
@@ -1005,7 +1000,8 @@
    hex digits, according to TYPE.  The string is converted to
    characters having the specified values. */
 static void
-convert_numeric_string_to_char_string (enum string_type type)
+convert_numeric_string_to_char_string (struct lexer *lexer, 
+                                      enum string_type type)
 {
   const char *base_name;
   int base;
@@ -1035,13 +1031,13 @@
       NOT_REACHED ();
     }
   
-  byte_cnt = ds_length (&tokstr) / chars_per_byte;
-  if (ds_length (&tokstr) % chars_per_byte)
+  byte_cnt = ds_length (&lexer->tokstr) / chars_per_byte;
+  if (ds_length (&lexer->tokstr) % chars_per_byte)
     msg (SE, _("String of %s digits has %d characters, which is not a "
               "multiple of %d."),
-        base_name, ds_length (&tokstr), chars_per_byte);
+        base_name, ds_length (&lexer->tokstr), chars_per_byte);
 
-  p = ds_cstr (&tokstr);
+  p = ds_cstr (&lexer->tokstr);
   for (i = 0; i < byte_cnt; i++)
     {
       int value;
@@ -1071,88 +1067,88 @@
          value = value * base + v;
        }
 
-      ds_cstr (&tokstr)[i] = (unsigned char) value;
+      ds_cstr (&lexer->tokstr)[i] = (unsigned char) value;
     }
 
-  ds_truncate (&tokstr, byte_cnt);
+  ds_truncate (&lexer->tokstr, byte_cnt);
 }
 
 /* Parses a string from the input buffer into tokstr.  The input
-   buffer pointer prog must point to the initial single or double
+   buffer pointer lexer->prog must point to the initial single or double
    quote.  TYPE indicates the type of string to be parsed.
    Returns token type. */
 static int 
-parse_string (enum string_type type)
+parse_string (struct lexer *lexer, enum string_type type)
 {
   if (type != CHARACTER_STRING)
-    prog++;
+    lexer->prog++;
 
   /* Accumulate the entire string, joining sections indicated by +
      signs. */
   for (;;)
     {
       /* Single or double quote. */
-      int c = *prog++;
+      int c = *lexer->prog++;
       
       /* Accumulate section. */
       for (;;)
        {
          /* Check end of line. */
-         if (*prog == '\0')
+         if (*lexer->prog == '\0')
            {
              msg (SE, _("Unterminated string constant."));
              goto finish;
            }
          
          /* Double quote characters to embed them in strings. */
-         if (*prog == c)
+         if (*lexer->prog == c)
            {
-             if (prog[1] == c)
-               prog++;
+             if (lexer->prog[1] == c)
+               lexer->prog++;
              else
                break;
            }
 
-         ds_put_char (&tokstr, *prog++);
+         ds_put_char (&lexer->tokstr, *lexer->prog++);
        }
-      prog++;
+      lexer->prog++;
 
       /* Skip whitespace after final quote mark. */
-      if (eof)
+      if (lexer->eof)
        break;
       for (;;)
        {
-         while (isspace ((unsigned char) *prog))
-           prog++;
-         if (*prog)
+         while (isspace ((unsigned char) *lexer->prog))
+           lexer->prog++;
+         if (*lexer->prog)
            break;
 
-         if (dot)
+         if (lexer->dot)
            goto finish;
 
-         if (!lex_get_line ())
+         if (!lex_get_line (lexer))
             goto finish;
        }
 
       /* Skip plus sign. */
-      if (*prog != '+')
+      if (*lexer->prog != '+')
        break;
-      prog++;
+      lexer->prog++;
 
       /* Skip whitespace after plus sign. */
-      if (eof)
+      if (lexer->eof)
        break;
       for (;;)
        {
-         while (isspace ((unsigned char) *prog))
-           prog++;
-         if (*prog)
+         while (isspace ((unsigned char) *lexer->prog))
+           lexer->prog++;
+         if (*lexer->prog)
            break;
 
-         if (dot)
+         if (lexer->dot)
            goto finish;
 
-         if (!lex_get_line ())
+         if (!lex_get_line (lexer))
             {
               msg (SE, _("Unexpected end of file in string concatenation."));
               goto finish;
@@ -1160,7 +1156,7 @@
        }
 
       /* Ensure that a valid string follows. */
-      if (*prog != '\'' && *prog != '"')
+      if (*lexer->prog != '\'' && *lexer->prog != '"')
        {
          msg (SE, _("String expected following `+'."));
          goto finish;
@@ -1171,13 +1167,13 @@
      into one large string. */
 finish:
   if (type != CHARACTER_STRING)
-    convert_numeric_string_to_char_string (type);
+    convert_numeric_string_to_char_string (lexer, type);
 
-  if (ds_length (&tokstr) > 255)
+  if (ds_length (&lexer->tokstr) > 255)
     {
       msg (SE, _("String exceeds 255 characters in length (%d characters)."),
-          ds_length (&tokstr));
-      ds_truncate (&tokstr, 255);
+          ds_length (&lexer->tokstr));
+      ds_truncate (&lexer->tokstr, 255);
     }
       
   return T_STRING;
@@ -1187,7 +1183,7 @@
 /* Reads one token from the lexer and writes a textual representation
    on stdout for debugging purposes. */
 static void
-dump_token (void)
+dump_token (struct lexer *lexer)
 {
   {
     const char *curfn;
@@ -1198,19 +1194,19 @@
       fprintf (stderr, "%s:%d\t", curfn, curln);
   }
   
-  switch (token)
+  switch (lexer->token)
     {
     case T_ID:
-      fprintf (stderr, "ID\t%s\n", tokid);
+      fprintf (stderr, "ID\t%s\n", lexer->tokid);
       break;
 
     case T_POS_NUM:
     case T_NEG_NUM:
-      fprintf (stderr, "NUM\t%f\n", tokval);
+      fprintf (stderr, "NUM\t%f\n", lexer->tokval);
       break;
 
     case T_STRING:
-      fprintf (stderr, "STRING\t\"%s\"\n", ds_cstr (&tokstr));
+      fprintf (stderr, "STRING\t\"%s\"\n", ds_cstr (&lexer->tokstr));
       break;
 
     case T_STOP:
@@ -1226,11 +1222,38 @@
       break;
 
     default:
-      if (token >= T_FIRST_KEYWORD && token <= T_LAST_KEYWORD)
+      if (lexer->token >= T_FIRST_KEYWORD && lexer->token <= T_LAST_KEYWORD)
        fprintf (stderr, "KEYWORD\t%s\n", lex_token_name (token));
       else
-       fprintf (stderr, "PUNCT\t%c\n", token);
+       fprintf (stderr, "PUNCT\t%c\n", lexer->token);
       break;
     }
 }
 #endif /* DUMP_TOKENS */
+
+
+/* Token Accessor Functions */
+
+int 
+lex_token (const struct lexer *lexer)
+{
+  return lexer->token;
+}
+
+double 
+lex_tokval (const struct lexer *lexer)
+{
+  return lexer->tokval;
+}
+
+const char *
+lex_tokid (const struct lexer *lexer)
+{
+  return lexer->tokid;
+}
+
+const struct string *
+lex_tokstr (const struct lexer *lexer)
+{
+  return &lexer->tokstr;
+}

Index: language/lexer/lexer.h
===================================================================
RCS file: /sources/pspp/pspp/src/language/lexer/lexer.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- language/lexer/lexer.h      28 Oct 2006 08:31:23 -0000      1.7
+++ language/lexer/lexer.h      11 Nov 2006 23:10:00 -0000      1.8
@@ -23,70 +23,74 @@
 #include <data/variable.h>
 #include <ctype.h>
 #include <stdbool.h>
-
 #include <data/identifier.h>
 
-
-extern int token;
-extern double tokval;
-extern char tokid[LONG_NAME_LEN + 1];
-extern struct string tokstr;
-
 #include <stddef.h>
 
+struct lexer ;
+
 /* Initialization. */
-void lex_init (bool (*)(struct string *, bool*));
-void lex_done (void);
+struct lexer * lex_create (bool (*)(struct string *, bool*));
+void lex_destroy (struct lexer *);
+
+
+
 
 /* Common functions. */
-void lex_get (void);
-void lex_error (const char *, ...);
+void lex_get (struct lexer *);
+void lex_error (struct lexer *, const char *, ...);
 void lex_sbc_only_once (const char *);
-void lex_sbc_missing (const char *);
-int lex_end_of_command (void);
+void lex_sbc_missing (struct lexer *, const char *);
+int lex_end_of_command (struct lexer *);
 
 /* Token testing functions. */
-bool lex_is_number (void);
-double lex_number (void);
-bool lex_is_integer (void);
-long lex_integer (void);
+bool lex_is_number (struct lexer *);
+double lex_number (struct lexer *);
+bool lex_is_integer (struct lexer *);
+long lex_integer (struct lexer *);
 
 /* Token matching functions. */
-bool lex_match (int);
-bool lex_match_id (const char *);
-bool lex_match_int (int);
+bool lex_match (struct lexer *, int);
+bool lex_match_id (struct lexer *, const char *);
+bool lex_match_int (struct lexer *, int);
 
 /* Forcible matching functions. */
-bool lex_force_match (int);
-bool lex_force_match_id (const char *);
-bool lex_force_int (void);
-bool lex_force_num (void);
-bool lex_force_id (void);
-bool lex_force_string (void);
+bool lex_force_match (struct lexer *, int);
+bool lex_force_match_id (struct lexer *, const char *);
+bool lex_force_int (struct lexer *);
+bool lex_force_num (struct lexer *);
+bool lex_force_id (struct lexer *);
+bool lex_force_string (struct lexer *);
        
 /* Weird token functions. */
-int lex_look_ahead (void);
-void lex_put_back (int);
-void lex_put_back_id (const char *tokid);
+int lex_look_ahead (struct lexer *);
+void lex_put_back (struct lexer *, int);
+void lex_put_back_id (struct lexer *, const char *tokid);
 
 /* Weird line processing functions. */
-const char *lex_entire_line (void);
-const struct string *lex_entire_line_ds (void);
-const char *lex_rest_of_line (int *end_dot);
-void lex_discard_line (void);
-void lex_discard_rest_of_command (void);
+const char *lex_entire_line (struct lexer *);
+const struct string *lex_entire_line_ds (struct lexer *);
+const char *lex_rest_of_line (struct lexer *, int *end_dot);
+void lex_discard_line (struct lexer *);
+void lex_discard_rest_of_command (struct lexer *);
 
 /* Weird line reading functions. */
-bool lex_get_line (void);
-bool lex_get_line_raw (void);
+bool lex_get_line (struct lexer *);
+bool lex_get_line_raw (struct lexer *);
 
 /* Token names. */
 const char *lex_token_name (int);
-char *lex_token_representation (void);
+char *lex_token_representation (struct lexer *);
+
+/* Token accessors */
+int lex_token (const struct lexer *);
+double lex_tokval (const struct lexer *);
+const char *lex_tokid (const struct lexer *);
+const struct string *lex_tokstr (const struct lexer *);
 
 /* Really weird functions. */
-void lex_negative_to_dash (void);
-void lex_reset_eof (void);
-void lex_skip_comment (void);
+void lex_negative_to_dash (struct lexer *);
+void lex_reset_eof (struct lexer *);
+void lex_skip_comment (struct lexer *);
 
 #endif /* !lexer_h */

Index: language/lexer/q2c.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/lexer/q2c.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- language/lexer/q2c.c        26 Oct 2006 06:16:36 -0000      1.17
+++ language/lexer/q2c.c        11 Nov 2006 23:10:00 -0000      1.18
@@ -40,22 +40,22 @@
 #define MAX_TOK_LEN 1024
 
 /* argv[0]. */
-char *program_name;
+static char *program_name;
 
 /* Have the input and output files been opened yet? */
-bool is_open;
+static bool is_open;
 
 /* Input, output files. */
-FILE *in, *out;
+static FILE *in, *out;
 
 /* Input, output file names. */
-char *ifn, *ofn;
+static char *ifn, *ofn;
 
 /* Input, output file line number. */
-int ln, oln = 1;
+static int ln, oln = 1;
 
 /* Input line buffer, current position. */
-char *buf, *cp;
+static char *buf, *cp;
 
 /* Token types. */
 enum
@@ -65,14 +65,14 @@
   };
 
 /* Current token: either one of the above, or a single character. */
-int token;
+static int token;
 
 /* Token string value. */
-char *tokstr;
+static char *tokstr;
 
 /* Utility functions. */
 
-char nullstr[] = "";
+static char nullstr[] = "";
 
 /* Close all open files and delete the output file, on failure. */
 static void
@@ -1177,7 +1177,7 @@
              dump (0, "/* Prototype for custom subcommands of %s. */",
                    cmdname);
            }
-         dump (0, "static int %scustom_%s (struct dataset *, struct cmd_%s *, 
void *);",
+         dump (0, "static int %scustom_%s (struct lexer *, struct dataset *, 
struct cmd_%s *, void *);",
                st_lower (prefix), st_lower (sbc->name),
                make_identifier (cmdname));
        }
@@ -1189,7 +1189,7 @@
   /* Prototypes for parsing and freeing functions. */
   {
     dump (0, "/* Command parsing functions. */");
-    dump (0, "static int parse_%s (struct dataset *, struct cmd_%s *, void 
*);",
+    dump (0, "static int parse_%s (struct lexer *, struct dataset *, struct 
cmd_%s *, void *);",
          make_identifier (cmdname), make_identifier (cmdname));
     dump (0, "static void free_%s (struct cmd_%s *);",
          make_identifier (cmdname), make_identifier (cmdname));
@@ -1342,17 +1342,17 @@
     t++;
       
   if (is_keyword (t))
-    sprintf (s, "lex_match (T_%s)", t);
+    sprintf (s, "lex_match (lexer, T_%s)", t);
   else if (!strcmp (t, "ON") || !strcmp (t, "YES"))
-    strcpy (s, "(lex_match_id (\"ON\") || lex_match_id (\"YES\") "
-           "|| lex_match_id (\"TRUE\"))");
+    strcpy (s, "(lex_match_id (lexer, \"ON\") || lex_match_id (lexer, \"YES\") 
"
+           "|| lex_match_id (lexer, \"TRUE\"))");
   else if (!strcmp (t, "OFF") || !strcmp (t, "NO"))
-    strcpy (s, "(lex_match_id (\"OFF\") || lex_match_id (\"NO\") "
-           "|| lex_match_id (\"FALSE\"))");
+    strcpy (s, "(lex_match_id (lexer, \"OFF\") || lex_match_id (lexer, \"NO\") 
"
+           "|| lex_match_id (lexer, \"FALSE\"))");
   else if (isdigit ((unsigned char) t[0]))
-    sprintf (s, "lex_match_int (%s)", t);
+    sprintf (s, "lex_match_int (lexer, %s)", t);
   else
-    sprintf (s, "lex_match_id (\"%s\")", t);
+    sprintf (s, "lex_match_id (lexer, \"%s\")", t);
   
   return s;
 }
@@ -1416,12 +1416,12 @@
            {
              if (s->optvalue)
                {
-                 dump (1, "if (lex_match ('('))");
+                 dump (1, "if (lex_match (lexer, '('))");
                  dump (1, "{");
                }
              else
                {
-                 dump (1, "if (!lex_match ('('))");
+                 dump (1, "if (!lex_match (lexer, '('))");
                  dump (1, "{");
                  dump (0, "msg (SE, _(\"`(' expected after %s "
                        "specifier of %s subcommand.\"));",
@@ -1434,26 +1434,26 @@
 
          if (s->value == VAL_INT)
            {
-             dump (1, "if (!lex_is_integer ())");
+             dump (1, "if (!lex_is_integer (lexer))");
              dump (1, "{");
              dump (0, "msg (SE, _(\"%s specifier of %s subcommand "
                    "requires an integer argument.\"));",
                    s->specname, sbc->name);
              dump (0, "goto lossage;");
              dump (-1, "}");
-             dump (-1, "p->%s%s = lex_integer ();",
+             dump (-1, "p->%s%s = lex_integer (lexer);",
                    sbc->prefix, st_lower (s->valname));
            }
          else
            {
-             dump (1, "if (!lex_is_number ())");
+             dump (1, "if (!lex_is_number (lexer))");
              dump (1, "{");
              dump (0, "msg (SE, _(\"Number expected after %s "
                    "specifier of %s subcommand.\"));",
                    s->specname, sbc->name);
              dump (0, "goto lossage;");
              dump (-1, "}");
-             dump (-1, "p->%s%s = tokval;", sbc->prefix,
+             dump (-1, "p->%s%s = lex_tokval (lexer);", sbc->prefix,
                    st_lower (s->valname));
            }
          
@@ -1480,11 +1480,11 @@
              outdent ();
            }
          
-         dump (0, "lex_get ();");
+         dump (0, "lex_get (lexer);");
          
          if (s->valtype == VT_PAREN)
            {
-             dump (1, "if (!lex_match (')'))");
+             dump (1, "if (!lex_match (lexer, ')'))");
              dump (1, "{");
              dump (0, "msg (SE, _(\"`)' expected after argument for "
                    "%s specifier of %s.\"));",
@@ -1520,7 +1520,7 @@
     {
       int count;
 
-      dump (1, "while (token != '/' && token != '.')");
+      dump (1, "while (lex_token (lexer) != '/' && lex_token (lexer) != '.')");
       dump (1, "{");
       
       {
@@ -1571,20 +1571,20 @@
          {
            dump (1, "else");
            dump (1, "{");
-           dump (0, "lex_error (NULL);");
+           dump (0, "lex_error (lexer, NULL);");
            dump (0, "goto lossage;");
            dump (-1, "}");
            outdent ();
          }
       }
 
-      dump (0, "lex_match (',');");
+      dump (0, "lex_match (lexer, ',');");
       dump (-1, "}");
       outdent ();
     }
   else if (sbc->type == SBC_VARLIST)
     {
-      dump (1, "if (!parse_variables (dataset_dict (ds), &p->%sv_%s, 
&p->%sn_%s, "
+      dump (1, "if (!parse_variables (lexer, dataset_dict (ds), &p->%sv_%s, 
&p->%sn_%s, "
            "PV_APPEND%s%s))",
            st_lower (sbc->prefix), st_lower (sbc->name),
            st_lower (sbc->prefix), st_lower (sbc->name),
@@ -1595,7 +1595,7 @@
     }
   else if (sbc->type == SBC_VAR)
     {
-      dump (0, "p->%sv_%s = parse_variable (dataset_dict (ds));",
+      dump (0, "p->%sv_%s = parse_variable (lexer, dataset_dict (ds));",
            st_lower (sbc->prefix), st_lower (sbc->name));
       dump (1, "if (!p->%sv_%s)",
            st_lower (sbc->prefix), st_lower (sbc->name));
@@ -1609,12 +1609,12 @@
          dump (1, "{");
          dump (0, "int x;");
        }
-      dump (1, "if (!lex_force_string ())");
+      dump (1, "if (!lex_force_string (lexer))");
       dump (0, "return false;");
       outdent ();
       if (sbc->restriction)
        {
-         dump (0, "x = ds_length (&tokstr);");
+         dump (0, "x = ds_length (lex_tokstr (lexer));");
          dump (1, "if (!(%s))", sbc->restriction);
          dump (1, "{");
          dump (0, "msg (SE, _(\"String for %s must be %s.\"));",
@@ -1624,28 +1624,28 @@
          outdent ();
        }
       dump (0, "free(p->s_%s);", st_lower(sbc->name) );
-      dump (0, "p->s_%s = ds_xstrdup (&tokstr);",
+      dump (0, "p->s_%s = ds_xstrdup (lex_tokstr (lexer));",
            st_lower (sbc->name));
-      dump (0, "lex_get ();");
+      dump (0, "lex_get (lexer);");
       if (sbc->restriction)
        dump (-1, "}");
     }
   else if (sbc->type == SBC_DBL)
     {
-      dump (1, "if (!lex_force_num ())");
+      dump (1, "if (!lex_force_num (lexer))");
       dump (0, "goto lossage;");
-      dump (-1, "p->n_%s[p->sbc_%s - 1] = lex_number ();", 
+      dump (-1, "p->n_%s[p->sbc_%s - 1] = lex_number (lexer);", 
            st_lower (sbc->name), st_lower (sbc->name) );
-      dump (0, "lex_get();");
+      dump (0, "lex_get(lexer);");
     }
   else if (sbc->type == SBC_INT)
     {
       dump(1, "{");
       dump(0, "int x;");
-      dump (1, "if (!lex_force_int ())");
+      dump (1, "if (!lex_force_int (lexer))");
       dump (0, "goto lossage;");
-      dump (-1, "x = lex_integer ();");
-      dump (0, "lex_get();");
+      dump (-1, "x = lex_integer (lexer);");
+      dump (0, "lex_get(lexer);");
       if (sbc->restriction)
        {
          char buf[1024];
@@ -1664,11 +1664,11 @@
     }
   else if (sbc->type == SBC_PINT)
     {
-      dump (0, "lex_match ('(');");
-      dump (1, "if (!lex_force_int ())");
+      dump (0, "lex_match (lexer, '(');");
+      dump (1, "if (!lex_force_int (lexer))");
       dump (0, "goto lossage;");
-      dump (-1, "p->n_%s = lex_integer ();", st_lower (sbc->name));
-      dump (0, "lex_match (')');");
+      dump (-1, "p->n_%s = lex_integer (lexer);", st_lower (sbc->name));
+      dump (0, "lex_match (lexer, ')');");
     }
   else if (sbc->type == SBC_DBL_LIST)
     {
@@ -1678,25 +1678,25 @@
       dump (0, "goto lossage;");
       dump (-1,"}");
 
-      dump (1, "while (token != '/' && token != '.')");
+      dump (1, "while (lex_token (lexer) != '/' && lex_token (lexer) != '.')");
       dump (1, "{");
-      dump (0, "lex_match(',');");
-      dump (0, "if (!lex_force_num ())");
+      dump (0, "lex_match (lexer, ',');");
+      dump (0, "if (!lex_force_num (lexer))");
       dump (1, "{");
       dump (0, "goto lossage;");
       dump (-1,"}");
 
-      dump (0, "subc_list_double_push(&p->dl_%s[p->sbc_%s-1],lex_number ());", 
-           st_lower (sbc->name),st_lower (sbc->name)
+      dump (0, "subc_list_double_push (&p->dl_%s[p->sbc_%s-1], lex_number 
(lexer));", 
+           st_lower (sbc->name), st_lower (sbc->name)
            );
 
-      dump (0, "lex_get();");
+      dump (0, "lex_get (lexer);");
       dump (-1,"}");
 
     }
   else if (sbc->type == SBC_CUSTOM)
     {
-      dump (1, "switch (%scustom_%s (ds, p, aux))",
+      dump (1, "switch (%scustom_%s (lexer, ds, p, aux))",
            st_lower (prefix), st_lower (sbc->name));
       dump (0, "{");
       dump (1, "case 0:");
@@ -1706,7 +1706,7 @@
       dump (0, "break;");
       dump (-1, "case 2:");
       indent ();
-      dump (0, "lex_error (NULL);");
+      dump (0, "lex_error (lexer, NULL);");
       dump (0, "goto lossage;");
       dump (-1, "default:");
       indent ();
@@ -1725,7 +1725,7 @@
   indent = 0;
 
   dump (0, "static int");
-  dump (0, "parse_%s (struct dataset *ds%s, struct cmd_%s *p, void *aux 
UNUSED)",
+  dump (0, "parse_%s (struct lexer *lexer, struct dataset *ds%s, struct cmd_%s 
*p, void *aux UNUSED)",
         make_identifier (cmdname),
        (def && ( def->type == SBC_VARLIST && def->type == SBC_CUSTOM))?"":" 
UNUSED",
        make_identifier (cmdname));
@@ -1740,19 +1740,19 @@
   if (def && (def->type == SBC_VARLIST))
     {
       if (def->type == SBC_VARLIST)
-       dump (1, "if (token == T_ID "
-              "&& dict_lookup_var (dataset_dict (ds), tokid) != NULL "
-             "&& lex_look_ahead () != '=')");
+       dump (1, "if (lex_token (lexer) == T_ID "
+              "&& dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) != 
NULL "
+             "&& lex_look_ahead (lexer) != '=')");
       else
        {
-         dump (0, "if ((token == T_ID "
-                "&& dict_lookup_var (dataset_dict (ds), tokid) "
+         dump (0, "if ((lex_token (lexer) == T_ID "
+                "&& dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) "
                "&& lex_look_ahead () != '=')");
          dump (1, "     || token == T_ALL)");
        }
       dump (1, "{");
       dump (0, "p->sbc_%s++;", st_lower (def->name));
-      dump (1, "if (!parse_variables (dataset_dict (ds), &p->%sv_%s, 
&p->%sn_%s, "
+      dump (1, "if (!parse_variables (lexer, dataset_dict (ds), &p->%sv_%s, 
&p->%sn_%s, "
            "PV_APPEND))",
            st_lower (def->prefix), st_lower (def->name),
            st_lower (def->prefix), st_lower (def->name));
@@ -1763,7 +1763,7 @@
     }
   else if (def && def->type == SBC_CUSTOM)
     {
-      dump (1, "switch (%scustom_%s (ds, p, aux))",
+      dump (1, "switch (%scustom_%s (lexer, ds, p, aux))",
            st_lower (prefix), st_lower (def->name));
       dump (0, "{");
       dump (1, "case 0:");
@@ -1791,7 +1791,7 @@
        f = 1;
        dump (1, "{");
 
-       dump (0, "lex_match ('=');");
+       dump (0, "lex_match (lexer, '=');");
        dump (0, "p->sbc_%s++;", st_lower (sbc->name));
        if (sbc->arity != ARITY_MANY)
          {
@@ -1811,15 +1811,15 @@
 
 
   /* Now deal with the /ALGORITHM subcommand implicit to all commands */
-  dump(1,"else if ( get_syntax() != COMPATIBLE && 
lex_match_id(\"ALGORITHM\"))");
+  dump(1,"else if ( get_syntax() != COMPATIBLE && lex_match_id(lexer, 
\"ALGORITHM\"))");
   dump(1,"{");
 
-  dump (0, "lex_match ('=');");
+  dump (0, "lex_match (lexer, '=');");
 
-  dump(1,"if (lex_match_id(\"COMPATIBLE\"))");
+  dump(1,"if (lex_match_id(lexer, \"COMPATIBLE\"))");
   dump(0,"set_cmd_algorithm(COMPATIBLE);");
   outdent();
-  dump(1,"else if (lex_match_id(\"ENHANCED\"))");
+  dump(1,"else if (lex_match_id(lexer, \"ENHANCED\"))");
   dump(0,"set_cmd_algorithm(ENHANCED);");
 
   dump (-1, "}");
@@ -1827,14 +1827,14 @@
 
 
   
-  dump (1, "if (!lex_match ('/'))");
+  dump (1, "if (!lex_match (lexer, '/'))");
   dump (0, "break;");
   dump (-2, "}");
   outdent ();
   dump (0, nullstr);
-  dump (1, "if (token != '.')");
+  dump (1, "if (lex_token (lexer) != '.')");
   dump (1, "{");
-  dump (0, "lex_error (_(\"expecting end of command\"));");
+  dump (0, "lex_error (lexer, _(\"expecting end of command\"));");
   dump (0, "goto lossage;");
   dump (-1, "}");
   dump (0, nullstr);

Index: language/lexer/range-parser.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/lexer/range-parser.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- language/lexer/range-parser.c       3 Nov 2006 04:53:51 -0000       1.4
+++ language/lexer/range-parser.c       11 Nov 2006 23:10:00 -0000      1.5
@@ -31,7 +31,7 @@
 #define _(msgid) gettext (msgid)
 #define N_(msgid) msgid
 
-static bool parse_number (double *, const struct fmt_spec *);
+static bool parse_number (struct lexer *, double *, const struct fmt_spec *);
 
 /* Parses and stores a numeric value, or a range of the form "x
    THRU y".  Open-ended ranges may be specified as "LO(WEST) THRU
@@ -42,18 +42,18 @@
    string values are also accepted, and converted to numeric
    values using the specified format. */
 bool
-parse_num_range (double *x, double *y, const struct fmt_spec *f) 
+parse_num_range (struct lexer *lexer, double *x, double *y, const struct 
fmt_spec *f) 
 {
-  if (lex_match_id ("LO") || lex_match_id ("LOWEST"))
+  if (lex_match_id (lexer, "LO") || lex_match_id (lexer, "LOWEST"))
     *x = LOWEST;
-  else if (!parse_number (x, f))
+  else if (!parse_number (lexer, x, f))
     return false;
 
-  if (lex_match_id ("THRU")) 
+  if (lex_match_id (lexer, "THRU")) 
     {
-      if (lex_match_id ("HI") || lex_match_id ("HIGHEST"))
+      if (lex_match_id (lexer, "HI") || lex_match_id (lexer, "HIGHEST"))
         *y = HIGHEST;
-      else if (!parse_number (y, f))
+      else if (!parse_number (lexer, y, f))
         return false;
 
       if (*y < *x) 
@@ -90,27 +90,27 @@
    string values are also accepted, and converted to numeric
    values using the specified format. */
 static bool
-parse_number (double *x, const struct fmt_spec *f)
+parse_number (struct lexer *lexer, double *x, const struct fmt_spec *f)
 {
-  if (lex_is_number ()) 
+  if (lex_is_number (lexer)) 
     {
-      *x = lex_number ();
-      lex_get ();
+      *x = lex_number (lexer);
+      lex_get (lexer);
       return true;
     }
-  else if (token == T_STRING && f != NULL) 
+  else if (lex_token (lexer) == T_STRING && f != NULL) 
     {
       struct data_in di;
       union value v;
-      di.s = ds_data (&tokstr);
-      di.e = ds_end (&tokstr);
+      di.s = ds_data (lex_tokstr (lexer));
+      di.e = ds_end (lex_tokstr (lexer));
       di.v = &v;
       di.flags = 0;
       di.f1 = 1;
-      di.f2 = ds_length (&tokstr);
+      di.f2 = ds_length (lex_tokstr (lexer));
       di.format = *f;
       data_in (&di);
-      lex_get ();
+      lex_get (lexer);
       *x = v.f;
       if (*x == SYSMIS)
         {
@@ -122,9 +122,9 @@
   else 
     {
       if (f != NULL)
-        lex_error (_("expecting number or data string"));
+        lex_error (lexer, _("expecting number or data string"));
       else
-        lex_force_num ();
+        lex_force_num (lexer);
       return false; 
     }
 }

Index: language/lexer/range-parser.h
===================================================================
RCS file: /sources/pspp/pspp/src/language/lexer/range-parser.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- language/lexer/range-parser.h       4 Mar 2006 01:11:57 -0000       1.1
+++ language/lexer/range-parser.h       11 Nov 2006 23:10:00 -0000      1.2
@@ -23,6 +23,7 @@
 #include <stdbool.h>
 
 struct fmt_spec;
-bool parse_num_range (double *x, double *y, const struct fmt_spec *fmt);
+struct lexer;
+bool parse_num_range (struct lexer *, double *, double *, const struct 
fmt_spec *fmt);
 
 #endif /* range-prs.h */

Index: language/lexer/subcommand-list.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/lexer/subcommand-list.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- language/lexer/subcommand-list.c    4 Mar 2006 01:11:57 -0000       1.1
+++ language/lexer/subcommand-list.c    11 Nov 2006 23:10:00 -0000      1.2
@@ -21,6 +21,7 @@
 02110-1301, USA. */
 
 
+#include <config.h>
 #include "subcommand-list.h"
 #include <stdlib.h>
 #include "xalloc.h"

Index: language/lexer/variable-parser.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/lexer/variable-parser.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- language/lexer/variable-parser.c    26 Oct 2006 06:16:36 -0000      1.10
+++ language/lexer/variable-parser.c    11 Nov 2006 23:10:00 -0000      1.11
@@ -44,23 +44,24 @@
    variable's index and returns true if successful.  On failure
    emits an error message and returns false. */
 static bool
-parse_vs_variable_idx (const struct var_set *vs, size_t *idx)
+parse_vs_variable_idx (struct lexer *lexer, const struct var_set *vs, 
+               size_t *idx)
 {
   assert (idx != NULL);
   
-  if (token != T_ID)
+  if (lex_token (lexer) != T_ID)
     {
-      lex_error (_("expecting variable name"));
+      lex_error (lexer, _("expecting variable name"));
       return false;
     }
-  else if (var_set_lookup_var_idx (vs, tokid, idx)) 
+  else if (var_set_lookup_var_idx (vs, lex_tokid (lexer), idx)) 
     {
-      lex_get ();
+      lex_get (lexer);
       return true;
     }
   else 
     {
-      msg (SE, _("%s is not a variable name."), tokid);
+      msg (SE, _("%s is not a variable name."), lex_tokid (lexer));
       return false;
     }
 }
@@ -69,20 +70,20 @@
    if successful.  On failure emits an error message and returns
    a null pointer. */
 static struct variable *
-parse_vs_variable (const struct var_set *vs)
+parse_vs_variable (struct lexer *lexer, const struct var_set *vs)
 {
   size_t idx;
-  return parse_vs_variable_idx (vs, &idx) ? var_set_get_var (vs, idx) : NULL;
+  return parse_vs_variable_idx (lexer, vs, &idx) ? var_set_get_var (vs, idx) : 
NULL;
 }
 
 /* Parses a variable name in dictionary D and returns the
    variable if successful.  On failure emits an error message and
    returns a null pointer. */
 struct variable *
-parse_variable (const struct dictionary *d) 
+parse_variable (struct lexer *lexer, const struct dictionary *d) 
 {
   struct var_set *vs = var_set_create_from_dict (d);
-  struct variable *var = parse_vs_variable (vs);
+  struct variable *var = parse_vs_variable (lexer, vs);
   var_set_destroy (vs);
   return var;
 }
@@ -92,7 +93,8 @@
    number of variables into *CNT.  Returns true only if
    successful. */
 bool
-parse_variables (const struct dictionary *d, struct variable ***var,
+parse_variables (struct lexer *lexer, const struct dictionary *d, 
+                       struct variable ***var,
                  size_t *cnt, int opts) 
 {
   struct var_set *vs;
@@ -103,7 +105,7 @@
   assert (cnt != NULL);
 
   vs = var_set_create_from_dict (d);
-  success = parse_var_set_vars (vs, var, cnt, opts);
+  success = parse_var_set_vars (lexer, vs, var, cnt, opts);
   if ( success == 0 )
      free ( *var ) ;
   var_set_destroy (vs);
@@ -116,7 +118,8 @@
    successful.  Same behavior as parse_variables, except that all
    allocations are taken from the given POOL. */
 bool
-parse_variables_pool (struct pool *pool, const struct dictionary *dict,
+parse_variables_pool (struct lexer *lexer, struct pool *pool, 
+               const struct dictionary *dict,
                       struct variable ***vars, size_t *var_cnt, int opts) 
 {
   int retval;
@@ -127,7 +130,7 @@
      later. */
   assert (!(opts & PV_APPEND));
   
-  retval = parse_variables (dict, vars, var_cnt, opts);
+  retval = parse_variables (lexer, dict, vars, var_cnt, opts);
   if (retval)
     pool_register (pool, free, *vars);
   return retval;
@@ -138,10 +141,11 @@
    dictionary class, and returns true.  Returns false on
    failure. */
 static bool
-parse_var_idx_class (const struct var_set *vs, size_t *idx,
+parse_var_idx_class (struct lexer *lexer, const struct var_set *vs, 
+                       size_t *idx,
                      enum dict_class *class)
 {
-  if (!parse_vs_variable_idx (vs, idx))
+  if (!parse_vs_variable_idx (lexer, vs, idx))
     return false;
 
   *class = dict_class_from_id (var_set_get_var (vs, *idx)->name);
@@ -212,7 +216,7 @@
    Conversely, if parse_variables() returns true, then *nv is
    nonzero and *v is non-NULL. */
 bool
-parse_var_set_vars (const struct var_set *vs, 
+parse_var_set_vars (struct lexer *lexer, const struct var_set *vs, 
                     struct variable ***v, size_t *nv,
                     int pv_opts)
 {
@@ -254,7 +258,7 @@
 
   do
     {
-      if (lex_match (T_ALL))
+      if (lex_match (lexer, T_ALL))
         add_variables (v, nv, &mv, included, pv_opts,
                        vs, 0, var_set_get_cnt (vs) - 1, DC_ORDINARY);
       else 
@@ -262,10 +266,10 @@
           enum dict_class class;
           size_t first_idx;
 
-          if (!parse_var_idx_class (vs, &first_idx, &class))
+          if (!parse_var_idx_class (lexer, vs, &first_idx, &class))
             goto fail;
 
-          if (!lex_match (T_TO))
+          if (!lex_match (lexer, T_TO))
             add_variable (v, nv, &mv, included, pv_opts, vs, first_idx);
           else 
             {
@@ -273,7 +277,7 @@
               enum dict_class last_class;
               struct variable *first_var, *last_var;
 
-              if (!parse_var_idx_class (vs, &last_idx, &last_class))
+              if (!parse_var_idx_class (lexer, vs, &last_idx, &last_class))
                 goto fail;
 
               first_var = var_set_get_var (vs, first_idx);
@@ -307,10 +311,10 @@
 
       if (pv_opts & PV_SINGLE)
         break;
-      lex_match (',');
+      lex_match (lexer, ',');
     }
-  while (token == T_ALL
-         || (token == T_ID && var_set_lookup_var (vs, tokid) != NULL));
+  while (lex_token (lexer) == T_ALL
+         || (lex_token (lexer) == T_ID && var_set_lookup_var (vs, lex_tokid 
(lexer)) != NULL));
   
   if (*nv == 0)
     goto fail;
@@ -372,7 +376,7 @@
 /* Parses a list of variable names according to the DATA LIST version
    of the TO convention.  */
 bool
-parse_DATA_LIST_vars (char ***names, size_t *nnames, int pv_opts)
+parse_DATA_LIST_vars (struct lexer *lexer, char ***names, size_t *nnames, int 
pv_opts)
 {
   int n1, n2;
   int d1, d2;
@@ -398,29 +402,29 @@
 
   do
     {
-      if (token != T_ID)
+      if (lex_token (lexer) != T_ID)
        {
-         lex_error ("expecting variable name");
+         lex_error (lexer, "expecting variable name");
          goto fail;
        }
-      if (dict_class_from_id (tokid) == DC_SCRATCH
+      if (dict_class_from_id (lex_tokid (lexer)) == DC_SCRATCH
           && (pv_opts & PV_NO_SCRATCH))
        {
          msg (SE, _("Scratch variables not allowed here."));
          goto fail;
        }
-      strcpy (name1, tokid);
-      lex_get ();
-      if (token == T_TO)
+      strcpy (name1, lex_tokid (lexer));
+      lex_get (lexer);
+      if (lex_token (lexer) == T_TO)
        {
-         lex_get ();
-         if (token != T_ID)
+         lex_get (lexer);
+         if (lex_token (lexer) != T_ID)
            {
-             lex_error ("expecting variable name");
+             lex_error (lexer, "expecting variable name");
              goto fail;
            }
-         strcpy (name2, tokid);
-         lex_get ();
+         strcpy (name2, lex_tokid (lexer));
+         lex_get (lexer);
 
          if (!extract_num (name1, root1, &n1, &d1)
              || !extract_num (name2, root2, &n2, &d2))
@@ -463,12 +467,12 @@
          (*names)[nvar++] = xstrdup (name1);
        }
 
-      lex_match (',');
+      lex_match (lexer, ',');
 
       if (pv_opts & PV_SINGLE)
        break;
     }
-  while (token == T_ID);
+  while (lex_token (lexer) == T_ID);
   success = 1;
 
 fail:
@@ -502,7 +506,7 @@
    parse_DATA_LIST_vars(), except that all allocations are taken
    from the given POOL. */
 bool
-parse_DATA_LIST_vars_pool (struct pool *pool,
+parse_DATA_LIST_vars_pool (struct lexer *lexer, struct pool *pool,
                            char ***names, size_t *nnames, int pv_opts)
 {
   int retval;
@@ -513,7 +517,7 @@
      re-free it later. */
   assert (!(pv_opts & PV_APPEND));
   
-  retval = parse_DATA_LIST_vars (names, nnames, pv_opts);
+  retval = parse_DATA_LIST_vars (lexer, names, nnames, pv_opts);
   if (retval)
     register_vars_pool (pool, *names, *nnames);
   return retval;
@@ -523,7 +527,7 @@
    existing and the rest are to be created.  Same args as
    parse_DATA_LIST_vars(). */
 bool
-parse_mixed_vars (const struct dictionary *dict, 
+parse_mixed_vars (struct lexer *lexer, const struct dictionary *dict, 
                  char ***names, size_t *nnames, int pv_opts)
 {
   size_t i;
@@ -537,14 +541,14 @@
       *names = NULL;
       *nnames = 0;
     }
-  while (token == T_ID || token == T_ALL)
+  while (lex_token (lexer) == T_ID || lex_token (lexer) == T_ALL)
     {
-      if (token == T_ALL || dict_lookup_var (dict, tokid) != NULL)
+      if (lex_token (lexer) == T_ALL || dict_lookup_var (dict, lex_tokid 
(lexer)) != NULL)
        {
          struct variable **v;
          size_t nv;
 
-         if (!parse_variables (dict, &v, &nv, PV_NONE))
+         if (!parse_variables (lexer, dict, &v, &nv, PV_NONE))
            goto fail;
          *names = xnrealloc (*names, *nnames + nv, sizeof **names);
          for (i = 0; i < nv; i++)
@@ -552,7 +556,7 @@
          free (v);
          *nnames += nv;
        }
-      else if (!parse_DATA_LIST_vars (names, nnames, PV_APPEND))
+      else if (!parse_DATA_LIST_vars (lexer, names, nnames, PV_APPEND))
        goto fail;
     }
   return 1;
@@ -571,7 +575,7 @@
    parse_mixed_vars(), except that all allocations are taken
    from the given POOL. */
 bool
-parse_mixed_vars_pool (const struct dictionary *dict, struct pool *pool,
+parse_mixed_vars_pool (struct lexer *lexer, const struct dictionary *dict, 
struct pool *pool,
                        char ***names, size_t *nnames, int pv_opts)
 {
   int retval;
@@ -582,7 +586,7 @@
      re-free it later. */
   assert (!(pv_opts & PV_APPEND));
 
-  retval = parse_mixed_vars (dict, names, nnames, pv_opts);
+  retval = parse_mixed_vars (lexer, dict, names, nnames, pv_opts);
   if (retval)
     register_vars_pool (pool, *names, *nnames);
   return retval;

Index: language/lexer/variable-parser.h
===================================================================
RCS file: /sources/pspp/pspp/src/language/lexer/variable-parser.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- language/lexer/variable-parser.h    26 Oct 2006 06:16:36 -0000      1.4
+++ language/lexer/variable-parser.h    11 Nov 2006 23:10:00 -0000      1.5
@@ -27,6 +27,7 @@
 struct dictionary;
 struct var_set;
 struct variable;
+struct lexer ;
 
 struct var_set *var_set_create_from_dict (const struct dictionary *d);
 struct var_set *var_set_create_from_array (struct variable *const *var,
@@ -55,19 +56,19 @@
     PV_NO_SCRATCH = 00200      /* Disallow scratch variables. */
   };
 
-struct variable *parse_variable (const struct dictionary *);
-bool parse_variables (const struct dictionary *, struct variable ***, size_t *,
+struct variable *parse_variable (struct lexer *, const struct dictionary *);
+bool parse_variables (struct lexer *, const struct dictionary *, struct 
variable ***, size_t *,
                      int opts);
-bool parse_variables_pool (struct pool *, const struct dictionary *,
+bool parse_variables_pool (struct lexer *, struct pool *, const struct 
dictionary *,
                           struct variable ***, size_t *, int opts);
-bool parse_var_set_vars (const struct var_set *, struct variable ***, size_t *,
+bool parse_var_set_vars (struct lexer *, const struct var_set *, struct 
variable ***, size_t *,
                         int opts);
-bool parse_DATA_LIST_vars (char ***names, size_t *cnt, int opts);
-bool parse_DATA_LIST_vars_pool (struct pool *,
+bool parse_DATA_LIST_vars (struct lexer *, char ***names, size_t *cnt, int 
opts);
+bool parse_DATA_LIST_vars_pool (struct lexer *, struct pool *,
                                char ***names, size_t *cnt, int opts);
-bool parse_mixed_vars (const struct dictionary *dict, 
+bool parse_mixed_vars (struct lexer *, const struct dictionary *dict, 
                       char ***names, size_t *cnt, int opts);
-bool parse_mixed_vars_pool (const struct dictionary *dict, 
+bool parse_mixed_vars_pool (struct lexer *, const struct dictionary *dict, 
                            struct pool *,
                            char ***names, size_t *cnt, int opts);
 

Index: language/stats/aggregate.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/aggregate.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -b -r1.18 -r1.19
--- language/stats/aggregate.c  3 Nov 2006 04:53:51 -0000       1.18
+++ language/stats/aggregate.c  11 Nov 2006 23:10:00 -0000      1.19
@@ -155,7 +155,7 @@
                                        const struct ccase *);
 
 /* Prototypes. */
-static bool parse_aggregate_functions (const struct dictionary *,
+static bool parse_aggregate_functions (struct lexer *, const struct dictionary 
*,
                                       struct agr_proc *);
 static void agr_destroy (struct agr_proc *);
 static bool aggregate_single_case (struct agr_proc *agr,
@@ -173,7 +173,7 @@
 
 /* Parses and executes the AGGREGATE procedure. */
 int
-cmd_aggregate (struct dataset *ds)
+cmd_aggregate (struct lexer *lexer, struct dataset *ds)
 {
   struct dictionary *dict = dataset_dict (ds);
   struct agr_proc agr;
@@ -193,12 +193,12 @@
   dict_set_documents (agr.dict, dict_get_documents (dict));
 
   /* OUTFILE subcommand must be first. */
-  if (!lex_force_match_id ("OUTFILE"))
+  if (!lex_force_match_id (lexer, "OUTFILE"))
     goto error;
-  lex_match ('=');
-  if (!lex_match ('*'))
+  lex_match (lexer, '=');
+  if (!lex_match (lexer, '*'))
     {
-      out_file = fh_parse (FH_REF_FILE | FH_REF_SCRATCH);
+      out_file = fh_parse (lexer, FH_REF_FILE | FH_REF_SCRATCH);
       if (out_file == NULL)
         goto error;
     }
@@ -206,28 +206,28 @@
   /* Read most of the subcommands. */
   for (;;)
     {
-      lex_match ('/');
+      lex_match (lexer, '/');
       
-      if (lex_match_id ("MISSING"))
+      if (lex_match_id (lexer, "MISSING"))
        {
-         lex_match ('=');
-         if (!lex_match_id ("COLUMNWISE"))
+         lex_match (lexer, '=');
+         if (!lex_match_id (lexer, "COLUMNWISE"))
            {
-             lex_error (_("while expecting COLUMNWISE"));
+             lex_error (lexer, _("while expecting COLUMNWISE"));
               goto error;
            }
          agr.missing = COLUMNWISE;
        }
-      else if (lex_match_id ("DOCUMENT"))
+      else if (lex_match_id (lexer, "DOCUMENT"))
         copy_documents = true;
-      else if (lex_match_id ("PRESORTED"))
+      else if (lex_match_id (lexer, "PRESORTED"))
         presorted = true;
-      else if (lex_match_id ("BREAK"))
+      else if (lex_match_id (lexer, "BREAK"))
        {
           int i;
 
-         lex_match ('=');
-          agr.sort = sort_parse_criteria (dict,
+         lex_match (lexer, '=');
+          agr.sort = sort_parse_criteria (lexer, dict,
                                           &agr.break_vars, &agr.break_var_cnt,
                                           &saw_direction, NULL);
           if (agr.sort == NULL)
@@ -242,7 +242,7 @@
        }
       else
         {
-          lex_error (_("expecting BREAK"));
+          lex_error (lexer, _("expecting BREAK"));
           goto error;
         }
     }
@@ -252,8 +252,8 @@
                "the same way as the input data."));
       
   /* Read in the aggregate functions. */
-  lex_match ('/');
-  if (!parse_aggregate_functions (dict, &agr))
+  lex_match (lexer, '/');
+  if (!parse_aggregate_functions (lexer, dict, &agr))
     goto error;
 
   /* Delete documents. */
@@ -359,7 +359,7 @@
 
 /* Parse all the aggregate functions. */
 static bool
-parse_aggregate_functions (const struct dictionary *dict, struct agr_proc *agr)
+parse_aggregate_functions (struct lexer *lexer, const struct dictionary *dict, 
struct agr_proc *agr)
 {
   struct agr_var *tail; /* Tail of linked list starting at agr->vars. */
 
@@ -370,6 +370,7 @@
       char **dest;
       char **dest_label;
       size_t n_dest;
+      struct string function_name;
 
       int include_missing;
       const struct agr_func *function;
@@ -392,11 +393,11 @@
       arg[1].c = NULL;
 
       /* Parse the list of target variables. */
-      while (!lex_match ('='))
+      while (!lex_match (lexer, '='))
        {
          size_t n_dest_prev = n_dest;
          
-         if (!parse_DATA_LIST_vars (&dest, &n_dest,
+         if (!parse_DATA_LIST_vars (lexer, &dest, &n_dest,
                                      PV_APPEND | PV_SINGLE | PV_NO_SCRATCH))
            goto error;
 
@@ -409,41 +410,51 @@
              dest_label[j] = NULL;
          }
          
-         if (token == T_STRING)
+
+         
+         if (lex_token (lexer) == T_STRING)
            {
-             ds_truncate (&tokstr, 255);
-             dest_label[n_dest - 1] = ds_xstrdup (&tokstr);
-             lex_get ();
+             struct string label;
+             ds_init_string (&label, lex_tokstr (lexer));
+
+             ds_truncate (&label, 255);
+             dest_label[n_dest - 1] = ds_xstrdup (&label);
+             lex_get (lexer);
+             ds_destroy (&label);
            }
        }
 
       /* Get the name of the aggregation function. */
-      if (token != T_ID)
+      if (lex_token (lexer) != T_ID)
        {
-         lex_error (_("expecting aggregation function"));
+         lex_error (lexer, _("expecting aggregation function"));
          goto error;
        }
 
       include_missing = 0;
-      if (tokid[strlen (tokid) - 1] == '.')
-       {
+
+      ds_init_string (&function_name, lex_tokstr (lexer));
+
+      ds_chomp (&function_name, '.');
+
+      if (lex_tokid(lexer)[strlen (lex_tokid (lexer)) - 1] == '.')
          include_missing = 1;
-         tokid[strlen (tokid) - 1] = 0;
-       }
       
       for (function = agr_func_tab; function->name; function++)
-       if (!strcasecmp (function->name, tokid))
+       if (!strcasecmp (function->name, ds_cstr (&function_name)))
          break;
       if (NULL == function->name)
        {
-         msg (SE, _("Unknown aggregation function %s."), tokid);
+         msg (SE, _("Unknown aggregation function %s."), 
+              ds_cstr (&function_name));
          goto error;
        }
+      ds_destroy (&function_name);
       func_index = function - agr_func_tab;
-      lex_get ();
+      lex_get (lexer);
 
       /* Check for leading lparen. */
-      if (!lex_match ('('))
+      if (!lex_match (lexer, '('))
        {
          if (func_index == N)
            func_index = N_NO_VARS;
@@ -451,7 +462,7 @@
            func_index = NU_NO_VARS;
          else
            {
-             lex_error (_("expecting `('"));
+             lex_error (lexer, _("expecting `('"));
              goto error;
            }
        }
@@ -466,7 +477,7 @@
            else if (function->n_args)
              pv_opts |= PV_SAME_TYPE;
 
-           if (!parse_variables (dict, &src, &n_src, pv_opts))
+           if (!parse_variables (lexer, dict, &src, &n_src, pv_opts))
              goto error;
          }
 
@@ -477,15 +488,15 @@
              {
                int type;
            
-               lex_match (',');
-               if (token == T_STRING)
+               lex_match (lexer, ',');
+               if (lex_token (lexer) == T_STRING)
                  {
-                   arg[i].c = ds_xstrdup (&tokstr);
+                   arg[i].c = ds_xstrdup (lex_tokstr (lexer));
                    type = ALPHA;
                  }
-               else if (lex_is_number ())
+               else if (lex_is_number (lexer))
                  {
-                   arg[i].f = tokval;
+                   arg[i].f = lex_tokval (lexer);
                    type = NUMERIC;
                  } else {
                    msg (SE, _("Missing argument %d to %s."), i + 1,
@@ -493,7 +504,7 @@
                    goto error;
                  }
            
-               lex_get ();
+               lex_get (lexer);
 
                if (type != src[0]->type)
                  {
@@ -505,9 +516,9 @@
              }
 
          /* Trailing rparen. */
-         if (!lex_match(')'))
+         if (!lex_match (lexer, ')'))
            {
-             lex_error (_("expecting `)'"));
+             lex_error (lexer, _("expecting `)'"));
              goto error;
            }
          
@@ -649,17 +660,18 @@
       free (dest);
       free (dest_label);
 
-      if (!lex_match ('/'))
+      if (!lex_match (lexer, '/'))
        {
-         if (token == '.')
+         if (lex_token (lexer) == '.')
            return true;
 
-         lex_error ("expecting end of command");
+         lex_error (lexer, "expecting end of command");
          return false;
        }
       continue;
       
     error:
+      ds_destroy (&function_name);
       for (i = 0; i < n_dest; i++)
        {
          free (dest[i]);
@@ -1106,7 +1118,8 @@
 /* Aggregate the current case and output it if we passed a
    breakpoint. */
 static bool
-presorted_agr_to_sysfile (const struct ccase *c, void *agr_, const struct 
dataset *ds UNUSED) 
+presorted_agr_to_sysfile (const struct ccase *c, void *agr_, 
+                         const struct dataset *ds UNUSED) 
 {
   struct agr_proc *agr = agr_;
 

Index: language/stats/autorecode.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/autorecode.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- language/stats/autorecode.c 29 Oct 2006 09:51:36 -0000      1.13
+++ language/stats/autorecode.c 11 Nov 2006 23:10:00 -0000      1.14
@@ -102,7 +102,7 @@
 
 /* Performs the AUTORECODE procedure. */
 int
-cmd_autorecode (struct dataset *ds)
+cmd_autorecode (struct lexer *lexer, struct dataset *ds)
 {
   struct autorecode_pgm arc;
   size_t dst_cnt;
@@ -119,15 +119,15 @@
   arc.print = 0;
   dst_cnt = 0;
 
-  lex_match_id ("VARIABLES");
-  lex_match ('=');
-  if (!parse_variables (dataset_dict (ds), &arc.src_vars, &arc.var_cnt,
+  lex_match_id (lexer, "VARIABLES");
+  lex_match (lexer, '=');
+  if (!parse_variables (lexer, dataset_dict (ds), &arc.src_vars, &arc.var_cnt,
                         PV_NO_DUPLICATE))
     goto lossage;
-  if (!lex_force_match_id ("INTO"))
+  if (!lex_force_match_id (lexer, "INTO"))
     goto lossage;
-  lex_match ('=');
-  if (!parse_DATA_LIST_vars (&arc.dst_names, &dst_cnt, PV_NONE))
+  lex_match (lexer, '=');
+  if (!parse_DATA_LIST_vars (lexer, &arc.dst_names, &dst_cnt, PV_NONE))
     goto lossage;
   if (dst_cnt != arc.var_cnt)
     {
@@ -144,14 +144,14 @@
 
       goto lossage;
     }
-  while (lex_match ('/'))
-    if (lex_match_id ("DESCENDING"))
+  while (lex_match (lexer, '/'))
+    if (lex_match_id (lexer, "DESCENDING"))
       arc.direction = DESCENDING;
-    else if (lex_match_id ("PRINT"))
+    else if (lex_match_id (lexer, "PRINT"))
       arc.print = 1;
-  if (token != '.')
+  if (lex_token (lexer) != '.')
     {
-      lex_error (_("expecting end of command"));
+      lex_error (lexer, _("expecting end of command"));
       goto lossage;
     }
 

Index: language/stats/correlations.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/correlations.q,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- language/stats/correlations.q       26 Oct 2006 06:16:36 -0000      1.13
+++ language/stats/correlations.q       11 Nov 2006 23:10:00 -0000      1.14
@@ -46,12 +46,12 @@
 static struct file_handle *matrix_file;
 
 static void free_correlations_state (void);
-static int internal_cmd_correlations (struct dataset *ds);
+static int internal_cmd_correlations (struct lexer *lexer, struct dataset *ds);
 
 int
-cmd_correlations (struct dataset *ds)
+cmd_correlations (struct lexer *lexer, struct dataset *ds)
 {
-  int result = internal_cmd_correlations (ds);
+  int result = internal_cmd_correlations (lexer, ds);
   free_correlations_state ();
   return result;
 }
@@ -71,14 +71,14 @@
 /* (functions) */
 
 int
-internal_cmd_correlations (struct dataset *ds)
+internal_cmd_correlations (struct lexer *lexer, struct dataset *ds)
 {
   struct cmd_correlations cmd;
 
   cor_list = cor_last = NULL;
   matrix_file = NULL;
 
-  if (!parse_correlations (ds, &cmd, NULL))
+  if (!parse_correlations (lexer, ds, &cmd, NULL))
     return CMD_FAILURE;
 
   free_correlations (&cmd);
@@ -87,26 +87,26 @@
 }
 
 static int
-cor_custom_variables (struct dataset *ds, struct cmd_correlations *cmd UNUSED, 
void *aux UNUSED)
+cor_custom_variables (struct lexer *lexer, struct dataset *ds, struct 
cmd_correlations *cmd UNUSED, void *aux UNUSED)
 {
   struct variable **v1, **v2;
   size_t nv1, nv2;
   struct cor_set *cor;
 
   /* Ensure that this is a VARIABLES subcommand. */
-  if (!lex_match_id ("VARIABLES")
-      && (token != T_ID || dict_lookup_var (dataset_dict (ds), tokid) != NULL)
-      && token != T_ALL)
+  if (!lex_match_id (lexer, "VARIABLES")
+      && (lex_token (lexer) != T_ID || dict_lookup_var (dataset_dict (ds), 
lex_tokid (lexer)) != NULL)
+      && lex_token (lexer) != T_ALL)
     return 2;
-  lex_match ('=');
+  lex_match (lexer, '=');
 
-  if (!parse_variables (dataset_dict (ds), &v1, &nv1,
+  if (!parse_variables (lexer, dataset_dict (ds), &v1, &nv1,
                        PV_NO_DUPLICATE | PV_NUMERIC))
     return 0;
   
-  if (lex_match (T_WITH))
+  if (lex_match (lexer, T_WITH))
     {
-      if (!parse_variables (dataset_dict (ds), &v2, &nv2,
+      if (!parse_variables (lexer, dataset_dict (ds), &v2, &nv2,
                            PV_NO_DUPLICATE | PV_NUMERIC))
        {
          free (v1);
@@ -134,21 +134,21 @@
 }
 
 static int
-cor_custom_matrix (struct dataset *ds UNUSED, struct cmd_correlations *cmd 
UNUSED, void *aux UNUSED)
+cor_custom_matrix (struct lexer *lexer, struct dataset *ds UNUSED, struct 
cmd_correlations *cmd UNUSED, void *aux UNUSED)
 {
-  if (!lex_force_match ('('))
+  if (!lex_force_match (lexer, '('))
     return 0;
   
-  if (lex_match ('*'))
+  if (lex_match (lexer, '*'))
     matrix_file = NULL;
   else 
     {
-      matrix_file = fh_parse (FH_REF_FILE);
+      matrix_file = fh_parse (lexer, FH_REF_FILE);
       if (matrix_file == NULL)
         return 0; 
     }
 
-  if (!lex_force_match (')'))
+  if (!lex_force_match (lexer, ')'))
     return 0;
 
   return 1;

Index: language/stats/crosstabs.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/crosstabs.q,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -b -r1.21 -r1.22
--- language/stats/crosstabs.q  5 Nov 2006 05:20:53 -0000       1.21
+++ language/stats/crosstabs.q  11 Nov 2006 23:10:00 -0000      1.22
@@ -176,7 +176,7 @@
 static struct pool *pl_tc;     /* For table cells. */
 static struct pool *pl_col;    /* For column data. */
 
-static int internal_cmd_crosstabs (struct dataset *ds);
+static int internal_cmd_crosstabs (struct lexer *lexer, struct dataset *ds);
 static void precalc (const struct ccase *, void *, const struct dataset *);
 static bool calc_general (const struct ccase *, void *, const struct dataset 
*);
 static bool calc_integer (const struct ccase *, void *, const struct dataset 
*);
@@ -188,9 +188,9 @@
 
 /* Parse and execute CROSSTABS, then clean up. */
 int
-cmd_crosstabs (struct dataset *ds)
+cmd_crosstabs (struct lexer *lexer, struct dataset *ds)
 {
-  int result = internal_cmd_crosstabs (ds);
+  int result = internal_cmd_crosstabs (lexer, ds);
 
   free (variables);
   pool_destroy (pl_tc);
@@ -201,7 +201,7 @@
 
 /* Parses and executes the CROSSTABS procedure. */
 static int
-internal_cmd_crosstabs (struct dataset *ds)
+internal_cmd_crosstabs (struct lexer *lexer, struct dataset *ds)
 {
   int i;
   bool ok;
@@ -213,7 +213,7 @@
   pl_tc = pool_create ();
   pl_col = pool_create ();
 
-  if (!parse_crosstabs (ds, &cmd, NULL))
+  if (!parse_crosstabs (lexer, ds, &cmd, NULL))
     return CMD_FAILURE;
 
   mode = variables ? INTEGER : GENERAL;
@@ -303,7 +303,7 @@
 
 /* Parses the TABLES subcommand. */
 static int
-crs_custom_tables (struct dataset *ds, struct cmd_crosstabs *cmd UNUSED, void 
*aux UNUSED)
+crs_custom_tables (struct lexer *lexer, struct dataset *ds, struct 
cmd_crosstabs *cmd UNUSED, void *aux UNUSED)
 {
   struct var_set *var_set;
   int n_by;
@@ -313,11 +313,11 @@
   int success = 0;
 
   /* Ensure that this is a TABLES subcommand. */
-  if (!lex_match_id ("TABLES")
-      && (token != T_ID || dict_lookup_var (dataset_dict (ds), tokid) == NULL)
-      && token != T_ALL)
+  if (!lex_match_id (lexer, "TABLES")
+      && (lex_token (lexer) != T_ID || dict_lookup_var (dataset_dict (ds), 
lex_tokid (lexer)) == NULL)
+      && lex_token (lexer) != T_ALL)
     return 2;
-  lex_match ('=');
+  lex_match (lexer, '=');
 
   if (variables != NULL)
     var_set = var_set_create_from_array (variables, variables_cnt);
@@ -329,7 +329,7 @@
     {
       by = xnrealloc (by, n_by + 1, sizeof *by);
       by_nvar = xnrealloc (by_nvar, n_by + 1, sizeof *by_nvar);
-      if (!parse_var_set_vars (var_set, &by[n_by], &by_nvar[n_by],
+      if (!parse_var_set_vars (lexer, var_set, &by[n_by], &by_nvar[n_by],
                                PV_NO_DUPLICATE | PV_NO_SCRATCH))
        goto done;
       if (xalloc_oversized (nx, by_nvar[n_by])) 
@@ -340,11 +340,11 @@
       nx *= by_nvar[n_by];
       n_by++;
 
-      if (!lex_match (T_BY))
+      if (!lex_match (lexer, T_BY))
        {
          if (n_by < 2)
            {
-             lex_error (_("expecting BY"));
+             lex_error (lexer, _("expecting BY"));
              goto done;
            }
          else 
@@ -407,7 +407,7 @@
 
 /* Parses the VARIABLES subcommand. */
 static int
-crs_custom_variables (struct dataset *ds, struct cmd_crosstabs *cmd UNUSED, 
void *aux UNUSED)
+crs_custom_variables (struct lexer *lexer, struct dataset *ds, struct 
cmd_crosstabs *cmd UNUSED, void *aux UNUSED)
 {
   if (nxtab)
     {
@@ -415,7 +415,7 @@
       return 0;
     }
 
-  lex_match ('=');
+  lex_match (lexer, '=');
   
   for (;;)
     {
@@ -424,42 +424,43 @@
 
       long min, max;
       
-      if (!parse_variables (dataset_dict (ds), &variables, &variables_cnt,
+      if (!parse_variables (lexer, dataset_dict (ds), 
+                           &variables, &variables_cnt,
                            (PV_APPEND | PV_NUMERIC
                             | PV_NO_DUPLICATE | PV_NO_SCRATCH)))
        return 0;
 
-      if (token != '(')
+      if (lex_token (lexer) != '(')
        {
-         lex_error ("expecting `('");
+         lex_error (lexer, "expecting `('");
          goto lossage;
        }
-      lex_get ();
+      lex_get (lexer);
 
-      if (!lex_force_int ())
+      if (!lex_force_int (lexer))
        goto lossage;
-      min = lex_integer ();
-      lex_get ();
+      min = lex_integer (lexer);
+      lex_get (lexer);
 
-      lex_match (',');
+      lex_match (lexer, ',');
 
-      if (!lex_force_int ())
+      if (!lex_force_int (lexer))
        goto lossage;
-      max = lex_integer ();
+      max = lex_integer (lexer);
       if (max < min)
        {
          msg (SE, _("Maximum value (%ld) less than minimum value (%ld)."),
               max, min);
          goto lossage;
        }
-      lex_get ();
+      lex_get (lexer);
 
-      if (token != ')')
+      if (lex_token (lexer) != ')')
        {
-         lex_error ("expecting `)'");
+         lex_error (lexer, "expecting `)'");
          goto lossage;
        }
-      lex_get ();
+      lex_get (lexer);
       
       for (i = orig_nv; i < variables_cnt; i++) 
         {
@@ -470,7 +471,7 @@
           var_attach_aux (variables[i], vr, var_dtor_free);
        }
       
-      if (token == '/')
+      if (lex_token (lexer) == '/')
        break;
     }
   

Index: language/stats/descriptives.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/descriptives.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -b -r1.16 -r1.17
--- language/stats/descriptives.c       5 Nov 2006 00:35:43 -0000       1.16
+++ language/stats/descriptives.c       11 Nov 2006 23:10:00 -0000      1.17
@@ -169,12 +169,12 @@
   };
 
 /* Parsing. */
-static enum dsc_statistic match_statistic (void);
+static enum dsc_statistic match_statistic (struct lexer *);
 static void free_dsc_proc (struct dsc_proc *);
 
 /* Z-score functions. */
 static bool try_name (const struct dictionary *dict, 
-                     struct dsc_proc *dsc, char *name);
+                     struct dsc_proc *dsc, const char *name);
 static bool generate_z_varname (const struct dictionary *dict, 
                                struct dsc_proc *dsc, char *z_name,
                                const char *name, size_t *z_cnt);
@@ -191,7 +191,7 @@
 
 /* Handles DESCRIPTIVES. */
 int
-cmd_descriptives (struct dataset *ds)
+cmd_descriptives (struct lexer *lexer, struct dataset *ds)
 {
   struct dictionary *dict = dataset_dict (ds);
   struct dsc_proc *dsc;
@@ -219,106 +219,106 @@
   dsc->show_stats = dsc->calc_stats = DEFAULT_STATS;
 
   /* Parse DESCRIPTIVES. */
-  while (token != '.') 
+  while (lex_token (lexer) != '.') 
     {
-      if (lex_match_id ("MISSING"))
+      if (lex_match_id (lexer, "MISSING"))
         {
-          lex_match ('=');
-          while (token != '.' && token != '/') 
+          lex_match (lexer, '=');
+          while (lex_token (lexer) != '.' && lex_token (lexer) != '/') 
             {
-              if (lex_match_id ("VARIABLE"))
+              if (lex_match_id (lexer, "VARIABLE"))
                 dsc->missing_type = DSC_VARIABLE;
-              else if (lex_match_id ("LISTWISE"))
+              else if (lex_match_id (lexer, "LISTWISE"))
                 dsc->missing_type = DSC_LISTWISE;
-              else if (lex_match_id ("INCLUDE"))
+              else if (lex_match_id (lexer, "INCLUDE"))
                 dsc->include_user_missing = 1;
               else
                 {
-                  lex_error (NULL);
+                  lex_error (lexer, NULL);
                   goto error;
                 }
-              lex_match (',');
+              lex_match (lexer, ',');
             }
         }
-      else if (lex_match_id ("SAVE"))
+      else if (lex_match_id (lexer, "SAVE"))
         save_z_scores = 1;
-      else if (lex_match_id ("FORMAT")) 
+      else if (lex_match_id (lexer, "FORMAT")) 
         {
-          lex_match ('=');
-          while (token != '.' && token != '/') 
+          lex_match (lexer, '=');
+          while (lex_token (lexer) != '.' && lex_token (lexer) != '/') 
             {
-              if (lex_match_id ("LABELS"))
+              if (lex_match_id (lexer, "LABELS"))
                 dsc->show_var_labels = 1;
-              else if (lex_match_id ("NOLABELS"))
+              else if (lex_match_id (lexer, "NOLABELS"))
                 dsc->show_var_labels = 0;
-              else if (lex_match_id ("INDEX"))
+              else if (lex_match_id (lexer, "INDEX"))
                 dsc->show_index = 1;
-              else if (lex_match_id ("NOINDEX"))
+              else if (lex_match_id (lexer, "NOINDEX"))
                 dsc->show_index = 0;
-              else if (lex_match_id ("LINE"))
+              else if (lex_match_id (lexer, "LINE"))
                 dsc->format = DSC_LINE;
-              else if (lex_match_id ("SERIAL"))
+              else if (lex_match_id (lexer, "SERIAL"))
                 dsc->format = DSC_SERIAL;
               else
                 {
-                  lex_error (NULL);
+                  lex_error (lexer, NULL);
                   goto error;
                 }
-              lex_match (',');
+              lex_match (lexer, ',');
             }
         }
-      else if (lex_match_id ("STATISTICS")) 
+      else if (lex_match_id (lexer, "STATISTICS")) 
         {
-          lex_match ('=');
+          lex_match (lexer, '=');
           dsc->show_stats = 0;
-          while (token != '.' && token != '/') 
+          while (lex_token (lexer) != '.' && lex_token (lexer) != '/') 
             {
-              if (lex_match (T_ALL)) 
+              if (lex_match (lexer, T_ALL)) 
                 dsc->show_stats |= (1ul << DSC_N_STATS) - 1;
-              else if (lex_match_id ("DEFAULT"))
+              else if (lex_match_id (lexer, "DEFAULT"))
                 dsc->show_stats |= DEFAULT_STATS;
               else
-               dsc->show_stats |= 1ul << (match_statistic ());
-              lex_match (',');
+               dsc->show_stats |= 1ul << (match_statistic (lexer));
+              lex_match (lexer, ',');
             }
           if (dsc->show_stats == 0)
             dsc->show_stats = DEFAULT_STATS;
         }
-      else if (lex_match_id ("SORT")) 
+      else if (lex_match_id (lexer, "SORT")) 
         {
-          lex_match ('=');
-          if (lex_match_id ("NAME"))
+          lex_match (lexer, '=');
+          if (lex_match_id (lexer, "NAME"))
             dsc->sort_by_stat = DSC_NAME;
           else 
            {
-             dsc->sort_by_stat = match_statistic ();
+             dsc->sort_by_stat = match_statistic (lexer);
              if (dsc->sort_by_stat == DSC_NONE )
                dsc->sort_by_stat = DSC_MEAN;
            }
-          if (lex_match ('(')) 
+          if (lex_match (lexer, '(')) 
             {
-              if (lex_match_id ("A"))
+              if (lex_match_id (lexer, "A"))
                 dsc->sort_ascending = 1;
-              else if (lex_match_id ("D"))
+              else if (lex_match_id (lexer, "D"))
                 dsc->sort_ascending = 0;
               else
-                lex_error (NULL);
-              lex_force_match (')');
+                lex_error (lexer, NULL);
+              lex_force_match (lexer, ')');
             }
         }
       else if (var_cnt == 0)
         {
-          if (lex_look_ahead () == '=') 
+          if (lex_look_ahead (lexer) == '=') 
             {
-              lex_match_id ("VARIABLES");
-              lex_match ('=');
+              lex_match_id (lexer, "VARIABLES");
+              lex_match (lexer, '=');
             }
 
-          while (token != '.' && token != '/') 
+          while (lex_token (lexer) != '.' && lex_token (lexer) != '/') 
             {
               int i;
               
-              if (!parse_variables (dataset_dict (ds), &vars, &var_cnt,
+              if (!parse_variables (lexer, dataset_dict (ds), &vars, &var_cnt,
                                     PV_APPEND | PV_NO_DUPLICATE | PV_NUMERIC))
                goto error;
 
@@ -332,34 +332,34 @@
                 }
               dsc->var_cnt = var_cnt;
 
-              if (lex_match ('(')) 
+              if (lex_match (lexer, '(')) 
                 {
-                  if (token != T_ID) 
+                  if (lex_token (lexer) != T_ID) 
                     {
-                      lex_error (NULL);
+                      lex_error (lexer, NULL);
                       goto error;
                     }
-                  if (try_name (dict, dsc, tokid)) 
+                  if (try_name (dict, dsc, lex_tokid (lexer))) 
                     {
-                      strcpy (dsc->vars[dsc->var_cnt - 1].z_name, tokid);
+                      strcpy (dsc->vars[dsc->var_cnt - 1].z_name, lex_tokid 
(lexer));
                       z_cnt++;
                     }
                   else
                     msg (SE, _("Z-score variable name %s would be"
-                               " a duplicate variable name."), tokid);
-                  lex_get ();
-                  if (!lex_force_match (')'))
+                               " a duplicate variable name."), lex_tokid 
(lexer));
+                  lex_get (lexer);
+                  if (!lex_force_match (lexer, ')'))
                    goto error;
                 }
             }
         }
       else 
         {
-          lex_error (NULL);
+          lex_error (lexer, NULL);
           goto error; 
         }
 
-      lex_match ('/');
+      lex_match (lexer, '/');
     }
   if (var_cnt == 0)
     {
@@ -436,18 +436,18 @@
    specifiers). Emits an error if the current token ID does not name a
    statistic. */
 static enum dsc_statistic
-match_statistic (void) 
+match_statistic (struct lexer *lexer) 
 {
-  if (token == T_ID) 
+  if (lex_token (lexer) == T_ID) 
     {
       enum dsc_statistic stat;
 
       for (stat = 0; stat < DSC_N_STATS; stat++)
-        if (lex_match_id (dsc_info[stat].identifier)) 
+        if (lex_match_id (lexer, dsc_info[stat].identifier)) 
          return stat;
 
-      lex_get();
-      lex_error (_("expecting statistic name: reverting to default"));
+      lex_get (lexer);
+      lex_error (lexer, _("expecting statistic name: reverting to default"));
     }
 
   return DSC_NONE;
@@ -473,7 +473,8 @@
 /* Returns false if NAME is a duplicate of any existing variable name or
    of any previously-declared z-var name; otherwise returns true. */
 static bool
-try_name (const struct dictionary *dict, struct dsc_proc *dsc, char *name)
+try_name (const struct dictionary *dict, struct dsc_proc *dsc, 
+         const char *name)
 {
   size_t i;
 

Index: language/stats/examine.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/examine.q,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- language/stats/examine.q    5 Nov 2006 00:35:43 -0000       1.14
+++ language/stats/examine.q    11 Nov 2006 23:10:00 -0000      1.15
@@ -110,7 +110,7 @@
 static struct metrics *totals=0;
 
 /* Parse the clause specifying the factors */
-static int examine_parse_independent_vars (const struct dictionary *dict, 
struct cmd_examine *cmd);
+static int examine_parse_independent_vars (struct lexer *lexer, const struct 
dictionary *dict, struct cmd_examine *cmd);
 
 
 
@@ -191,14 +191,14 @@
 
 
 int
-cmd_examine (struct dataset *ds)
+cmd_examine (struct lexer *lexer, struct dataset *ds)
 {
   bool ok;
 
   subc_list_double_create(&percentile_list);
   percentile_algorithm = PC_HAVERAGE;
 
-  if ( !parse_examine (ds, &cmd, NULL) )
+  if ( !parse_examine (lexer, ds, &cmd, NULL) )
     return CMD_FAILURE;
 
   /* If /MISSING=INCLUDE is set, then user missing values are ignored */
@@ -429,43 +429,43 @@
 
 /* Parse the PERCENTILES subcommand */
 static int
-xmn_custom_percentiles(struct dataset *ds UNUSED, 
+xmn_custom_percentiles(struct lexer *lexer, struct dataset *ds UNUSED, 
                       struct cmd_examine *p UNUSED, void *aux UNUSED)
 {
   sbc_percentile = 1;
 
-  lex_match('=');
+  lex_match (lexer, '=');
 
-  lex_match('(');
+  lex_match (lexer, '(');
 
-  while ( lex_is_number() ) 
+  while ( lex_is_number (lexer) ) 
     {
-      subc_list_double_push (&percentile_list, lex_number());
+      subc_list_double_push (&percentile_list, lex_number (lexer));
 
-      lex_get();
+      lex_get (lexer);
 
-      lex_match(',') ;
+      lex_match (lexer, ',') ;
     }
-  lex_match(')');
+  lex_match (lexer, ')');
 
-  lex_match('=');
+  lex_match (lexer, '=');
 
-  if ( lex_match_id("HAVERAGE"))
+  if ( lex_match_id (lexer, "HAVERAGE"))
     percentile_algorithm = PC_HAVERAGE; 
 
-  else if ( lex_match_id("WAVERAGE"))
+  else if ( lex_match_id (lexer, "WAVERAGE"))
     percentile_algorithm = PC_WAVERAGE; 
 
-  else if ( lex_match_id("ROUND"))
+  else if ( lex_match_id (lexer, "ROUND"))
     percentile_algorithm = PC_ROUND;
 
-  else if ( lex_match_id("EMPIRICAL"))
+  else if ( lex_match_id (lexer, "EMPIRICAL"))
     percentile_algorithm = PC_EMPIRICAL;
 
-  else if ( lex_match_id("AEMPIRICAL"))
+  else if ( lex_match_id (lexer, "AEMPIRICAL"))
     percentile_algorithm = PC_AEMPIRICAL; 
 
-  else if ( lex_match_id("NONE"))
+  else if ( lex_match_id (lexer, "NONE"))
     percentile_algorithm = PC_NONE; 
 
 
@@ -485,7 +485,7 @@
 
 /* TOTAL and NOTOTAL are simple, mutually exclusive flags */
 static int
-xmn_custom_total (struct dataset *ds UNUSED, struct cmd_examine *p, void *aux 
UNUSED)
+xmn_custom_total (struct lexer *lexer UNUSED, struct dataset *ds UNUSED, 
struct cmd_examine *p, void *aux UNUSED)
 {
   if ( p->sbc_nototal ) 
     {
@@ -497,7 +497,7 @@
 }
 
 static int
-xmn_custom_nototal (struct dataset *ds UNUSED, 
+xmn_custom_nototal (struct lexer *lexer UNUSED, struct dataset *ds UNUSED, 
                    struct cmd_examine *p, void *aux UNUSED)
 {
   if ( p->sbc_total ) 
@@ -514,18 +514,18 @@
 /* Parser for the variables sub command  
    Returns 1 on success */
 static int
-xmn_custom_variables(struct dataset *ds, struct cmd_examine *cmd, void *aux 
UNUSED)
+xmn_custom_variables (struct lexer *lexer, struct dataset *ds, struct 
cmd_examine *cmd, void *aux UNUSED)
 {
   const struct dictionary *dict = dataset_dict (ds);
-  lex_match('=');
+  lex_match (lexer, '=');
 
-  if ((token != T_ID || dict_lookup_var (dict, tokid) == NULL)
-      && token != T_ALL)
+  if ((lex_token (lexer) != T_ID || dict_lookup_var (dict, lex_tokid (lexer)) 
== NULL)
+      && lex_token (lexer) != T_ALL)
     {
       return 2;
     }
   
-  if (!parse_variables (dict, &dependent_vars, &n_dependent_vars,
+  if (!parse_variables (lexer, dict, &dependent_vars, &n_dependent_vars,
                        PV_NO_DUPLICATE | PV_NUMERIC | PV_NO_SCRATCH) )
     {
       free (dependent_vars);
@@ -536,10 +536,10 @@
 
   totals = xnmalloc (n_dependent_vars, sizeof *totals);
 
-  if ( lex_match(T_BY))
+  if ( lex_match (lexer, T_BY))
     {
       int success ; 
-      success =  examine_parse_independent_vars (dict, cmd);
+      success =  examine_parse_independent_vars (lexer, dict, cmd);
       if ( success != 1 ) {
         free (dependent_vars);
        free (totals) ; 
@@ -554,35 +554,35 @@
 
 /* Parse the clause specifying the factors */
 static int
-examine_parse_independent_vars (const struct dictionary *dict, struct 
cmd_examine *cmd)
+examine_parse_independent_vars (struct lexer *lexer, const struct dictionary 
*dict, struct cmd_examine *cmd)
 {
   int success;
   struct factor *sf = xmalloc (sizeof *sf);
 
-  if ((token != T_ID || dict_lookup_var (dict, tokid) == NULL)
-      && token != T_ALL)
+  if ((lex_token (lexer) != T_ID || dict_lookup_var (dict, lex_tokid (lexer)) 
== NULL)
+      && lex_token (lexer) != T_ALL)
     {
       free ( sf ) ;
       return 2;
     }
 
 
-  sf->indep_var[0] = parse_variable (dict);
+  sf->indep_var[0] = parse_variable (lexer, dict);
   sf->indep_var[1] = 0;
 
-  if ( token == T_BY ) 
+  if ( lex_token (lexer) == T_BY ) 
     {
 
-      lex_match(T_BY);
+      lex_match (lexer, T_BY);
 
-      if ((token != T_ID || dict_lookup_var (dict, tokid) == NULL)
-         && token != T_ALL)
+      if ((lex_token (lexer) != T_ID || dict_lookup_var (dict, lex_tokid 
(lexer)) == NULL)
+         && lex_token (lexer) != T_ALL)
        {
          free ( sf ) ;
          return 2;
        }
 
-      sf->indep_var[1] = parse_variable (dict);
+      sf->indep_var[1] = parse_variable (lexer, dict);
 
     }
 
@@ -596,12 +596,12 @@
   sf->next = factors;
   factors = sf;
   
-  lex_match(',');
+  lex_match (lexer, ',');
 
-  if ( token == '.' || token == '/' ) 
+  if ( lex_token (lexer) == '.' || lex_token (lexer) == '/' ) 
     return 1;
 
-  success =  examine_parse_independent_vars (dict, cmd);
+  success =  examine_parse_independent_vars (lexer, dict, cmd);
   
   if ( success != 1 ) 
     free ( sf ) ; 

Index: language/stats/flip.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/flip.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- language/stats/flip.c       26 Oct 2006 06:16:36 -0000      1.13
+++ language/stats/flip.c       11 Nov 2006 23:10:00 -0000      1.14
@@ -90,7 +90,7 @@
 
 /* Parses and executes FLIP. */
 int
-cmd_flip (struct dataset *ds)
+cmd_flip (struct lexer *lexer, struct dataset *ds)
 {
   struct flip_pgm *flip;
   struct case_sink *sink;
@@ -112,24 +112,24 @@
   flip->new_names_tail = NULL;
   flip->file = NULL;
 
-  lex_match ('/');
-  if (lex_match_id ("VARIABLES"))
+  lex_match (lexer, '/');
+  if (lex_match_id (lexer, "VARIABLES"))
     {
-      lex_match ('=');
-      if (!parse_variables (dict, &flip->var, &flip->var_cnt,
+      lex_match (lexer, '=');
+      if (!parse_variables (lexer, dict, &flip->var, &flip->var_cnt,
                             PV_NO_DUPLICATE))
        goto error;
-      lex_match ('/');
+      lex_match (lexer, '/');
     }
   else
     dict_get_vars (dict, &flip->var, &flip->var_cnt, 1u << DC_SYSTEM);
   pool_register (flip->pool, free, flip->var);
 
-  lex_match ('/');
-  if (lex_match_id ("NEWNAMES"))
+  lex_match (lexer, '/');
+  if (lex_match_id (lexer, "NEWNAMES"))
     {
-      lex_match ('=');
-      flip->new_names = parse_variable (dict);
+      lex_match (lexer, '=');
+      flip->new_names = parse_variable (lexer, dict);
       if (!flip->new_names)
         goto error;
     }
@@ -178,7 +178,7 @@
   /* Set up flipped data for reading. */
   proc_set_source (ds, flip_source_create (flip));
 
-  return ok ? lex_end_of_command () : CMD_CASCADING_FAILURE;
+  return ok ? lex_end_of_command (lexer) : CMD_CASCADING_FAILURE;
 
  error:
   destroy_flip_pgm (flip);

Index: language/stats/frequencies.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/frequencies.q,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -b -r1.21 -r1.22
--- language/stats/frequencies.q        29 Oct 2006 11:16:07 -0000      1.21
+++ language/stats/frequencies.q        11 Nov 2006 23:10:00 -0000      1.22
@@ -305,15 +305,15 @@
 
 /* Parser and outline. */
 
-static int internal_cmd_frequencies (struct dataset *ds);
+static int internal_cmd_frequencies (struct lexer *lexer, struct dataset *ds);
 
 int
-cmd_frequencies (struct dataset *ds)
+cmd_frequencies (struct lexer *lexer, struct dataset *ds)
 {
   int result;
 
   int_pool = pool_create ();
-  result = internal_cmd_frequencies (ds);
+  result = internal_cmd_frequencies (lexer, ds);
   pool_destroy (int_pool);
   int_pool=0;
   pool_destroy (gen_pool);
@@ -324,7 +324,7 @@
 }
 
 static int
-internal_cmd_frequencies (struct dataset *ds)
+internal_cmd_frequencies (struct lexer *lexer, struct dataset *ds)
 {
   int i;
   bool ok;
@@ -335,7 +335,7 @@
   n_variables = 0;
   v_variables = NULL;
 
-  if (!parse_frequencies (ds, &cmd, NULL))
+  if (!parse_frequencies (lexer, ds, &cmd, NULL))
     return CMD_FAILURE;
 
   if (cmd.onepage_limit == NOT_LONG)
@@ -376,7 +376,7 @@
          int pl;
          subc_list_double *ptl_list = &cmd.dl_percentiles[i];
          for ( pl = 0 ; pl < subc_list_double_count(ptl_list); ++pl)
-             add_percentile(subc_list_double_at(ptl_list,pl) / 100.0 );
+             add_percentile (subc_list_double_at(ptl_list, pl) / 100.0 );
        }
     }
   if ( cmd.sbc_ntiles ) 
@@ -385,7 +385,7 @@
        {
          int j;
          for (j = 0; j <= cmd.n_ntiles[i]; ++j ) 
-             add_percentile(j / (double) cmd.n_ntiles[i]);
+             add_percentile (j / (double) cmd.n_ntiles[i]);
        }
     }
   
@@ -665,7 +665,7 @@
 
          norm.N = vf->tab.valid_cases;
 
-         calc_stats(v,d);
+         calc_stats (v, d);
          norm.mean = d[frq_mean];
          norm.stddev = d[frq_stddev];
 
@@ -793,7 +793,7 @@
 /* Parses the VARIABLES subcommand, adding to
    {n_variables,v_variables}. */
 static int
-frq_custom_variables (struct dataset *ds, struct cmd_frequencies *cmd UNUSED, 
void *aux UNUSED)
+frq_custom_variables (struct lexer *lexer, struct dataset *ds, struct 
cmd_frequencies *cmd UNUSED, void *aux UNUSED)
 {
   int mode;
   int min = 0, max = 0;
@@ -801,31 +801,31 @@
   size_t old_n_variables = n_variables;
   size_t i;
 
-  lex_match ('=');
-  if (token != T_ALL && (token != T_ID
-                         || dict_lookup_var (dataset_dict (ds), tokid) == 
NULL))
+  lex_match (lexer, '=');
+  if (lex_token (lexer) != T_ALL && (lex_token (lexer) != T_ID
+                         || dict_lookup_var (dataset_dict (ds), lex_tokid 
(lexer)) == NULL))
     return 2;
 
-  if (!parse_variables (dataset_dict (ds), &v_variables, &n_variables,
+  if (!parse_variables (lexer, dataset_dict (ds), &v_variables, &n_variables,
                        PV_APPEND | PV_NO_SCRATCH))
     return 0;
 
-  if (!lex_match ('('))
+  if (!lex_match (lexer, '('))
     mode = FRQM_GENERAL;
   else
     {
       mode = FRQM_INTEGER;
-      if (!lex_force_int ())
+      if (!lex_force_int (lexer))
        return 0;
-      min = lex_integer ();
-      lex_get ();
-      if (!lex_force_match (','))
+      min = lex_integer (lexer);
+      lex_get (lexer);
+      if (!lex_force_match (lexer, ','))
        return 0;
-      if (!lex_force_int ())
+      if (!lex_force_int (lexer))
        return 0;
-      max = lex_integer ();
-      lex_get ();
-      if (!lex_force_match (')'))
+      max = lex_integer (lexer);
+      lex_get (lexer);
+      if (!lex_force_match (lexer, ')'))
        return 0;
       if (max < min)
        {
@@ -881,11 +881,11 @@
 /* Parses the GROUPED subcommand, setting the n_grouped, grouped
    fields of specified variables. */
 static int
-frq_custom_grouped (struct dataset *ds, struct cmd_frequencies *cmd UNUSED, 
void *aux UNUSED)
+frq_custom_grouped (struct lexer *lexer, struct dataset *ds, struct 
cmd_frequencies *cmd UNUSED, void *aux UNUSED)
 {
-  lex_match ('=');
-  if ((token == T_ID && dict_lookup_var (dataset_dict (ds), tokid) != NULL)
-      || token == T_ID)
+  lex_match (lexer, '=');
+  if ((lex_token (lexer) == T_ID && dict_lookup_var (dataset_dict (ds), 
lex_tokid (lexer)) != NULL)
+      || lex_token (lexer) == T_ID)
     for (;;)
       {
        size_t i;
@@ -898,27 +898,27 @@
        size_t n;
        struct variable **v;
 
-       if (!parse_variables (dataset_dict (ds), &v, &n,
+       if (!parse_variables (lexer, dataset_dict (ds), &v, &n,
                               PV_NO_DUPLICATE | PV_NUMERIC))
          return 0;
-       if (lex_match ('('))
+       if (lex_match (lexer, '('))
          {
            nl = ml = 0;
            dl = NULL;
-           while (lex_integer ())
+           while (lex_integer (lexer))
              {
                if (nl >= ml)
                  {
                    ml += 16;
                    dl = pool_nrealloc (int_pool, dl, ml, sizeof *dl);
                  }
-               dl[nl++] = tokval;
-               lex_get ();
-               lex_match (',');
+               dl[nl++] = lex_tokval (lexer);
+               lex_get (lexer);
+               lex_match (lexer, ',');
              }
            /* Note that nl might still be 0 and dl might still be
               NULL.  That's okay. */
-           if (!lex_match (')'))
+           if (!lex_match (lexer, ')'))
              {
                free (v);
                msg (SE, _("`)' expected after GROUPED interval list."));
@@ -949,12 +949,12 @@
                 }
             }
        free (v);
-       if (!lex_match ('/'))
+       if (!lex_match (lexer, '/'))
          break;
-       if ((token != T_ID || dict_lookup_var (dataset_dict (ds), tokid) != 
NULL)
-            && token != T_ALL)
+       if ((lex_token (lexer) != T_ID || dict_lookup_var (dataset_dict (ds), 
lex_tokid (lexer)) != NULL)
+            && lex_token (lexer) != T_ALL)
          {
-           lex_put_back ('/');
+           lex_put_back (lexer, '/');
            break;
          }
       }
@@ -979,7 +979,7 @@
        break;
     }
 
-  if (i >= n_percentiles || tokval != percentiles[i].p)
+  if (i >= n_percentiles || x != percentiles[i].p)
     {
       percentiles = pool_nrealloc (int_pool, percentiles,
                                    n_percentiles + 1, sizeof *percentiles);

Index: language/stats/means.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/means.q,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- language/stats/means.q      26 Oct 2006 06:16:36 -0000      1.10
+++ language/stats/means.q      11 Nov 2006 23:10:00 -0000      1.11
@@ -61,7 +61,7 @@
 
 /* Parses and executes the T-TEST procedure. */
 int
-cmd_means (struct dataset *ds)
+cmd_means (struct lexer *lexer, struct dataset *ds)
 {
   struct cmd_means cmd;
   int success = CMD_FAILURE;
@@ -71,7 +71,7 @@
   v_dim = NULL;
   v_var = NULL;
 
-  if (!parse_means (ds, &cmd, NULL))
+  if (!parse_means (lexer, ds, &cmd, NULL))
     goto free;
 
   if (cmd.sbc_cells)
@@ -122,15 +122,15 @@
 
 /* Parses the TABLES subcommand. */
 static int
-mns_custom_tables (struct dataset *ds, struct cmd_means *cmd, void *aux UNUSED)
+mns_custom_tables (struct lexer *lexer, struct dataset *ds, struct cmd_means 
*cmd, void *aux UNUSED)
 {
   struct var_set *var_set;
   
-  if (!lex_match_id ("TABLES")
-      && (token != T_ID || dict_lookup_var (dataset_dict (ds), tokid) == NULL)
-      && token != T_ALL)
+  if (!lex_match_id (lexer, "TABLES")
+      && (lex_token (lexer) != T_ID || dict_lookup_var (dataset_dict (ds), 
lex_tokid (lexer)) == NULL)
+      && lex_token (lexer) != T_ALL)
     return 2;
-  lex_match ('=');
+  lex_match (lexer, '=');
 
   if (cmd->sbc_tables)
     {
@@ -147,7 +147,7 @@
       size_t nvl;
       struct variable **vl;
 
-      if (!parse_var_set_vars (var_set, &vl, &nvl,
+      if (!parse_var_set_vars (lexer, var_set, &vl, &nvl,
                                PV_NO_DUPLICATE | PV_NO_SCRATCH)) 
         goto lossage;
       
@@ -158,7 +158,7 @@
       nv_dim[n_dim - 1] = nvl;
       v_dim[n_dim - 1] = vl;
     }
-  while (lex_match (T_BY));
+  while (lex_match (lexer, T_BY));
 
   var_set_destroy (var_set);
   return 1;

Index: language/stats/oneway.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/oneway.q,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- language/stats/oneway.q     5 Nov 2006 00:35:44 -0000       1.14
+++ language/stats/oneway.q     11 Nov 2006 23:10:00 -0000      1.15
@@ -112,12 +112,12 @@
 
 
 int
-cmd_oneway (struct dataset *ds)
+cmd_oneway (struct lexer *lexer, struct dataset *ds)
 {
   int i;
   bool ok;
 
-  if ( !parse_oneway (ds, &cmd, NULL) )
+  if ( !parse_oneway (lexer, ds, &cmd, NULL) )
     return CMD_FAILURE;
 
   /* What statistics were requested */
@@ -213,18 +213,19 @@
 
 /* Parser for the variables sub command */
 static int
-oneway_custom_variables(struct dataset *ds, struct cmd_oneway *cmd UNUSED, 
+oneway_custom_variables (struct lexer *lexer, 
+                       struct dataset *ds, struct cmd_oneway *cmd UNUSED, 
                        void *aux UNUSED)
 {
   struct dictionary *dict = dataset_dict (ds);
 
-  lex_match('=');
+  lex_match (lexer, '=');
 
-  if ((token != T_ID || dict_lookup_var (dict, tokid) == NULL)
-      && token != T_ALL)
+  if ((lex_token (lexer) != T_ID || dict_lookup_var (dict, lex_tokid (lexer)) 
== NULL)
+      && lex_token (lexer) != T_ALL)
     return 2;
 
-  if (!parse_variables (dict, &vars, &n_vars,
+  if (!parse_variables (lexer, dict, &vars, &n_vars,
                        PV_DUPLICATE 
                        | PV_NUMERIC | PV_NO_SCRATCH) )
     {
@@ -234,14 +235,14 @@
 
   assert(n_vars);
 
-  if ( ! lex_match(T_BY))
+  if ( ! lex_match (lexer, T_BY))
     return 2;
 
-  indep_var = parse_variable (dict);
+  indep_var = parse_variable (lexer, dict);
 
   if ( !indep_var ) 
     {
-      msg(SE,_("`%s' is not a variable name"),tokid);
+      msg(SE,_("`%s' is not a variable name"),lex_tokid (lexer));
       return 0;
     }
 

Index: language/stats/rank.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/rank.q,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -b -r1.18 -r1.19
--- language/stats/rank.q       5 Nov 2006 00:35:44 -0000       1.18
+++ language/stats/rank.q       11 Nov 2006 23:10:00 -0000      1.19
@@ -729,7 +729,6 @@
   return var;
 }
 
-int cmd_rank(struct dataset *ds);
 
 static void
 rank_cleanup(void)
@@ -758,14 +757,14 @@
 }
 
 int
-cmd_rank (struct dataset *ds)
+cmd_rank (struct lexer *lexer, struct dataset *ds)
 {
   bool result;
   struct variable *order;
   size_t i;
   n_rank_specs = 0;
 
-  if ( !parse_rank (ds, &cmd, NULL) )
+  if ( !parse_rank (lexer, ds, &cmd, NULL) )
     {
       rank_cleanup ();
     return CMD_FAILURE;
@@ -929,27 +928,28 @@
 /* Parser for the variables sub command  
    Returns 1 on success */
 static int
-rank_custom_variables (struct dataset *ds, struct cmd_rank *cmd UNUSED, void 
*aux UNUSED)
+rank_custom_variables (struct lexer *lexer, struct dataset *ds, struct 
cmd_rank *cmd UNUSED, void *aux UNUSED)
 {
   static const int terminators[2] = {T_BY, 0};
 
-  lex_match('=');
+  lex_match (lexer, '=');
 
-  if ((token != T_ID || dict_lookup_var (dataset_dict (ds), tokid) == NULL)
-      && token != T_ALL)
+  if ((lex_token (lexer) != T_ID || dict_lookup_var (dataset_dict (ds), 
lex_tokid (lexer)) == NULL)
+      && lex_token (lexer) != T_ALL)
       return 2;
 
-  sc = sort_parse_criteria (dataset_dict (ds), 
+  sc = sort_parse_criteria (lexer, dataset_dict (ds), 
                            &src_vars, &n_src_vars, 0, terminators);
 
-  if ( lex_match(T_BY)  )
+  if ( lex_match (lexer, T_BY)  )
     {
-      if ((token != T_ID || dict_lookup_var (dataset_dict (ds), tokid) == 
NULL))
+      if ((lex_token (lexer) != T_ID || dict_lookup_var (dataset_dict (ds), 
lex_tokid (lexer)) == NULL))
        {
          return 2;
        }
 
-      if (!parse_variables (dataset_dict (ds), &group_vars, &n_group_vars,
+      if (!parse_variables (lexer, dataset_dict (ds), 
+                           &group_vars, &n_group_vars,
                            PV_NO_DUPLICATE | PV_NUMERIC | PV_NO_SCRATCH) )
        {
          free (group_vars);
@@ -963,7 +963,7 @@
 
 /* Parse the [/rank INTO var1 var2 ... varN ] clause */
 static int
-parse_rank_function(struct dictionary *dict, struct cmd_rank *cmd UNUSED, enum 
RANK_FUNC f)
+parse_rank_function (struct lexer *lexer, struct dictionary *dict, struct 
cmd_rank *cmd UNUSED, enum RANK_FUNC f)
 {
   int var_count = 0;
   
@@ -975,16 +975,16 @@
   rank_specs[n_rank_specs - 1].destvars = 
            xcalloc (sc->crit_cnt, sizeof (struct variable *));
          
-  if (lex_match_id("INTO"))
+  if (lex_match_id (lexer, "INTO"))
     {
       struct variable *destvar;
 
-      while( token == T_ID ) 
+      while( lex_token (lexer) == T_ID ) 
        {
 
-         if ( dict_lookup_var (dict, tokid) != NULL )
+         if ( dict_lookup_var (dict, lex_tokid (lexer)) != NULL )
            {
-             msg(SE, _("Variable %s already exists."), tokid);
+             msg(SE, _("Variable %s already exists."), lex_tokid (lexer));
              return 0;
            }
          if ( var_count >= sc->crit_cnt ) 
@@ -993,10 +993,10 @@
              return 0;
            }
 
-         destvar = create_rank_variable (dict, f, src_vars[var_count], tokid);
+         destvar = create_rank_variable (dict, f, src_vars[var_count], 
lex_tokid (lexer));
          rank_specs[n_rank_specs - 1].destvars[var_count] = destvar ;
 
-         lex_get();
+         lex_get (lexer);
          ++var_count;
        }
     }
@@ -1006,74 +1006,74 @@
 
 
 static int
-rank_custom_rank(struct dataset *ds, struct cmd_rank *cmd, void *aux UNUSED )
+rank_custom_rank (struct lexer *lexer, struct dataset *ds, struct cmd_rank 
*cmd, void *aux UNUSED )
 {
   struct dictionary *dict = dataset_dict (ds);
 
-  return parse_rank_function (dict, cmd, RANK);
+  return parse_rank_function (lexer, dict, cmd, RANK);
 }
 
 static int
-rank_custom_normal(struct dataset *ds, struct cmd_rank *cmd, void *aux UNUSED )
+rank_custom_normal (struct lexer *lexer, struct dataset *ds, struct cmd_rank 
*cmd, void *aux UNUSED )
 {
   struct  dictionary *dict = dataset_dict (ds);
 
-  return parse_rank_function (dict, cmd, NORMAL);
+  return parse_rank_function (lexer, dict, cmd, NORMAL);
 }
 
 static int
-rank_custom_percent(struct dataset *ds, struct cmd_rank *cmd, void *aux UNUSED 
)
+rank_custom_percent (struct lexer *lexer, struct dataset *ds, struct cmd_rank 
*cmd, void *aux UNUSED )
 {
   struct dictionary *dict = dataset_dict (ds);
 
-  return parse_rank_function (dict, cmd, PERCENT);
+  return parse_rank_function (lexer, dict, cmd, PERCENT);
 }
 
 static int
-rank_custom_rfraction(struct dataset *ds, struct cmd_rank *cmd, void *aux 
UNUSED )
+rank_custom_rfraction (struct lexer *lexer, struct dataset *ds, struct 
cmd_rank *cmd, void *aux UNUSED )
 {
   struct dictionary *dict = dataset_dict (ds);
 
-  return parse_rank_function (dict, cmd, RFRACTION);
+  return parse_rank_function (lexer, dict, cmd, RFRACTION);
 }
 
 static int
-rank_custom_proportion(struct dataset *ds, struct cmd_rank *cmd, void *aux 
UNUSED )
+rank_custom_proportion (struct lexer *lexer, struct dataset *ds, struct 
cmd_rank *cmd, void *aux UNUSED )
 {
   struct dictionary *dict = dataset_dict (ds);
 
-  return parse_rank_function (dict, cmd, PROPORTION);
+  return parse_rank_function (lexer, dict, cmd, PROPORTION);
 }
 
 static int
-rank_custom_n (struct dataset *ds, struct cmd_rank *cmd, void *aux UNUSED )
+rank_custom_n (struct lexer *lexer, struct dataset *ds, struct cmd_rank *cmd, 
void *aux UNUSED )
 {
   struct dictionary *dict = dataset_dict (ds);
 
-  return parse_rank_function (dict, cmd, N);
+  return parse_rank_function (lexer, dict, cmd, N);
 }
 
 static int
-rank_custom_savage(struct dataset *ds, struct cmd_rank *cmd, void *aux UNUSED )
+rank_custom_savage (struct lexer *lexer, struct dataset *ds, struct cmd_rank 
*cmd, void *aux UNUSED )
 {
   struct dictionary *dict = dataset_dict (ds);
 
-  return parse_rank_function (dict, cmd, SAVAGE);
+  return parse_rank_function (lexer, dict, cmd, SAVAGE);
 }
 
 
 static int
-rank_custom_ntiles (struct dataset *ds, struct cmd_rank *cmd, void *aux UNUSED 
)
+rank_custom_ntiles (struct lexer *lexer, struct dataset *ds, struct cmd_rank 
*cmd, void *aux UNUSED )
 {
   struct dictionary *dict = dataset_dict (ds);
 
-  if ( lex_force_match('(') ) 
+  if ( lex_force_match (lexer, '(') ) 
     {
-      if ( lex_force_int() ) 
+      if ( lex_force_int (lexer) ) 
        {
-         k_ntiles = lex_integer ();
-         lex_get();
-         lex_force_match(')');
+         k_ntiles = lex_integer (lexer);
+         lex_get (lexer);
+         lex_force_match (lexer, ')');
        }
       else
        return 0;
@@ -1081,5 +1081,5 @@
   else
     return 0;
 
-  return parse_rank_function(dict, cmd, NTILES);
+  return parse_rank_function (lexer, dict, cmd, NTILES);
 }

Index: language/stats/regression.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/regression.q,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -b -r1.37 -r1.38
--- language/stats/regression.q 5 Nov 2006 00:35:44 -0000       1.37
+++ language/stats/regression.q 11 Nov 2006 23:10:00 -0000      1.38
@@ -916,31 +916,31 @@
 }
 
 static int
-regression_custom_export (struct dataset *ds UNUSED, struct cmd_regression 
*cmd UNUSED, void *aux UNUSED)
+regression_custom_export (struct lexer *lexer, struct dataset *ds UNUSED, 
struct cmd_regression *cmd UNUSED, void *aux UNUSED)
 {
   /* 0 on failure, 1 on success, 2 on failure that should result in syntax 
error */
-  if (!lex_force_match ('('))
+  if (!lex_force_match (lexer, '('))
     return 0;
 
-  if (lex_match ('*'))
+  if (lex_match (lexer, '*'))
     model_file = NULL;
   else
     {
-      model_file = fh_parse (FH_REF_FILE);
+      model_file = fh_parse (lexer, FH_REF_FILE);
       if (model_file == NULL)
        return 0;
     }
 
-  if (!lex_force_match (')'))
+  if (!lex_force_match (lexer, ')'))
     return 0;
 
   return 1;
 }
 
 int
-cmd_regression (struct dataset *ds)
+cmd_regression (struct lexer *lexer, struct dataset *ds)
 {
-  if (!parse_regression (ds, &cmd, NULL))
+  if (!parse_regression (lexer, ds, &cmd, NULL))
     return CMD_FAILURE;
 
   models = xnmalloc (cmd.n_dependent, sizeof *models);
@@ -1004,20 +1004,20 @@
 
 /* Parser for the variables sub command */
 static int
-regression_custom_variables (struct dataset *ds, 
+regression_custom_variables (struct lexer *lexer, struct dataset *ds, 
                             struct cmd_regression *cmd UNUSED,
                             void *aux UNUSED)
 {
   const struct dictionary *dict = dataset_dict (ds);
 
-  lex_match ('=');
+  lex_match (lexer, '=');
 
-  if ((token != T_ID || dict_lookup_var (dict, tokid) == NULL)
-      && token != T_ALL)
+  if ((lex_token (lexer) != T_ID || dict_lookup_var (dict, lex_tokid (lexer)) 
== NULL)
+      && lex_token (lexer) != T_ALL)
     return 2;
 
 
-  if (!parse_variables (dict, &v_variables, &n_variables, PV_NONE))
+  if (!parse_variables (lexer, dict, &v_variables, &n_variables, PV_NONE))
     {
       free (v_variables);
       return 0;

Index: language/stats/sort-cases.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/sort-cases.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- language/stats/sort-cases.c 26 Oct 2006 06:16:36 -0000      1.6
+++ language/stats/sort-cases.c 11 Nov 2006 23:10:00 -0000      1.7
@@ -40,24 +40,24 @@
 
 /* Performs the SORT CASES procedures. */
 int
-cmd_sort_cases (struct dataset *ds)
+cmd_sort_cases (struct lexer *lexer, struct dataset *ds)
 {
   struct sort_criteria *criteria;
   bool success = false;
 
-  lex_match (T_BY);
+  lex_match (lexer, T_BY);
 
-  criteria = sort_parse_criteria (dataset_dict (ds), NULL, NULL, NULL, NULL);
+  criteria = sort_parse_criteria (lexer, dataset_dict (ds), NULL, NULL, NULL, 
NULL);
   if (criteria == NULL)
     return CMD_CASCADING_FAILURE;
 
-  if (get_testing_mode () && lex_match ('/')) 
+  if (get_testing_mode () && lex_match (lexer, '/')) 
     {
-      if (!lex_force_match_id ("BUFFERS") || !lex_match ('=')
-          || !lex_force_int ())
+      if (!lex_force_match_id (lexer, "BUFFERS") || !lex_match (lexer, '=')
+          || !lex_force_int (lexer))
         goto done;
 
-      min_buffers = max_buffers = lex_integer ();
+      min_buffers = max_buffers = lex_integer (lexer);
       allow_internal_sort = false;
       if (max_buffers < 2) 
         {
@@ -65,7 +65,7 @@
           goto done;
         }
 
-      lex_get ();
+      lex_get (lexer);
     }
 
   success = sort_active_file_in_place (ds, criteria);
@@ -76,6 +76,6 @@
   allow_internal_sort = true;
   
   sort_destroy_criteria (criteria);
-  return success ? lex_end_of_command () : CMD_CASCADING_FAILURE;
+  return success ? lex_end_of_command (lexer) : CMD_CASCADING_FAILURE;
 }
 

Index: language/stats/sort-criteria.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/sort-criteria.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- language/stats/sort-criteria.c      27 Jun 2006 19:09:22 -0000      1.3
+++ language/stats/sort-criteria.c      11 Nov 2006 23:10:00 -0000      1.4
@@ -50,7 +50,7 @@
    
 */
 struct sort_criteria *
-sort_parse_criteria (const struct dictionary *dict,
+sort_parse_criteria (struct lexer *lexer, const struct dictionary *dict,
                      struct variable ***vars, size_t *var_cnt,
                      bool *saw_direction,
                     const int *terminators
@@ -82,23 +82,23 @@
       enum sort_direction direction;
 
       /* Variables. */
-      if (!parse_variables (dict, vars, var_cnt,
+      if (!parse_variables (lexer, dict, vars, var_cnt,
                            PV_NO_DUPLICATE | PV_APPEND | PV_NO_SCRATCH))
         goto error;
 
       /* Sort direction. */
-      if (lex_match ('('))
+      if (lex_match (lexer, '('))
        {
-         if (lex_match_id ("D") || lex_match_id ("DOWN"))
+         if (lex_match_id (lexer, "D") || lex_match_id (lexer, "DOWN"))
            direction = SRT_DESCEND;
-         else if (lex_match_id ("A") || lex_match_id ("UP"))
+         else if (lex_match_id (lexer, "A") || lex_match_id (lexer, "UP"))
             direction = SRT_ASCEND;
           else
            {
              msg (SE, _("`A' or `D' expected inside parentheses."));
               goto error;
            }
-         if (!lex_match (')'))
+         if (!lex_match (lexer, ')'))
            {
              msg (SE, _("`)' expected."));
               goto error;
@@ -120,7 +120,7 @@
           c->dir = direction;
         }
     }
-  while (token != '.' && token != '/' && !is_terminator(token, terminators));
+  while (lex_token (lexer) != '.' && lex_token (lexer) != '/' && 
!is_terminator(lex_token (lexer), terminators));
 
   free (local_vars);
   return criteria;

Index: language/stats/sort-criteria.h
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/sort-criteria.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- language/stats/sort-criteria.h      16 Apr 2006 01:05:15 -0000      1.2
+++ language/stats/sort-criteria.h      11 Nov 2006 23:10:00 -0000      1.3
@@ -26,8 +26,9 @@
 
 struct variable;
 struct dictionary;
+struct lexer ;
 
-struct sort_criteria *sort_parse_criteria (const struct dictionary *,
+struct sort_criteria *sort_parse_criteria (struct lexer *, const struct 
dictionary *,
                                            struct variable ***, size_t *,
                                            bool *saw_direction,
                                           const int *terminators

Index: language/stats/t-test.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/stats/t-test.q,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- language/stats/t-test.q     5 Nov 2006 00:35:44 -0000       1.14
+++ language/stats/t-test.q     11 Nov 2006 23:10:00 -0000      1.15
@@ -154,7 +154,7 @@
 
 static struct pair *pairs=0;
 
-static int parse_value (union value * v, int type) ;
+static int parse_value (struct lexer *lexer, union value * v, int type) ;
 
 /* Structures and Functions for the Statistics Summary Box */
 struct ssbox;
@@ -258,11 +258,11 @@
 
 
 int
-cmd_t_test (struct dataset *ds)
+cmd_t_test (struct lexer *lexer, struct dataset *ds)
 {
   bool ok;
   
-  if ( !parse_t_test (ds, &cmd, NULL) )
+  if ( !parse_t_test (lexer, ds, &cmd, NULL) )
     return CMD_FAILURE;
 
   if (! cmd.sbc_criteria)
@@ -362,16 +362,16 @@
 }
 
 static int
-tts_custom_groups (struct dataset *ds, struct cmd_t_test *cmd UNUSED, void 
*aux UNUSED)
+tts_custom_groups (struct lexer *lexer, struct dataset *ds, struct cmd_t_test 
*cmd UNUSED, void *aux UNUSED)
 {
   int n_group_values=0;
 
-  lex_match('=');
+  lex_match (lexer, '=');
 
-  indep_var = parse_variable (dataset_dict (ds));
+  indep_var = parse_variable (lexer, dataset_dict (ds));
   if (!indep_var)
     {
-      lex_error ("expecting variable name in GROUPS subcommand");
+      lex_error (lexer, "expecting variable name in GROUPS subcommand");
       return 0;
     }
 
@@ -382,7 +382,7 @@
       return 0;
     }
 
-  if (!lex_match ('('))
+  if (!lex_match (lexer, '('))
     {
       if (indep_var->type == NUMERIC)
        {
@@ -403,11 +403,11 @@
        }
     }
 
-  if (!parse_value (&gp.v.g_value[0], indep_var->type))
+  if (!parse_value (lexer, &gp.v.g_value[0], indep_var->type))
       return 0;
 
-  lex_match (',');
-  if (lex_match (')'))
+  lex_match (lexer, ',');
+  if (lex_match (lexer, ')'))
     {
       if (indep_var->type != NUMERIC)
        {
@@ -423,11 +423,11 @@
       return 1;
     }
 
-  if (!parse_value (&gp.v.g_value[1], indep_var->type))
+  if (!parse_value (lexer, &gp.v.g_value[1], indep_var->type))
     return 0;
 
   n_group_values = 2;
-  if (!lex_force_match (')'))
+  if (!lex_force_match (lexer, ')'))
     return 0;
 
   if ( n_group_values == 2 ) 
@@ -441,7 +441,7 @@
 
 
 static int
-tts_custom_pairs (struct dataset *ds, struct cmd_t_test *cmd UNUSED, void *aux 
UNUSED)
+tts_custom_pairs (struct lexer *lexer, struct dataset *ds, struct cmd_t_test 
*cmd UNUSED, void *aux UNUSED)
 {
   struct variable **vars;
   size_t n_vars;
@@ -451,10 +451,10 @@
   size_t n_after_WITH = SIZE_MAX;
   int paired ; /* Was the PAIRED keyword given ? */
 
-  lex_match('=');
+  lex_match (lexer, '=');
 
   n_vars=0;
-  if (!parse_variables (dataset_dict (ds), &vars, &n_vars,
+  if (!parse_variables (lexer, dataset_dict (ds), &vars, &n_vars,
                        PV_DUPLICATE | PV_NUMERIC | PV_NO_SCRATCH))
     {
       free (vars);
@@ -463,10 +463,10 @@
   assert (n_vars);
 
   n_before_WITH = 0;
-  if (lex_match (T_WITH))
+  if (lex_match (lexer, T_WITH))
     {
       n_before_WITH = n_vars;
-      if (!parse_variables (dataset_dict (ds), &vars, &n_vars,
+      if (!parse_variables (lexer, dataset_dict (ds), &vars, &n_vars,
                            PV_DUPLICATE | PV_APPEND
                            | PV_NUMERIC | PV_NO_SCRATCH))
        {
@@ -476,7 +476,7 @@
       n_after_WITH = n_vars - n_before_WITH;
     }
 
-  paired = (lex_match ('(') && lex_match_id ("PAIRED") && lex_match (')'));
+  paired = (lex_match (lexer, '(') && lex_match_id (lexer, "PAIRED") && 
lex_match (lexer, ')'));
 
   /* Determine the number of pairs needed */
   if (paired)
@@ -566,22 +566,22 @@
 /* Parses the current token (numeric or string, depending on type)
     value v and returns success. */
 static int
-parse_value (union value * v, int type )
+parse_value (struct lexer *lexer, union value * v, int type )
 {
   if (type == NUMERIC)
     {
-      if (!lex_force_num ())
+      if (!lex_force_num (lexer))
        return 0;
-      v->f = tokval;
+      v->f = lex_tokval (lexer);
     }
   else
     {
-      if (!lex_force_string ())
+      if (!lex_force_string (lexer))
        return 0;
-      strncpy (v->s, ds_cstr (&tokstr), ds_length (&tokstr));
+      strncpy (v->s, ds_cstr (lex_tokstr (lexer)), ds_length (lex_tokstr 
(lexer)));
     }
 
-  lex_get ();
+  lex_get (lexer);
 
   return 1;
 }

Index: language/tests/casefile-test.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/tests/casefile-test.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- language/tests/casefile-test.c      5 Nov 2006 00:35:44 -0000       1.8
+++ language/tests/casefile-test.c      11 Nov 2006 23:10:00 -0000      1.9
@@ -45,7 +45,7 @@
 static void fail_test (const char *message, ...);
 
 int
-cmd_debug_casefile (struct dataset *ds UNUSED) 
+cmd_debug_casefile (struct lexer *lexer, struct dataset *ds UNUSED) 
 {
   static const size_t sizes[] =
     {
@@ -57,15 +57,15 @@
   int pattern;
 
   size_max = sizeof sizes / sizeof *sizes;
-  if (lex_match_id ("SMALL")) 
+  if (lex_match_id (lexer, "SMALL")) 
     {
       size_max -= 4;
       case_max = 511; 
     }
   else
     case_max = 4095;
-  if (token != '.')
-    return lex_end_of_command ();
+  if (lex_token (lexer) != '.')
+    return lex_end_of_command (lexer);
     
   for (pattern = 0; pattern < 7; pattern++) 
     {

Index: language/tests/float-format.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/tests/float-format.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- language/tests/float-format.c       28 Oct 2006 04:01:55 -0000      1.1
+++ language/tests/float-format.c       11 Nov 2006 23:10:00 -0000      1.2
@@ -69,17 +69,17 @@
 /* Parses a floating-point format name into *FORMAT,
    and returns success. */
 static bool
-parse_float_format (enum float_format *format) 
+parse_float_format (struct lexer *lexer, enum float_format *format) 
 {
   size_t i;
 
   for (i = 0; i < format_cnt; i++)
-    if (lex_match_id (fp_formats[i].name)) 
+    if (lex_match_id (lexer, fp_formats[i].name)) 
       {
         *format = fp_formats[i].format;
         return true;
       }
-  lex_error ("expecting floating-point format identifier");
+  lex_error (lexer, "expecting floating-point format identifier");
   return false;
 }
 
@@ -101,25 +101,25 @@
    representation.  Also supports ordinary floating-point numbers
    written in decimal notation.  Returns success. */
 static bool
-parse_fp (struct fp *fp) 
+parse_fp (struct lexer *lexer, struct fp *fp) 
 {
-  if (lex_is_number ()) 
+  if (lex_is_number (lexer)) 
     {
-      double number = lex_number ();
+      double number = lex_number (lexer);
       fp->format = FLOAT_NATIVE_DOUBLE;
       memcpy (fp->data, &number, sizeof number);
-      lex_get ();
+      lex_get (lexer);
     }
-  else if (token == T_ID)
+  else if (lex_token (lexer) == T_ID)
     {
       size_t length;
       
-      if (!parse_float_format (&fp->format)
-          || !lex_force_match ('(')
-          || !lex_force_string ())
+      if (!parse_float_format (lexer, &fp->format)
+          || !lex_force_match (lexer, '(')
+          || !lex_force_string (lexer))
         return false;
 
-      length = ds_length (&tokstr);
+      length = ds_length (lex_tokstr (lexer));
       if (fp->format != FLOAT_HEX) 
         {
           if (length != float_get_size (fp->format)) 
@@ -129,7 +129,7 @@
               return false;
             }
           assert (length <= sizeof fp->data);
-          memcpy (fp->data, ds_data (&tokstr), length); 
+          memcpy (fp->data, ds_data (lex_tokstr (lexer)), length); 
         }
       else 
         {
@@ -138,16 +138,16 @@
               msg (SE, _("Hexadecimal floating constant too long."));
               return false;
             }
-          strncpy ((char *) fp->data, ds_cstr (&tokstr), sizeof fp->data);
+          strncpy ((char *) fp->data, ds_cstr (lex_tokstr (lexer)), sizeof 
fp->data);
         }
 
-      lex_get ();
-      if (!lex_force_match (')'))
+      lex_get (lexer);
+      if (!lex_force_match (lexer, ')'))
         return false;
     }
   else
     {
-      lex_error (NULL);
+      lex_error (lexer, NULL);
       return false;
     }
   return true;
@@ -235,7 +235,7 @@
 
 /* Executes the DEBUG FLOAT FORMAT command. */
 int
-cmd_debug_float_format (struct dataset *ds UNUSED) 
+cmd_debug_float_format (struct lexer *lexer, struct dataset *ds UNUSED) 
 {
   struct fp fp[16];
   size_t fp_cnt = 0;
@@ -249,30 +249,30 @@
           msg (SE, _("Too many values in single command."));
           return CMD_FAILURE;
         }
-      if (!parse_fp (&fp[fp_cnt++]))
+      if (!parse_fp (lexer, &fp[fp_cnt++]))
         return CMD_FAILURE;
 
-      if (token == '.' && fp_cnt > 1)
+      if (lex_token (lexer) == '.' && fp_cnt > 1)
         break;
-      else if (!lex_force_match ('='))
+      else if (!lex_force_match (lexer, '='))
         return CMD_FAILURE;
       
       if (fp_cnt == 1) 
         {
-          if (lex_match ('='))
+          if (lex_match (lexer, '='))
             bijective = true;
-          else if (lex_match (T_GT))
+          else if (lex_match (lexer, T_GT))
             bijective = false;
           else 
             {
-              lex_error (NULL);
+              lex_error (lexer, NULL);
               return CMD_FAILURE;
             }
         }
       else 
         {
-          if ((bijective && !lex_force_match ('='))
-              || (!bijective && !lex_force_match (T_GT)))
+          if ((bijective && !lex_force_match (lexer, '='))
+              || (!bijective && !lex_force_match (lexer, T_GT)))
             return CMD_FAILURE;
         }
     }

Index: language/tests/moments-test.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/tests/moments-test.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- language/tests/moments-test.c       26 Oct 2006 06:16:36 -0000      1.6
+++ language/tests/moments-test.c       11 Nov 2006 23:10:00 -0000      1.7
@@ -31,27 +31,27 @@
 #define _(msgid) gettext (msgid)
 
 static bool
-read_values (double **values, double **weights, size_t *cnt) 
+read_values (struct lexer *lexer, double **values, double **weights, size_t 
*cnt) 
 {
   size_t cap = 0;
 
   *values = NULL;
   *weights = NULL;
   *cnt = 0;
-  while (lex_is_number ())
+  while (lex_is_number (lexer))
     {
-      double value = tokval;
+      double value = lex_tokval (lexer);
       double weight = 1.;
-      lex_get ();
-      if (lex_match ('*'))
+      lex_get (lexer);
+      if (lex_match (lexer, '*'))
         {
-          if (!lex_is_number ())
+          if (!lex_is_number (lexer))
             {
-              lex_error (_("expecting weight value"));
+              lex_error (lexer, _("expecting weight value"));
               return false;
             }
-          weight = tokval;
-          lex_get ();
+          weight = lex_tokval (lexer);
+          lex_get (lexer);
         }
 
       if (*cnt >= cap) 
@@ -70,7 +70,7 @@
 }
 
 int
-cmd_debug_moments (struct dataset *ds UNUSED) 
+cmd_debug_moments (struct lexer *lexer, struct dataset *ds UNUSED) 
 {
   int retval = CMD_FAILURE;
   double *values = NULL;
@@ -80,22 +80,22 @@
   size_t cnt;
   size_t i;
 
-  if (lex_match_id ("ONEPASS"))
+  if (lex_match_id (lexer, "ONEPASS"))
     two_pass = 0;
-  if (token != '/') 
+  if (lex_token (lexer) != '/') 
     {
-      lex_force_match ('/');
+      lex_force_match (lexer, '/');
       goto done;
     }
-  fprintf (stderr, "%s => ", lex_rest_of_line (NULL));
-  lex_get ();
+  fprintf (stderr, "%s => ", lex_rest_of_line (lexer, NULL));
+  lex_get (lexer);
 
   if (two_pass) 
     {
       struct moments *m = NULL;
   
       m = moments_create (MOMENT_KURTOSIS);
-      if (!read_values (&values, &weights, &cnt)) 
+      if (!read_values (lexer, &values, &weights, &cnt)) 
         {
           moments_destroy (m);
           goto done; 
@@ -112,7 +112,7 @@
       struct moments1 *m = NULL;
   
       m = moments1_create (MOMENT_KURTOSIS);
-      if (!read_values (&values, &weights, &cnt)) 
+      if (!read_values (lexer, &values, &weights, &cnt)) 
         {
           moments1_destroy (m);
           goto done; 
@@ -136,7 +136,7 @@
     }
   fprintf (stderr, "\n");
 
-  retval = lex_end_of_command ();
+  retval = lex_end_of_command (lexer);
   
  done:
   free (values);

Index: language/tests/pool-test.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/tests/pool-test.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- language/tests/pool-test.c  26 Oct 2006 06:16:36 -0000      1.3
+++ language/tests/pool-test.c  11 Nov 2006 23:10:00 -0000      1.4
@@ -32,7 +32,7 @@
 /* Self-test routine.
    This is not exhaustive, but it can be useful. */
 int
-cmd_debug_pool (struct dataset *ds UNUSED)
+cmd_debug_pool (struct lexer *lexer UNUSED, struct dataset *ds UNUSED)
 {
   int seed = time (0) * 257 % 32768;
 

Index: language/utilities/date.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/utilities/date.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- language/utilities/date.c   26 Oct 2006 06:16:36 -0000      1.3
+++ language/utilities/date.c   11 Nov 2006 23:10:00 -0000      1.4
@@ -27,10 +27,10 @@
 
 /* Stub for USE command. */
 int
-cmd_use (struct dataset *ds UNUSED) 
+cmd_use (struct lexer *lexer, struct dataset *ds UNUSED) 
 {
-  if (lex_match (T_ALL))
-    return lex_end_of_command ();
+  if (lex_match (lexer, T_ALL))
+    return lex_end_of_command (lexer);
 
   msg (SW, _("Only USE ALL is currently implemented."));
   return CMD_FAILURE;

Index: language/utilities/echo.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/utilities/echo.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- language/utilities/echo.c   26 Oct 2006 06:16:36 -0000      1.4
+++ language/utilities/echo.c   11 Nov 2006 23:10:00 -0000      1.5
@@ -29,11 +29,11 @@
 
 /* Echos a string to the output stream */
 int
-cmd_echo (struct dataset *ds UNUSED)
+cmd_echo (struct lexer *lexer, struct dataset *ds UNUSED)
 {
   struct tab_table *tab;
 
-  if (token != T_STRING) 
+  if (lex_token (lexer) != T_STRING) 
     return CMD_FAILURE;
   
   tab = tab_create(1, 1, 0);
@@ -41,7 +41,7 @@
   tab_dim (tab, tab_natural_dimensions);
   tab_flags (tab, SOMF_NO_TITLE );
 
-  tab_text(tab, 0, 0, 0, ds_cstr (&tokstr));
+  tab_text(tab, 0, 0, 0, ds_cstr (lex_tokstr (lexer)));
 
   tab_submit(tab);
 

Index: language/utilities/include.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/utilities/include.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- language/utilities/include.c        26 Oct 2006 06:16:36 -0000      1.5
+++ language/utilities/include.c        11 Nov 2006 23:10:00 -0000      1.6
@@ -31,20 +31,20 @@
 #define _(msgid) gettext (msgid)
 
 int
-cmd_include (struct dataset *ds UNUSED)
+cmd_include (struct lexer *lexer, struct dataset *ds UNUSED)
 {
   /* Skip optional FILE=. */
-  if (lex_match_id ("FILE"))
-    lex_match ('=');
+  if (lex_match_id (lexer, "FILE"))
+    lex_match (lexer, '=');
 
   /* File name can be identifier or string. */
-  if (token != T_ID && token != T_STRING) 
+  if (lex_token (lexer) != T_ID && lex_token (lexer) != T_STRING) 
     {
-      lex_error (_("expecting file name")); 
+      lex_error (lexer, _("expecting file name")); 
       return CMD_CASCADING_FAILURE;
     }
-  getl_include_syntax_file (ds_cstr (&tokstr));
+  getl_include_syntax_file (ds_cstr (lex_tokstr (lexer)));
 
-  lex_get ();
-  return lex_end_of_command ();
+  lex_get (lexer);
+  return lex_end_of_command (lexer);
 }

Index: language/utilities/permissions.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/utilities/permissions.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- language/utilities/permissions.c    26 Oct 2006 06:16:36 -0000      1.6
+++ language/utilities/permissions.c    11 Nov 2006 23:10:00 -0000      1.7
@@ -42,32 +42,32 @@
 
 /* Parses the PERMISSIONS command. */
 int
-cmd_permissions (struct dataset *ds UNUSED)
+cmd_permissions (struct lexer *lexer, struct dataset *ds UNUSED)
 {
   char  *fn = 0;
 
-  lex_match ('/');
+  lex_match (lexer, '/');
 
-  if (lex_match_id ("FILE"))
-    lex_match ('=');
+  if (lex_match_id (lexer, "FILE"))
+    lex_match (lexer, '=');
 
-  fn = ds_xstrdup (&tokstr);
-  lex_force_match(T_STRING);
+  fn = ds_xstrdup (lex_tokstr (lexer));
+  lex_force_match (lexer, T_STRING);
 
 
-  lex_match ('/');
+  lex_match (lexer, '/');
   
-  if ( ! lex_match_id ("PERMISSIONS"))
+  if ( ! lex_match_id (lexer, "PERMISSIONS"))
     goto error;
 
-  lex_match('=');
+  lex_match (lexer, '=');
 
-  if ( lex_match_id("READONLY"))
+  if ( lex_match_id (lexer, "READONLY"))
     {
       if ( ! change_permissions(fn, PER_RO ) ) 
        goto error;
     }
-  else if ( lex_match_id("WRITEABLE"))
+  else if ( lex_match_id (lexer, "WRITEABLE"))
     {
       if ( ! change_permissions(fn, PER_RW ) ) 
        goto error;

Index: language/utilities/set.q
===================================================================
RCS file: /sources/pspp/pspp/src/language/utilities/set.q,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -b -r1.18 -r1.19
--- language/utilities/set.q    5 Nov 2006 05:20:53 -0000       1.18
+++ language/utilities/set.q    11 Nov 2006 23:10:01 -0000      1.19
@@ -127,12 +127,15 @@
 static enum float_format stc_to_float_format (int stc);
 
 int
-cmd_set (struct dataset *ds)
+cmd_set (struct lexer *lexer, struct dataset *ds)
 {
   struct cmd_set cmd;
 
-  if (!parse_set (ds, &cmd, NULL))
+  if (!parse_set (lexer, ds, &cmd, NULL))
+    {
+      free_set (&cmd);
     return CMD_FAILURE;
+    }
 
   if (cmd.sbc_cca)
     do_cc (cmd.s_cca, FMT_CCA);
@@ -212,6 +215,8 @@
   if (cmd.sbc_compression)
     msg (SW, _("Active file compression is not implemented."));
 
+  free_set (&cmd);
+
   return CMD_SUCCESS;
 }
 
@@ -352,20 +357,22 @@
    completely blank fields in numeric data imply.  X, Wnd: Syntax is
    SYSMIS or a numeric value. */
 static int
-stc_custom_blanks (struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, void 
*aux UNUSED)
+stc_custom_blanks (struct lexer *lexer, 
+                  struct dataset *ds UNUSED, 
+                  struct cmd_set *cmd UNUSED, void *aux UNUSED)
 {
-  lex_match ('=');
-  if ((token == T_ID && lex_id_match ("SYSMIS", tokid)))
+  lex_match (lexer, '=');
+  if ((lex_token (lexer) == T_ID && lex_id_match ("SYSMIS", lex_tokid 
(lexer))))
     {
-      lex_get ();
+      lex_get (lexer);
       set_blanks (SYSMIS);
     }
   else
     {
-      if (!lex_force_num ())
+      if (!lex_force_num (lexer))
        return 0;
-      set_blanks (lex_number ());
-      lex_get ();
+      set_blanks (lex_number (lexer));
+      lex_get (lexer);
     }
   return 1;
 }
@@ -373,15 +380,17 @@
 /* Parses the EPOCH subcommand, which controls the epoch used for
    parsing 2-digit years. */
 static int
-stc_custom_epoch (struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, void 
*aux UNUSED) 
+stc_custom_epoch (struct lexer *lexer, 
+                 struct dataset *ds UNUSED, 
+                 struct cmd_set *cmd UNUSED, void *aux UNUSED) 
 {
-  lex_match ('=');
-  if (lex_match_id ("AUTOMATIC"))
+  lex_match (lexer, '=');
+  if (lex_match_id (lexer, "AUTOMATIC"))
     set_epoch (-1);
-  else if (lex_is_integer ()) 
+  else if (lex_is_integer (lexer)) 
     {
-      int new_epoch = lex_integer ();
-      lex_get ();
+      int new_epoch = lex_integer (lexer);
+      lex_get (lexer);
       if (new_epoch < 1500) 
         {
           msg (SE, _("EPOCH must be 1500 or later."));
@@ -391,7 +400,7 @@
     }
   else 
     {
-      lex_error (_("expecting AUTOMATIC or year"));
+      lex_error (lexer, _("expecting AUTOMATIC or year"));
       return 0;
     }
 
@@ -399,24 +408,24 @@
 }
 
 static int
-stc_custom_length (struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, void 
*aux UNUSED)
+stc_custom_length (struct lexer *lexer, struct dataset *ds UNUSED, struct 
cmd_set *cmd UNUSED, void *aux UNUSED)
 {
   int page_length;
 
-  lex_match ('=');
-  if (lex_match_id ("NONE"))
+  lex_match (lexer, '=');
+  if (lex_match_id (lexer, "NONE"))
     page_length = -1;
   else
     {
-      if (!lex_force_int ())
+      if (!lex_force_int (lexer))
        return 0;
-      if (lex_integer () < 1)
+      if (lex_integer (lexer) < 1)
        {
          msg (SE, _("LENGTH must be at least 1."));
          return 0;
        }
-      page_length = lex_integer ();
-      lex_get ();
+      page_length = lex_integer (lexer);
+      lex_get (lexer);
     }
 
   if (page_length != -1) 
@@ -426,41 +435,41 @@
 }
 
 static int
-stc_custom_seed (struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, void 
*aux UNUSED)
+stc_custom_seed (struct lexer *lexer, struct dataset *ds UNUSED, struct 
cmd_set *cmd UNUSED, void *aux UNUSED)
 {
-  lex_match ('=');
-  if (lex_match_id ("RANDOM"))
+  lex_match (lexer, '=');
+  if (lex_match_id (lexer, "RANDOM"))
     set_rng (time (0));
   else
     {
-      if (!lex_force_num ())
+      if (!lex_force_num (lexer))
        return 0;
-      set_rng (lex_number ());
-      lex_get ();
+      set_rng (lex_number (lexer));
+      lex_get (lexer);
     }
 
   return 1;
 }
 
 static int
-stc_custom_width (struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, void 
*aux UNUSED)
+stc_custom_width (struct lexer *lexer, struct dataset *ds UNUSED, struct 
cmd_set *cmd UNUSED, void *aux UNUSED)
 {
-  lex_match ('=');
-  if (lex_match_id ("NARROW"))
+  lex_match (lexer, '=');
+  if (lex_match_id (lexer, "NARROW"))
     set_viewwidth (79);
-  else if (lex_match_id ("WIDE"))
+  else if (lex_match_id (lexer, "WIDE"))
     set_viewwidth (131);
   else
     {
-      if (!lex_force_int ())
+      if (!lex_force_int (lexer))
        return 0;
-      if (lex_integer () < 40)
+      if (lex_integer (lexer) < 40)
        {
          msg (SE, _("WIDTH must be at least 40."));
          return 0;
        }
-      set_viewwidth (lex_integer ());
-      lex_get ();
+      set_viewwidth (lex_integer (lexer));
+      lex_get (lexer);
     }
 
   return 1;
@@ -469,12 +478,12 @@
 /* Parses FORMAT subcommand, which consists of a numeric format
    specifier. */
 static int
-stc_custom_format (struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, void 
*aux UNUSED)
+stc_custom_format (struct lexer *lexer, struct dataset *ds UNUSED, struct 
cmd_set *cmd UNUSED, void *aux UNUSED)
 {
   struct fmt_spec fmt;
 
-  lex_match ('=');
-  if (!parse_format_specifier (&fmt))
+  lex_match (lexer, '=');
+  if (!parse_format_specifier (lexer, &fmt))
     return 0;
   if (fmt_is_string (fmt.type))
     {
@@ -490,16 +499,16 @@
 }
 
 static int
-stc_custom_journal (struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, 
void *aux UNUSED)
+stc_custom_journal (struct lexer *lexer, struct dataset *ds UNUSED, struct 
cmd_set *cmd UNUSED, void *aux UNUSED)
 {
-  lex_match ('=');
-  if (!lex_match_id ("ON") && !lex_match_id ("OFF")) 
+  lex_match (lexer, '=');
+  if (!lex_match_id (lexer, "ON") && !lex_match_id (lexer, "OFF")) 
     {
-      if (token == T_STRING)
-        lex_get ();
+      if (lex_token (lexer) == T_STRING)
+        lex_get (lexer);
       else
         {
-          lex_error (NULL);
+          lex_error (lexer, NULL);
           return 0;
         }
     }
@@ -507,14 +516,14 @@
 }
 
 static int
-stc_custom_listing (struct dataset *ds UNUSED, struct cmd_set *cmd UNUSED, 
void *aux UNUSED)
+stc_custom_listing (struct lexer *lexer, struct dataset *ds UNUSED, struct 
cmd_set *cmd UNUSED, void *aux UNUSED)
 {
   bool listing;
 
-  lex_match ('=');
-  if (lex_match_id ("ON") || lex_match_id ("YES"))
+  lex_match (lexer, '=');
+  if (lex_match_id (lexer, "ON") || lex_match_id (lexer, "YES"))
     listing = true;
-  else if (lex_match_id ("OFF") || lex_match_id ("NO"))
+  else if (lex_match_id (lexer, "OFF") || lex_match_id (lexer, "NO"))
     listing = false;
   else
     {
@@ -527,9 +536,9 @@
 }
 
 static int
-stc_custom_disk (struct dataset *ds, struct cmd_set *cmd UNUSED, void *aux)
+stc_custom_disk (struct lexer *lexer, struct dataset *ds, struct cmd_set *cmd 
UNUSED, void *aux)
 {
-  return stc_custom_listing (ds, cmd, aux);
+  return stc_custom_listing (lexer, ds, cmd, aux);
 }
 
 static void
@@ -828,9 +837,9 @@
 }
 
 int
-cmd_show (struct dataset *ds) 
+cmd_show (struct lexer *lexer, struct dataset *ds) 
 {
-  if (token == '.') 
+  if (lex_token (lexer) == '.') 
     {
       show_all (ds);
       return CMD_SUCCESS;
@@ -838,38 +847,38 @@
 
   do 
     {
-      if (lex_match (T_ALL))
+      if (lex_match (lexer, T_ALL))
         show_all (ds);
-      else if (lex_match_id ("CC")) 
+      else if (lex_match_id (lexer, "CC")) 
         show_all_cc ();
-      else if (lex_match_id ("WARRANTY"))
+      else if (lex_match_id (lexer, "WARRANTY"))
         show_warranty (ds);
-      else if (lex_match_id ("COPYING"))
+      else if (lex_match_id (lexer, "COPYING"))
         show_copying (ds);
-      else if (token == T_ID)
+      else if (lex_token (lexer) == T_ID)
         {
           int i;
 
           for (i = 0; i < sizeof show_table / sizeof *show_table; i++)
-            if (lex_match_id (show_table[i].name)) 
+            if (lex_match_id (lexer, show_table[i].name)) 
               {
                 show_table[i].function (ds);
                 goto found;
               }
-          lex_error (NULL);
+          lex_error (lexer, NULL);
           return CMD_FAILURE;
 
         found: ;
         }
       else 
         {
-          lex_error (NULL);
+          lex_error (lexer, NULL);
           return CMD_FAILURE;
         }
 
-      lex_match ('/');
+      lex_match (lexer, '/');
     }
-  while (token != '.');
+  while (lex_token (lexer) != '.');
 
   return CMD_SUCCESS;
 }

Index: language/utilities/title.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/utilities/title.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- language/utilities/title.c  26 Oct 2006 06:16:36 -0000      1.7
+++ language/utilities/title.c  11 Nov 2006 23:10:01 -0000      1.8
@@ -36,36 +36,36 @@
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
-static int get_title (const char *cmd, char **title);
+static int get_title (struct lexer *, const char *cmd, char **title);
 
 int
-cmd_title (struct dataset *ds UNUSED)
+cmd_title (struct lexer *lexer, struct dataset *ds UNUSED)
 {
-  return get_title ("TITLE", &outp_title);
+  return get_title (lexer, "TITLE", &outp_title);
 }
 
 int
-cmd_subtitle (struct dataset *ds UNUSED)
+cmd_subtitle (struct lexer *lexer, struct dataset *ds UNUSED)
 {
-  return get_title ("SUBTITLE", &outp_subtitle);
+  return get_title (lexer, "SUBTITLE", &outp_subtitle);
 }
 
 static int
-get_title (const char *cmd, char **title)
+get_title (struct lexer *lexer, const char *cmd, char **title)
 {
   int c;
 
-  c = lex_look_ahead ();
+  c = lex_look_ahead (lexer);
   if (c == '"' || c == '\'')
     {
-      lex_get ();
-      if (!lex_force_string ())
+      lex_get (lexer);
+      if (!lex_force_string (lexer))
        return CMD_FAILURE;
       if (*title)
        free (*title);
-      *title = ds_xstrdup (&tokstr);
-      lex_get ();
-      if (token != '.')
+      *title = ds_xstrdup (lex_tokstr (lexer));
+      lex_get (lexer);
+      if (lex_token (lexer) != '.')
        {
          msg (SE, _("%s: `.' expected after string."), cmd);
          return CMD_FAILURE;
@@ -77,28 +77,26 @@
 
       if (*title)
        free (*title);
-      *title = xstrdup (lex_rest_of_line (NULL));
-      lex_discard_line ();
+      *title = xstrdup (lex_rest_of_line (lexer, NULL));
+      lex_discard_line (lexer);
       for (cp = *title; *cp; cp++)
        *cp = toupper ((unsigned char) (*cp));
-      token = '.';
     }
   return CMD_SUCCESS;
 }
 
 /* Performs the FILE LABEL command. */
 int
-cmd_file_label (struct dataset *ds)
+cmd_file_label (struct lexer *lexer, struct dataset *ds)
 {
   const char *label;
 
-  label = lex_rest_of_line (NULL);
-  lex_discard_line ();
+  label = lex_rest_of_line (lexer, NULL);
+  lex_discard_line (lexer);
   while (isspace ((unsigned char) *label))
     label++;
 
   dict_set_label (dataset_dict (ds), label);
-  token = '.';
 
   return CMD_SUCCESS;
 }
@@ -128,7 +126,7 @@
 
 /* Performs the DOCUMENT command. */
 int
-cmd_document (struct dataset *ds)
+cmd_document (struct lexer *lexer, struct dataset *ds)
 {
   struct dictionary *dict = dataset_dict (ds);
   /* Add a few header lines for reference. */
@@ -148,8 +146,8 @@
       const char *orig_line;
       char *copy_line;
 
-      orig_line = lex_rest_of_line (&had_dot);
-      lex_discard_line ();
+      orig_line = lex_rest_of_line (lexer, &had_dot);
+      lex_discard_line (lexer);
       while (isspace ((unsigned char) *orig_line))
        orig_line++;
 
@@ -161,20 +159,19 @@
       add_document_line (dict, copy_line, 3);
       free (copy_line);
 
-      lex_get_line ();
+      lex_get_line (lexer);
       if (had_dot)
        break;
     }
 
-  token = '.';
   return CMD_SUCCESS;
 }
 
 /* Performs the DROP DOCUMENTS command. */
 int
-cmd_drop_documents (struct dataset *ds)
+cmd_drop_documents (struct lexer *lexer, struct dataset *ds)
 {
   dict_set_documents (dataset_dict (ds), NULL);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }

Index: language/xforms/compute.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/xforms/compute.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- language/xforms/compute.c   26 Oct 2006 06:16:36 -0000      1.9
+++ language/xforms/compute.c   11 Nov 2006 23:10:01 -0000      1.10
@@ -43,7 +43,7 @@
 
 /* Target of a COMPUTE or IF assignment, either a variable or a
    vector element. */
-static struct lvalue *lvalue_parse (struct dataset *);
+static struct lvalue *lvalue_parse (struct lexer *lexer, struct dataset *);
 static int lvalue_get_type (const struct lvalue *, const struct dictionary *);
 static bool lvalue_is_vector (const struct lvalue *);
 static void lvalue_finalize (struct lvalue *,
@@ -69,7 +69,10 @@
     struct expression *rvalue;  /* Rvalue expression. */
   };
 
-static struct expression *parse_rvalue (const struct lvalue *, struct dataset 
*);
+static struct expression *parse_rvalue (struct lexer *lexer, 
+                                       const struct lvalue *, 
+                                       struct dataset *);
+
 static struct compute_trns *compute_trns_create (void);
 static trns_proc_func *get_proc_func (const struct lvalue *, const struct 
dictionary *);
 static trns_free_func compute_trns_free;
@@ -77,7 +80,7 @@
 /* COMPUTE. */
 
 int
-cmd_compute (struct dataset *ds)
+cmd_compute (struct lexer *lexer, struct dataset *ds)
 {
   struct dictionary *dict = dataset_dict (ds);
   struct lvalue *lvalue = NULL;
@@ -85,13 +88,13 @@
 
   compute = compute_trns_create ();
 
-  lvalue = lvalue_parse (ds);
+  lvalue = lvalue_parse (lexer, ds);
   if (lvalue == NULL)
     goto fail;
 
-  if (!lex_force_match ('='))
+  if (!lex_force_match (lexer, '='))
     goto fail;
-  compute->rvalue = parse_rvalue (lvalue, ds);
+  compute->rvalue = parse_rvalue (lexer, lvalue, ds);
   if (compute->rvalue == NULL)
     goto fail;
 
@@ -100,7 +103,7 @@
 
   lvalue_finalize (lvalue, compute, dict);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 
  fail:
   lvalue_destroy (lvalue);
@@ -213,7 +216,7 @@
 /* IF. */
 
 int
-cmd_if (struct dataset *ds)
+cmd_if (struct lexer *lexer, struct dataset *ds)
 {
   struct dictionary *dict = dataset_dict (ds);
   struct compute_trns *compute = NULL;
@@ -222,19 +225,19 @@
   compute = compute_trns_create ();
 
   /* Test expression. */
-  compute->test = expr_parse (ds, EXPR_BOOLEAN);
+  compute->test = expr_parse (lexer, ds, EXPR_BOOLEAN);
   if (compute->test == NULL)
     goto fail;
 
   /* Lvalue variable. */
-  lvalue = lvalue_parse (ds);
+  lvalue = lvalue_parse (lexer, ds);
   if (lvalue == NULL)
     goto fail;
 
   /* Rvalue expression. */
-  if (!lex_force_match ('='))
+  if (!lex_force_match (lexer, '='))
     goto fail;
-  compute->rvalue = parse_rvalue (lvalue, ds);
+  compute->rvalue = parse_rvalue (lexer, lvalue, ds);
   if (compute->rvalue == NULL)
     goto fail;
 
@@ -243,7 +246,7 @@
 
   lvalue_finalize (lvalue, compute, dict);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 
  fail:
   lvalue_destroy (lvalue);
@@ -267,12 +270,13 @@
 /* Parses and returns an rvalue expression of the same type as
    LVALUE, or a null pointer on failure. */
 static struct expression *
-parse_rvalue (const struct lvalue *lvalue, struct dataset *ds)
+parse_rvalue (struct lexer *lexer, 
+             const struct lvalue *lvalue, struct dataset *ds)
 {
   const struct dictionary *dict = dataset_dict (ds);
   bool is_numeric = lvalue_get_type (lvalue, dict) == NUMERIC;
 
-  return expr_parse (ds, is_numeric ? EXPR_NUMBER : EXPR_STRING);
+  return expr_parse (lexer, ds, is_numeric ? EXPR_NUMBER : EXPR_STRING);
 }
 
 /* Returns a new struct compute_trns after initializing its fields. */
@@ -315,7 +319,7 @@
 /* Parses the target variable or vector element into a new
    `struct lvalue', which is returned. */
 static struct lvalue *
-lvalue_parse (struct dataset *ds) 
+lvalue_parse (struct lexer *lexer, struct dataset *ds) 
 {
   struct lvalue *lvalue;
 
@@ -324,34 +328,34 @@
   lvalue->vector = NULL;
   lvalue->element = NULL;
 
-  if (!lex_force_id ())
+  if (!lex_force_id (lexer))
     goto lossage;
   
-  if (lex_look_ahead () == '(')
+  if (lex_look_ahead (lexer) == '(')
     {
       /* Vector. */
-      lvalue->vector = dict_lookup_vector (dataset_dict (ds), tokid);
+      lvalue->vector = dict_lookup_vector (dataset_dict (ds), lex_tokid 
(lexer));
       if (lvalue->vector == NULL)
        {
-         msg (SE, _("There is no vector named %s."), tokid);
+         msg (SE, _("There is no vector named %s."), lex_tokid (lexer));
           goto lossage;
        }
 
       /* Vector element. */
-      lex_get ();
-      if (!lex_force_match ('('))
+      lex_get (lexer);
+      if (!lex_force_match (lexer, '('))
        goto lossage;
-      lvalue->element = expr_parse (ds, EXPR_NUMBER);
+      lvalue->element = expr_parse (lexer, ds, EXPR_NUMBER);
       if (lvalue->element == NULL)
         goto lossage;
-      if (!lex_force_match (')'))
+      if (!lex_force_match (lexer, ')'))
         goto lossage;
     }
   else
     {
       /* Variable name. */
-      str_copy_trunc (lvalue->var_name, sizeof lvalue->var_name, tokid);
-      lex_get ();
+      str_copy_trunc (lvalue->var_name, sizeof lvalue->var_name, lex_tokid 
(lexer));
+      lex_get (lexer);
     }
   return lvalue;
 

Index: language/xforms/count.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/xforms/count.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- language/xforms/count.c     26 Oct 2006 06:16:36 -0000      1.10
+++ language/xforms/count.c     11 Nov 2006 23:10:01 -0000      1.11
@@ -93,11 +93,11 @@
 static trns_proc_func count_trns_proc;
 static trns_free_func count_trns_free;
 
-static bool parse_numeric_criteria (struct pool *, struct criteria *);
-static bool parse_string_criteria (struct pool *, struct criteria *);
+static bool parse_numeric_criteria (struct lexer *, struct pool *, struct 
criteria *);
+static bool parse_string_criteria (struct lexer *, struct pool *, struct 
criteria *);
 
 int
-cmd_count (struct dataset *ds)
+cmd_count (struct lexer *lexer, struct dataset *ds)
 {
   struct dst_var *dv;           /* Destination var being parsed. */
   struct count_trns *trns;      /* Transformation. */
@@ -115,9 +115,9 @@
       dv->crit = NULL;
 
       /* Get destination variable, or at least its name. */
-      if (!lex_force_id ())
+      if (!lex_force_id (lexer))
        goto fail;
-      dv->var = dict_lookup_var (dataset_dict (ds), tokid);
+      dv->var = dict_lookup_var (dataset_dict (ds), lex_tokid (lexer));
       if (dv->var != NULL)
         {
           if (dv->var->type == ALPHA)
@@ -127,10 +127,10 @@
             }
         }
       else
-        dv->name = pool_strdup (trns->pool, tokid);
+        dv->name = pool_strdup (trns->pool, lex_tokid (lexer));
 
-      lex_get ();
-      if (!lex_force_match ('='))
+      lex_get (lexer);
+      if (!lex_force_match (lexer, '='))
        goto fail;
 
       crit = dv->crit = pool_alloc (trns->pool, sizeof *crit);
@@ -140,32 +140,32 @@
           
          crit->next = NULL;
          crit->vars = NULL;
-         if (!parse_variables (dataset_dict (ds), &crit->vars, &crit->var_cnt,
+         if (!parse_variables (lexer, dataset_dict (ds), &crit->vars, 
&crit->var_cnt,
                                 PV_DUPLICATE | PV_SAME_TYPE))
            goto fail;
           pool_register (trns->pool, free, crit->vars);
 
-         if (!lex_force_match ('('))
+         if (!lex_force_match (lexer, '('))
            goto fail;
 
           crit->value_cnt = 0;
           if (crit->vars[0]->type == NUMERIC)
-            ok = parse_numeric_criteria (trns->pool, crit);
+            ok = parse_numeric_criteria (lexer, trns->pool, crit);
           else
-            ok = parse_string_criteria (trns->pool, crit);
+            ok = parse_string_criteria (lexer, trns->pool, crit);
          if (!ok)
            goto fail;
 
-         if (token == '/' || token == '.')
+         if (lex_token (lexer) == '/' || lex_token (lexer) == '.')
            break;
 
          crit = crit->next = pool_alloc (trns->pool, sizeof *crit);
        }
 
-      if (token == '.')
+      if (lex_token (lexer) == '.')
        break;
 
-      if (!lex_force_match ('/'))
+      if (!lex_force_match (lexer, '/'))
        goto fail;
       dv = dv->next = pool_alloc (trns->pool, sizeof *dv);
     }
@@ -192,7 +192,7 @@
 
 /* Parses a set of numeric criterion values.  Returns success. */
 static bool
-parse_numeric_criteria (struct pool *pool, struct criteria *crit)
+parse_numeric_criteria (struct lexer *lexer, struct pool *pool, struct 
criteria *crit)
 {
   size_t allocated = 0;
 
@@ -203,11 +203,11 @@
     {
       double low, high;
       
-      if (lex_match_id ("SYSMIS"))
+      if (lex_match_id (lexer, "SYSMIS"))
         crit->count_system_missing = true;
-      else if (lex_match_id ("MISSING"))
+      else if (lex_match_id (lexer, "MISSING"))
        crit->count_user_missing = true;
-      else if (parse_num_range (&low, &high, NULL)) 
+      else if (parse_num_range (lexer, &low, &high, NULL)) 
         {
           struct num_value *cur;
 
@@ -223,8 +223,8 @@
       else
         return false;
 
-      lex_match (',');
-      if (lex_match (')'))
+      lex_match (lexer, ',');
+      if (lex_match (lexer, ')'))
        break;
     }
   return true;
@@ -232,7 +232,7 @@
 
 /* Parses a set of string criteria values.  Returns success. */
 static bool
-parse_string_criteria (struct pool *pool, struct criteria *crit)
+parse_string_criteria (struct lexer *lexer, struct pool *pool, struct criteria 
*crit)
 {
   int len = 0;
   size_t allocated = 0;
@@ -251,15 +251,15 @@
                                            &allocated,
                                            sizeof *crit->values.str);
 
-      if (!lex_force_string ())
+      if (!lex_force_string (lexer))
        return false;
       cur = &crit->values.str[crit->value_cnt++];
       *cur = pool_alloc (pool, len + 1);
-      str_copy_rpad (*cur, len + 1, ds_cstr (&tokstr));
-      lex_get ();
+      str_copy_rpad (*cur, len + 1, ds_cstr (lex_tokstr (lexer)));
+      lex_get (lexer);
 
-      lex_match (',');
-      if (lex_match (')'))
+      lex_match (lexer, ',');
+      if (lex_match (lexer, ')'))
        break;
     }
 

Index: language/xforms/fail.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/xforms/fail.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- language/xforms/fail.c      26 Oct 2006 06:16:36 -0000      1.3
+++ language/xforms/fail.c      11 Nov 2006 23:10:01 -0000      1.4
@@ -42,10 +42,10 @@
 
 
 int
-cmd_debug_xform_fail (struct dataset *ds)
+cmd_debug_xform_fail (struct lexer *lexer, struct dataset *ds)
 {
 
   add_transformation (ds, trns_fail, NULL, NULL);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }

Index: language/xforms/recode.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/xforms/recode.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- language/xforms/recode.c    26 Oct 2006 06:16:36 -0000      1.12
+++ language/xforms/recode.c    11 Nov 2006 23:10:01 -0000      1.13
@@ -108,21 +108,21 @@
     size_t map_cnt;             /* Number of mappings. */
   };
 
-static bool parse_src_vars (struct recode_trns *, const struct dictionary 
*dict);
-static bool parse_mappings (struct recode_trns *);
-static bool parse_dst_vars (struct recode_trns *, const struct dictionary 
*dict);
+static bool parse_src_vars (struct lexer *, struct recode_trns *, const struct 
dictionary *dict);
+static bool parse_mappings (struct lexer *, struct recode_trns *);
+static bool parse_dst_vars (struct lexer *, struct recode_trns *, const struct 
dictionary *dict);
 
 static void add_mapping (struct recode_trns *,
                          size_t *map_allocated, const struct map_in *);
 
-static bool parse_map_in (struct map_in *, struct pool *,
+static bool parse_map_in (struct lexer *lexer, struct map_in *, struct pool *,
                           enum var_type src_type, size_t max_src_width);
 static void set_map_in_generic (struct map_in *, enum map_in_type);
 static void set_map_in_num (struct map_in *, enum map_in_type, double, double);
 static void set_map_in_str (struct map_in *, struct pool *,
                             const struct string *, size_t width);
 
-static bool parse_map_out (struct pool *, struct map_out *);
+static bool parse_map_out (struct lexer *lexer, struct pool *, struct map_out 
*);
 static void set_map_out_num (struct map_out *, double);
 static void set_map_out_str (struct map_out *, struct pool *,
                              const struct string *);
@@ -137,7 +137,7 @@
 
 /* Parses the RECODE transformation. */
 int
-cmd_recode (struct dataset *ds)
+cmd_recode (struct lexer *lexer, struct dataset *ds)
 {
   do
     {
@@ -147,9 +147,9 @@
       /* Parse source variable names,
          then input to output mappings,
          then destintation variable names. */
-      if (!parse_src_vars (trns, dataset_dict (ds) )
-          || !parse_mappings (trns)
-          || !parse_dst_vars (trns, dataset_dict (ds)))
+      if (!parse_src_vars (lexer, trns, dataset_dict (ds) )
+          || !parse_mappings (lexer, trns)
+          || !parse_dst_vars (lexer, trns, dataset_dict (ds)))
         {
           recode_trns_free (trns);
           return CMD_FAILURE;
@@ -170,18 +170,19 @@
       add_transformation (ds, 
                          recode_trns_proc, recode_trns_free, trns);
     }
-  while (lex_match ('/'));
+  while (lex_match (lexer, '/'));
   
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Parses a set of variables to recode into TRNS->src_vars and
    TRNS->var_cnt.  Sets TRNS->src_type.  Returns true if
    successful, false on parse error. */
 static bool
-parse_src_vars (struct recode_trns *trns, const struct dictionary *dict) 
+parse_src_vars (struct lexer *lexer, 
+               struct recode_trns *trns, const struct dictionary *dict) 
 {
-  if (!parse_variables (dict, &trns->src_vars, &trns->var_cnt,
+  if (!parse_variables (lexer, dict, &trns->src_vars, &trns->var_cnt,
                         PV_SAME_TYPE))
     return false;
   pool_register (trns->pool, free, trns->src_vars);
@@ -193,7 +194,7 @@
    into TRNS->mappings and TRNS->map_cnt.  Sets TRNS->dst_type.
    Returns true if successful, false on parse error. */
 static bool
-parse_mappings (struct recode_trns *trns) 
+parse_mappings (struct lexer *lexer, struct recode_trns *trns) 
 {
   size_t max_src_width;
   size_t map_allocated;
@@ -214,13 +215,13 @@
   trns->map_cnt = 0;
   map_allocated = 0;
   have_dst_type = false;
-  if (!lex_force_match ('('))
+  if (!lex_force_match (lexer, '('))
     return false;
   do
     {
       enum var_type dst_type;
 
-      if (!lex_match_id ("CONVERT")) 
+      if (!lex_match_id (lexer, "CONVERT")) 
         {
           struct map_out out;
           size_t first_map_idx;
@@ -232,15 +233,15 @@
           do
             {
               struct map_in in;
-              if (!parse_map_in (&in, trns->pool,
+              if (!parse_map_in (lexer, &in, trns->pool,
                                  trns->src_type, max_src_width))
                 return false;
               add_mapping (trns, &map_allocated, &in);
-              lex_match (',');
+              lex_match (lexer, ',');
             }
-          while (!lex_match ('='));
+          while (!lex_match (lexer, '='));
 
-          if (!parse_map_out (trns->pool, &out))
+          if (!parse_map_out (lexer, trns->pool, &out))
             return false;
           dst_type = out.width == 0 ? NUMERIC : ALPHA;
           if (have_dst_type && dst_type != trns->dst_type)
@@ -273,10 +274,10 @@
       trns->dst_type = dst_type;
       have_dst_type = true;
 
-      if (!lex_force_match (')'))
+      if (!lex_force_match (lexer, ')'))
         return false; 
     }
-  while (lex_match ('('));
+  while (lex_match (lexer, '('));
 
   return true;
 }
@@ -287,31 +288,31 @@
    be provided in MAX_SRC_WIDTH.  Returns true if successful,
    false on parse error. */
 static bool
-parse_map_in (struct map_in *in, struct pool *pool,
+parse_map_in (struct lexer *lexer, struct map_in *in, struct pool *pool,
               enum var_type src_type, size_t max_src_width)
 {
-  if (lex_match_id ("ELSE"))
+  if (lex_match_id (lexer, "ELSE"))
     set_map_in_generic (in, MAP_ELSE);
   else if (src_type == NUMERIC)
     {
-      if (lex_match_id ("MISSING"))
+      if (lex_match_id (lexer, "MISSING"))
         set_map_in_generic (in, MAP_MISSING);
-      else if (lex_match_id ("SYSMIS"))
+      else if (lex_match_id (lexer, "SYSMIS"))
         set_map_in_generic (in, MAP_SYSMIS);
       else 
         {
           double x, y;
-          if (!parse_num_range (&x, &y, NULL))
+          if (!parse_num_range (lexer, &x, &y, NULL))
             return false;
           set_map_in_num (in, x == y ? MAP_SINGLE : MAP_RANGE, x, y);
         }
     }
   else
     {
-      if (!lex_force_string ())
+      if (!lex_force_string (lexer))
         return false;
-      set_map_in_str (in, pool, &tokstr, max_src_width);
-      lex_get ();
+      set_map_in_str (in, pool, lex_tokstr (lexer), max_src_width);
+      lex_get (lexer);
     }
 
   return true;
@@ -365,25 +366,25 @@
 /* Parses a mapping output value into OUT, allocating memory from
    POOL.  Returns true if successful, false on parse error. */
 static bool
-parse_map_out (struct pool *pool, struct map_out *out)
+parse_map_out (struct lexer *lexer, struct pool *pool, struct map_out *out)
 {
-  if (lex_is_number ())
+  if (lex_is_number (lexer))
     {
-      set_map_out_num (out, lex_number ());
-      lex_get ();
+      set_map_out_num (out, lex_number (lexer));
+      lex_get (lexer);
     }
-  else if (lex_match_id ("SYSMIS"))
+  else if (lex_match_id (lexer, "SYSMIS"))
     set_map_out_num (out, SYSMIS);
-  else if (token == T_STRING)
+  else if (lex_token (lexer) == T_STRING)
     {
-      set_map_out_str (out, pool, &tokstr);
-      lex_get ();
+      set_map_out_str (out, pool, lex_tokstr (lexer));
+      lex_get (lexer);
     }
-  else if (lex_match_id ("COPY"))
+  else if (lex_match_id (lexer, "COPY"))
     out->copy_input = true;
   else 
     {
-      lex_error (_("expecting output value"));
+      lex_error (lexer, _("expecting output value"));
       return false;
     }
   return true; 
@@ -415,16 +416,17 @@
 /* Parses a set of target variables into TRNS->dst_vars and
    TRNS->dst_names. */
 static bool
-parse_dst_vars (struct recode_trns *trns, const struct dictionary *dict) 
+parse_dst_vars (struct lexer *lexer, struct recode_trns *trns, 
+               const struct dictionary *dict) 
 {
   size_t i;
   
-  if (lex_match_id ("INTO"))
+  if (lex_match_id (lexer, "INTO"))
     {
       size_t name_cnt;
       size_t i;
 
-      if (!parse_mixed_vars_pool (dict, trns->pool, 
+      if (!parse_mixed_vars_pool (lexer, dict, trns->pool, 
                                  &trns->dst_names, &name_cnt,
                                   PV_NONE))
         return false;

Index: language/xforms/sample.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/xforms/sample.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- language/xforms/sample.c    26 Oct 2006 06:16:36 -0000      1.9
+++ language/xforms/sample.c    11 Nov 2006 23:10:01 -0000      1.10
@@ -57,7 +57,7 @@
 static trns_free_func sample_trns_free;
 
 int
-cmd_sample (struct dataset *ds)
+cmd_sample (struct lexer *lexer, struct dataset *ds)
 {
   struct sample_trns *trns;
 
@@ -65,34 +65,34 @@
   int a, b;
   unsigned frac;
 
-  if (!lex_force_num ())
+  if (!lex_force_num (lexer))
     return CMD_FAILURE;
-  if (!lex_is_integer ())
+  if (!lex_is_integer (lexer))
     {
       unsigned long min = gsl_rng_min (get_rng ());
       unsigned long max = gsl_rng_max (get_rng ());
 
       type = TYPE_FRACTION;
-      if (tokval <= 0 || tokval >= 1)
+      if (lex_tokval (lexer) <= 0 || lex_tokval (lexer) >= 1)
        {
          msg (SE, _("The sampling factor must be between 0 and 1 "
                     "exclusive."));
          return CMD_FAILURE;
        }
          
-      frac = tokval * (max - min) + min;
+      frac = lex_tokval (lexer) * (max - min) + min;
       a = b = 0;
     }
   else
     {
       type = TYPE_A_FROM_B;
-      a = lex_integer ();
-      lex_get ();
-      if (!lex_force_match_id ("FROM"))
+      a = lex_integer (lexer);
+      lex_get (lexer);
+      if (!lex_force_match_id (lexer, "FROM"))
        return CMD_FAILURE;
-      if (!lex_force_int ())
+      if (!lex_force_int (lexer))
        return CMD_FAILURE;
-      b = lex_integer ();
+      b = lex_integer (lexer);
       if (a >= b)
        {
          msg (SE, _("Cannot sample %d observations from a population of "
@@ -103,7 +103,7 @@
       
       frac = 0;
     }
-  lex_get ();
+  lex_get (lexer);
 
   trns = xmalloc (sizeof *trns);
   trns->type = type;
@@ -113,7 +113,7 @@
   trns->frac = frac;
   add_transformation (ds, sample_trns_proc, sample_trns_free, trns);
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }
 
 /* Executes a SAMPLE transformation. */

Index: language/xforms/select-if.c
===================================================================
RCS file: /sources/pspp/pspp/src/language/xforms/select-if.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- language/xforms/select-if.c 26 Oct 2006 06:16:36 -0000      1.11
+++ language/xforms/select-if.c 11 Nov 2006 23:10:01 -0000      1.12
@@ -47,19 +47,19 @@
 
 /* Parses the SELECT IF transformation. */
 int
-cmd_select_if (struct dataset *ds)
+cmd_select_if (struct lexer *lexer, struct dataset *ds)
 {
   struct expression *e;
   struct select_if_trns *t;
 
-  e = expr_parse (ds, EXPR_BOOLEAN);
+  e = expr_parse (lexer, ds, EXPR_BOOLEAN);
   if (!e)
     return CMD_CASCADING_FAILURE;
 
-  if (token != '.')
+  if (lex_token (lexer) != '.')
     {
       expr_free (e);
-      lex_error (_("expecting end of command"));
+      lex_error (lexer, _("expecting end of command"));
       return CMD_CASCADING_FAILURE;
     }
 
@@ -92,12 +92,12 @@
 
 /* Parses the FILTER command. */
 int
-cmd_filter (struct dataset *ds)
+cmd_filter (struct lexer *lexer, struct dataset *ds)
 {
   struct dictionary *dict = dataset_dict (ds);
-  if (lex_match_id ("OFF"))
+  if (lex_match_id (lexer, "OFF"))
     dict_set_filter (dataset_dict (ds), NULL);
-  else if (token == '.') 
+  else if (lex_token (lexer) == '.') 
     {
       msg (SW, _("Syntax error expecting OFF or BY.  "
                  "Turning off case filtering."));
@@ -107,8 +107,8 @@
     {
       struct variable *v;
 
-      lex_match (T_BY);
-      v = parse_variable (dict);
+      lex_match (lexer, T_BY);
+      v = parse_variable (lexer, dict);
       if (!v)
        return CMD_FAILURE;
 
@@ -127,5 +127,5 @@
       dict_set_filter (dict, v);
     }
 
-  return lex_end_of_command ();
+  return lex_end_of_command (lexer);
 }

Index: ui/terminal/main.c
===================================================================
RCS file: /sources/pspp/pspp/src/ui/terminal/main.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- ui/terminal/main.c  7 Nov 2006 12:59:59 -0000       1.19
+++ ui/terminal/main.c  11 Nov 2006 23:10:01 -0000      1.20
@@ -72,7 +72,7 @@
 void interrupt_handler(int sig);
 static struct dataset * the_dataset = NULL;
 
-
+static struct lexer *the_lexer;
 
 /* Program entry point. */
 int
@@ -102,11 +102,11 @@
     {
       msg_ui_init ();
       outp_read_devices ();
-      lex_init (do_read_line);
+      the_lexer = lex_create (do_read_line);
 
       for (;;)
         {
-          int result = cmd_parse (the_dataset, 
+          int result = cmd_parse (the_lexer, the_dataset, 
                                  proc_has_source (the_dataset)
                                   ? CMD_STATE_DATA : CMD_STATE_INITIAL);
           if (result == CMD_EOF || result == CMD_FINISH)
@@ -188,7 +188,7 @@
       random_done ();
       settings_done ();
       fh_done ();
-      lex_done ();
+      lex_destroy (the_lexer);
       getl_uninitialize ();
       readln_uninitialize ();
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]