Add support for reading SPSS/PC+ system files.
[pspp] / src / language / data-io / get.c
index 0e542ef0d28dc50b08ea97bd780424da5aede1d1..9a788a01e3a67922ddad51177cadef6cefbbb418 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2007, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2007, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -66,12 +66,15 @@ cmd_import (struct lexer *lexer, struct dataset *ds)
 
 /* Parses a GET or IMPORT command. */
 static int
-parse_read_command (struct lexer *lexer, struct dataset *ds, enum reader_command type)
+parse_read_command (struct lexer *lexer, struct dataset *ds,
+                    enum reader_command command)
 {
   struct casereader *reader = NULL;
   struct file_handle *fh = NULL;
   struct dictionary *dict = NULL;
   struct case_map *map = NULL;
+  struct case_map_stage *stage = NULL;
+  char *encoding = NULL;
 
   for (;;)
     {
@@ -86,17 +89,26 @@ parse_read_command (struct lexer *lexer, struct dataset *ds, enum reader_command
          if (fh == NULL)
             goto error;
        }
-      else if (type == IMPORT_CMD && lex_match_id (lexer, "TYPE"))
+      else if (command == GET_CMD && lex_match_id (lexer, "ENCODING"))
+        {
+         lex_match (lexer, T_EQUALS);
+
+          if (!lex_force_string (lexer))
+            goto error;
+
+          free (encoding);
+          encoding = ss_xstrdup (lex_tokss (lexer));
+
+          lex_get (lexer);
+        }
+      else if (command == IMPORT_CMD && lex_match_id (lexer, "TYPE"))
        {
          lex_match (lexer, T_EQUALS);
 
-         if (lex_match_id (lexer, "COMM"))
-           type = PFM_COMM;
-         else if (lex_match_id (lexer, "TAPE"))
-           type = PFM_TAPE;
-         else
+         if (!lex_match_id (lexer, "COMM")
+              && !lex_match_id (lexer, "TAPE"))
            {
-             lex_error (lexer, _("expecting %s or %s"), "COMM", "TAPE");
+             lex_error_expecting (lexer, "COMM", "TAPE", NULL_SENTINEL);
               goto error;
            }
        }
@@ -106,15 +118,15 @@ parse_read_command (struct lexer *lexer, struct dataset *ds, enum reader_command
 
   if (fh == NULL)
     {
-      lex_sbc_missing (lexer, "FILE");
+      lex_sbc_missing ("FILE");
       goto error;
     }
 
-  reader = any_reader_open (fh, &dict);
+  reader = any_reader_open_and_decode (fh, encoding, &dict, NULL);
   if (reader == NULL)
     goto error;
 
-  case_map_prepare_dict (dict);
+  stage = case_map_stage_create (dict);
 
   while (lex_token (lexer) != T_ENDCMD)
     {
@@ -124,7 +136,8 @@ parse_read_command (struct lexer *lexer, struct dataset *ds, enum reader_command
     }
   dict_compact_values (dict);
 
-  map = case_map_from_dict (dict);
+  map = case_map_stage_get_case_map (stage);
+  case_map_stage_destroy (stage);
   if (map != NULL)
     reader = case_map_create_input_translator (map, reader);
 
@@ -132,12 +145,15 @@ parse_read_command (struct lexer *lexer, struct dataset *ds, enum reader_command
   dataset_set_source (ds, reader);
 
   fh_unref (fh);
+  free (encoding);
   return CMD_SUCCESS;
 
  error:
+  case_map_stage_destroy (stage);
   fh_unref (fh);
   casereader_destroy (reader);
   if (dict != NULL)
     dict_destroy (dict);
+  free (encoding);
   return CMD_CASCADING_FAILURE;
 }