995be8e7ce896212cd9775af4789c1aa1441360a
[pspp] / src / language / data-io / get-data.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012,
3                  2013, 2015, 2016 Free Software Foundation, Inc.
4
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation, either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
17
18 #include <config.h>
19
20 #include <stdlib.h>
21
22 #include <string.h>
23
24 #include "data/dataset.h"
25 #include "data/dictionary.h"
26 #include "data/format.h"
27 #include "data/gnumeric-reader.h"
28 #include "data/ods-reader.h"
29 #include "data/spreadsheet-reader.h"
30 #include "data/psql-reader.h"
31 #include "data/settings.h"
32 #include "language/command.h"
33 #include "language/data-io/data-parser.h"
34 #include "language/data-io/data-reader.h"
35 #include "language/data-io/file-handle.h"
36 #include "language/data-io/placement-parser.h"
37 #include "language/lexer/format-parser.h"
38 #include "language/lexer/lexer.h"
39 #include "libpspp/cast.h"
40 #include "libpspp/i18n.h"
41 #include "libpspp/message.h"
42
43 #include "gl/xalloc.h"
44
45 #include "gettext.h"
46 #define _(msgid) gettext (msgid)
47 #define N_(msgid) (msgid)
48
49
50 #ifdef ODF_READ_SUPPORT
51 static const bool odf_read_support = true;
52 #else
53 static const bool odf_read_support = false;
54 struct spreadsheet *ods_probe (const char *filename, bool report_errors){}
55 struct casereader * ods_make_reader (struct spreadsheet *spreadsheet,
56                                           const struct spreadsheet_read_options *opts){}
57 void ods_unref (struct spreadsheet *r){}
58 #endif
59
60 #ifdef GNM_READ_SUPPORT
61 static const bool gnm_read_support = true;
62 #else
63 static const bool gnm_read_support = false;
64 struct spreadsheet *gnumeric_probe (const char *filename, bool report_errors){}
65 struct casereader * gnumeric_make_reader (struct spreadsheet *spreadsheet,
66                                           const struct spreadsheet_read_options *opts){}
67 void gnumeric_unref (struct spreadsheet *r){}
68
69 #endif
70
71 static bool parse_spreadsheet (struct lexer *lexer, char **filename,
72                                struct spreadsheet_read_options *opts);
73
74 static void destroy_spreadsheet_read_info (struct spreadsheet_read_options *);
75
76 static int parse_get_txt (struct lexer *lexer, struct dataset *);
77 static int parse_get_psql (struct lexer *lexer, struct dataset *);
78
79 int
80 cmd_get_data (struct lexer *lexer, struct dataset *ds)
81 {
82   char *tok = NULL;
83   struct spreadsheet_read_options opts;
84   
85   opts.sheet_name = NULL;
86   opts.sheet_index = -1;
87   opts.cell_range = NULL;
88   opts.read_names = false;
89   opts.asw = -1;
90
91   lex_force_match (lexer, T_SLASH);
92
93   if (!lex_force_match_id (lexer, "TYPE"))
94     goto error;
95
96   lex_force_match (lexer, T_EQUALS);
97
98   tok = strdup (lex_tokcstr (lexer));
99   if (lex_match_id (lexer, "TXT"))
100     {
101       free (tok);
102       return parse_get_txt (lexer, ds);
103     }
104   else if (lex_match_id (lexer, "PSQL"))
105     {
106       free (tok);
107       return parse_get_psql (lexer, ds);
108     }
109   else if (lex_match_id (lexer, "GNM") || 
110       lex_match_id (lexer, "ODS"))
111     {
112       char *filename = NULL;
113       if (!parse_spreadsheet (lexer, &filename, &opts))
114         goto error;
115
116       struct spreadsheet *spreadsheet = NULL;
117       if ( gnm_read_support && 0 == strncasecmp (tok, "GNM", 3))
118         spreadsheet = gnumeric_probe (filename, true);
119       else if ( odf_read_support && 0 == strncasecmp (tok, "ODS", 3))
120         spreadsheet = ods_probe (filename, true);
121
122       free (filename);
123       if (spreadsheet == NULL)
124         goto error;
125
126       struct casereader *reader = spreadsheet_make_reader (spreadsheet, &opts);
127       if (reader)
128         {
129           dataset_set_dict (ds, dict_clone (spreadsheet->dict));
130           dataset_set_source (ds, reader);
131           free (tok);
132           destroy_spreadsheet_read_info (&opts);
133           spreadsheet_unref (spreadsheet);
134           return CMD_SUCCESS;
135         }
136       spreadsheet_unref (spreadsheet);
137     }
138   else
139     msg (SE, _("Unsupported TYPE %s."), tok);
140
141
142  error:
143   destroy_spreadsheet_read_info (&opts);
144   free (tok);
145   return CMD_FAILURE;
146 }
147
148 static int
149 parse_get_psql (struct lexer *lexer, struct dataset *ds)
150 {
151   struct psql_read_info psql;
152   psql.allow_clear = false;
153   psql.conninfo = NULL;
154   psql.str_width = -1;
155   psql.bsize = -1;
156   ds_init_empty (&psql.sql);
157
158   lex_force_match (lexer, T_SLASH);
159
160   if (!lex_force_match_id (lexer, "CONNECT"))
161     goto error;
162
163   lex_force_match (lexer, T_EQUALS);
164
165   if (!lex_force_string (lexer))
166     goto error;
167
168   psql.conninfo = ss_xstrdup (lex_tokss (lexer));
169
170   lex_get (lexer);
171
172   while (lex_match (lexer, T_SLASH) )
173     {
174       if ( lex_match_id (lexer, "ASSUMEDSTRWIDTH"))
175         {
176           lex_match (lexer, T_EQUALS);
177           psql.str_width = lex_integer (lexer);
178           lex_get (lexer);
179         }
180       else if ( lex_match_id (lexer, "BSIZE"))
181         {
182           lex_match (lexer, T_EQUALS);
183           psql.bsize = lex_integer (lexer);
184           lex_get (lexer);
185         }
186       else if ( lex_match_id (lexer, "UNENCRYPTED"))
187         {
188           psql.allow_clear = true;
189         }
190       else if (lex_match_id (lexer, "SQL"))
191         {
192           lex_match (lexer, T_EQUALS);
193           if ( ! lex_force_string (lexer) )
194             goto error;
195
196           ds_put_substring (&psql.sql, lex_tokss (lexer));
197           lex_get (lexer);
198         }
199      }
200   {
201     struct dictionary *dict = NULL;
202     struct casereader *reader = psql_open_reader (&psql, &dict);
203
204     if ( reader )
205       {
206         dataset_set_dict (ds, dict);
207         dataset_set_source (ds, reader);
208       }
209   }
210
211   ds_destroy (&psql.sql);
212   free (psql.conninfo);
213
214   return CMD_SUCCESS;
215
216  error:
217
218   ds_destroy (&psql.sql);
219   free (psql.conninfo);
220
221   return CMD_FAILURE;
222 }
223
224 static bool
225 parse_spreadsheet (struct lexer *lexer, char **filename, 
226                    struct spreadsheet_read_options *opts)
227 {
228   opts->sheet_index = 1;
229   opts->sheet_name = NULL;
230   opts->cell_range = NULL;
231   opts->read_names = true;
232   opts->asw = -1;
233
234   lex_force_match (lexer, T_SLASH);
235
236   if (!lex_force_match_id (lexer, "FILE"))
237     goto error;
238
239   lex_force_match (lexer, T_EQUALS);
240
241   if (!lex_force_string (lexer))
242     goto error;
243
244   *filename  = utf8_to_filename (lex_tokcstr (lexer));
245
246   lex_get (lexer);
247
248   while (lex_match (lexer, T_SLASH) )
249     {
250       if ( lex_match_id (lexer, "ASSUMEDSTRWIDTH"))
251         {
252           lex_match (lexer, T_EQUALS);
253           opts->asw = lex_integer (lexer);
254           lex_get (lexer);
255         }
256       else if (lex_match_id (lexer, "SHEET"))
257         {
258           lex_match (lexer, T_EQUALS);
259           if (lex_match_id (lexer, "NAME"))
260             {
261               if ( ! lex_force_string (lexer) )
262                 goto error;
263
264               opts->sheet_name = ss_xstrdup (lex_tokss (lexer));
265               opts->sheet_index = -1;
266
267               lex_get (lexer);
268             }
269           else if (lex_match_id (lexer, "INDEX"))
270             {
271               opts->sheet_index = lex_integer (lexer);
272               if (opts->sheet_index <= 0)
273                 {
274                   msg (SE, _("The sheet index must be greater than or equal to 1"));
275                   goto error;
276                 }
277               lex_get (lexer);
278             }
279           else
280             {
281               msg (SE, _("%s must be followed by either \"%s\" or \"%s\"."),
282                    "/SHEET", "NAME", "INDEX");
283               goto error;
284             }
285         }
286       else if (lex_match_id (lexer, "CELLRANGE"))
287         {
288           lex_match (lexer, T_EQUALS);
289
290           if (lex_match_id (lexer, "FULL"))
291             {
292               opts->cell_range = NULL;
293             }
294           else if (lex_match_id (lexer, "RANGE"))
295             {
296               if ( ! lex_force_string (lexer) )
297                 goto error;
298
299               opts->cell_range = ss_xstrdup (lex_tokss (lexer));
300               lex_get (lexer);
301             }
302           else
303             {
304               msg (SE, _("%s must be followed by either \"%s\" or \"%s\"."),
305                    "/CELLRANGE", "FULL", "RANGE");
306               goto error;
307             }
308         }
309       else if (lex_match_id (lexer, "READNAMES"))
310         {
311           lex_match (lexer, T_EQUALS);
312
313           if ( lex_match_id (lexer, "ON"))
314             {
315               opts->read_names = true;
316             }
317           else if (lex_match_id (lexer, "OFF"))
318             {
319               opts->read_names = false;
320             }
321           else
322             {
323               msg (SE, _("%s must be followed by either \"%s\" or \"%s\"."),
324                    "/READNAMES", "ON", "OFF");
325               goto error;
326             }
327         }
328       else
329         {
330           lex_error (lexer, NULL);
331           goto error;
332         }
333     }
334
335   return true;
336
337  error:
338   return false;
339 }
340
341
342 static bool
343 set_type (struct data_parser *parser, const char *subcommand,
344           enum data_parser_type type, bool *has_type)
345 {
346   if (!*has_type)
347     {
348       data_parser_set_type (parser, type);
349       *has_type = true;
350     }
351   else if (type != data_parser_get_type (parser))
352     {
353       msg (SE, _("%s is allowed only with %s arrangement, but %s arrangement "
354                  "was stated or implied earlier in this command."),
355            subcommand,
356            type == DP_FIXED ? "FIXED" : "DELIMITED",
357            type == DP_FIXED ? "DELIMITED" : "FIXED");
358       return false;
359     }
360   return true;
361 }
362
363 static int
364 parse_get_txt (struct lexer *lexer, struct dataset *ds)
365 {
366   struct data_parser *parser = NULL;
367   struct dictionary *dict = dict_create (get_default_encoding ());
368   struct file_handle *fh = NULL;
369   struct dfm_reader *reader = NULL;
370   char *encoding = NULL;
371   char *name = NULL;
372
373   int record;
374   enum data_parser_type type;
375   bool has_type;
376
377   lex_force_match (lexer, T_SLASH);
378
379   if (!lex_force_match_id (lexer, "FILE"))
380     goto error;
381   lex_force_match (lexer, T_EQUALS);
382   fh = fh_parse (lexer, FH_REF_FILE | FH_REF_INLINE, NULL);
383   if (fh == NULL)
384     goto error;
385
386   parser = data_parser_create (dict);
387   has_type = false;
388   data_parser_set_type (parser, DP_DELIMITED);
389   data_parser_set_span (parser, false);
390   data_parser_set_quotes (parser, ss_empty ());
391   data_parser_set_quote_escape (parser, true);
392   data_parser_set_empty_line_has_field (parser, true);
393
394   for (;;)
395     {
396       if (!lex_force_match (lexer, T_SLASH))
397         goto error;
398
399       if (lex_match_id (lexer, "ENCODING"))
400         {
401           lex_match (lexer, T_EQUALS);
402           if (!lex_force_string (lexer))
403             goto error;
404
405           free (encoding);
406           encoding = ss_xstrdup (lex_tokss (lexer));
407
408           lex_get (lexer);
409         }
410       else if (lex_match_id (lexer, "ARRANGEMENT"))
411         {
412           bool ok;
413
414           lex_match (lexer, T_EQUALS);
415           if (lex_match_id (lexer, "FIXED"))
416             ok = set_type (parser, "ARRANGEMENT=FIXED", DP_FIXED, &has_type);
417           else if (lex_match_id (lexer, "DELIMITED"))
418             ok = set_type (parser, "ARRANGEMENT=DELIMITED",
419                            DP_DELIMITED, &has_type);
420           else
421             {
422               lex_error_expecting (lexer, "FIXED", "DELIMITED", NULL_SENTINEL);
423               goto error;
424             }
425           if (!ok)
426             goto error;
427         }
428       else if (lex_match_id (lexer, "FIRSTCASE"))
429         {
430           lex_match (lexer, T_EQUALS);
431           if (!lex_force_int (lexer))
432             goto error;
433           if (lex_integer (lexer) < 1)
434             {
435               msg (SE, _("Value of %s must be 1 or greater."), "FIRSTCASE");
436               goto error;
437             }
438           data_parser_set_skip (parser, lex_integer (lexer) - 1);
439           lex_get (lexer);
440         }
441       else if (lex_match_id_n (lexer, "DELCASE", 4))
442         {
443           if (!set_type (parser, "DELCASE", DP_DELIMITED, &has_type))
444             goto error;
445           lex_match (lexer, T_EQUALS);
446           if (lex_match_id (lexer, "LINE"))
447             data_parser_set_span (parser, false);
448           else if (lex_match_id (lexer, "VARIABLES"))
449             {
450               data_parser_set_span (parser, true);
451
452               /* VARIABLES takes an integer argument, but for no
453                  good reason.  We just ignore it. */
454               if (!lex_force_int (lexer))
455                 goto error;
456               lex_get (lexer);
457             }
458           else
459             {
460               lex_error_expecting (lexer, "LINE", "VARIABLES", NULL_SENTINEL);
461               goto error;
462             }
463         }
464       else if (lex_match_id (lexer, "FIXCASE"))
465         {
466           if (!set_type (parser, "FIXCASE", DP_FIXED, &has_type))
467             goto error;
468           lex_match (lexer, T_EQUALS);
469           if (!lex_force_int (lexer))
470             goto error;
471           if (lex_integer (lexer) < 1)
472             {
473               msg (SE, _("Value of %s must be 1 or greater."), "FIXCASE");
474               goto error;
475             }
476           data_parser_set_records (parser, lex_integer (lexer));
477           lex_get (lexer);
478         }
479       else if (lex_match_id (lexer, "IMPORTCASES"))
480         {
481           lex_match (lexer, T_EQUALS);
482           if (lex_match (lexer, T_ALL))
483             {
484               /* Nothing to do. */
485             }
486           else if (lex_match_id (lexer, "FIRST"))
487             {
488               if (!lex_force_int (lexer))
489                 goto error;
490               lex_get (lexer);
491             }
492           else if (lex_match_id (lexer, "PERCENT"))
493             {
494               if (!lex_force_int (lexer))
495                 goto error;
496               lex_get (lexer);
497             }
498           msg (SW, _("Ignoring obsolete IMPORTCASES subcommand.  (N OF CASES "
499                      "or SAMPLE may be used to substitute.)"));
500         }
501       else if (lex_match_id_n (lexer, "DELIMITERS", 4))
502         {
503           struct string hard_seps = DS_EMPTY_INITIALIZER;
504           const char *soft_seps = "";
505           struct substring s;
506           int c;
507
508           if (!set_type (parser, "DELIMITERS", DP_DELIMITED, &has_type))
509             goto error;
510           lex_match (lexer, T_EQUALS);
511
512           if (!lex_force_string (lexer))
513             goto error;
514
515           /* XXX should support multibyte UTF-8 characters */
516           s = lex_tokss (lexer);
517           if (ss_match_string (&s, ss_cstr ("\\t")))
518             ds_put_cstr (&hard_seps, "\t");
519           if (ss_match_string (&s, ss_cstr ("\\\\")))
520             ds_put_cstr (&hard_seps, "\\");
521           while ((c = ss_get_byte (&s)) != EOF)
522             if (c == ' ')
523               soft_seps = " ";
524             else
525               ds_put_byte (&hard_seps, c);
526           data_parser_set_soft_delimiters (parser, ss_cstr (soft_seps));
527           data_parser_set_hard_delimiters (parser, ds_ss (&hard_seps));
528           ds_destroy (&hard_seps);
529
530           lex_get (lexer);
531         }
532       else if (lex_match_id (lexer, "QUALIFIERS"))
533         {
534           if (!set_type (parser, "QUALIFIERS", DP_DELIMITED, &has_type))
535             goto error;
536           lex_match (lexer, T_EQUALS);
537
538           if (!lex_force_string (lexer))
539             goto error;
540
541           /* XXX should support multibyte UTF-8 characters */
542           if (settings_get_syntax () == COMPATIBLE
543               && ss_length (lex_tokss (lexer)) != 1)
544             {
545               msg (SE, _("In compatible syntax mode, the QUALIFIER string "
546                          "must contain exactly one character."));
547               goto error;
548             }
549
550           data_parser_set_quotes (parser, lex_tokss (lexer));
551           lex_get (lexer);
552         }
553       else if (lex_match_id (lexer, "VARIABLES"))
554         break;
555       else
556         {
557           lex_error_expecting (lexer, "VARIABLES", NULL_SENTINEL);
558           goto error;
559         }
560     }
561   lex_match (lexer, T_EQUALS);
562
563   record = 1;
564   type = data_parser_get_type (parser);
565   do
566     {
567       struct fmt_spec input, output;
568       struct variable *v;
569       int fc, lc;
570
571       while (type == DP_FIXED && lex_match (lexer, T_SLASH))
572         {
573           if (!lex_force_int (lexer))
574             goto error;
575           if (lex_integer (lexer) < record)
576             {
577               msg (SE, _("The record number specified, %ld, is at or "
578                          "before the previous record, %d.  Data "
579                          "fields must be listed in order of "
580                          "increasing record number."),
581                    lex_integer (lexer), record);
582               goto error;
583             }
584           if (lex_integer (lexer) > data_parser_get_records (parser))
585             {
586               msg (SE, _("The record number specified, %ld, exceeds "
587                          "the number of records per case specified "
588                          "on FIXCASE, %d."),
589                    lex_integer (lexer), data_parser_get_records (parser));
590               goto error;
591             }
592           record = lex_integer (lexer);
593           lex_get (lexer);
594         }
595
596       if (!lex_force_id (lexer)
597           || !dict_id_is_valid (dict, lex_tokcstr (lexer), true))
598         goto error;
599       name = xstrdup (lex_tokcstr (lexer));
600       lex_get (lexer);
601
602       if (type == DP_DELIMITED)
603         {
604           if (!parse_format_specifier (lexer, &input)
605               || !fmt_check_input (&input))
606             goto error;
607
608           output = fmt_for_output_from_input (&input);
609         }
610       else
611         {
612           char fmt_type_name[FMT_TYPE_LEN_MAX + 1];
613           enum fmt_type fmt_type;
614           int w, d;
615
616           if (!parse_column_range (lexer, 0, &fc, &lc, NULL))
617             goto error;
618
619           /* Accept a format (e.g. F8.2) or just a type name (e.g. DOLLAR).  */
620           if (!parse_abstract_format_specifier (lexer, fmt_type_name, &w, &d))
621             goto error;
622           if (!fmt_from_name (fmt_type_name, &fmt_type))
623             {
624               msg (SE, _("Unknown format type `%s'."), fmt_type_name);
625               goto error;
626             }
627
628           /* Compose input format. */
629           input.type = fmt_type;
630           input.w = lc - fc + 1;
631           input.d = 0;
632           if (!fmt_check_input (&input))
633             goto error;
634
635           /* Compose output format. */
636           if (w != 0)
637             {
638               output.type = fmt_type;
639               output.w = w;
640               output.d = d;
641               if (!fmt_check_output (&output))
642                 goto error;
643             }
644           else
645             output = fmt_for_output_from_input (&input);
646         }
647
648       v = dict_create_var (dict, name, fmt_var_width (&input));
649       if (v == NULL)
650         {
651           msg (SE, _("%s is a duplicate variable name."), name);
652           goto error;
653         }
654       var_set_both_formats (v, &output);
655
656       if (type == DP_DELIMITED)
657         data_parser_add_delimited_field (parser, &input,
658                                          var_get_case_index (v),
659                                          name);
660       else
661         data_parser_add_fixed_field (parser, &input, var_get_case_index (v),
662                                      name, record, fc);
663       free (name);
664       name = NULL;
665     }
666   while (lex_token (lexer) != T_ENDCMD);
667
668   reader = dfm_open_reader (fh, lexer, encoding);
669   if (reader == NULL)
670     goto error;
671
672   data_parser_make_active_file (parser, ds, reader, dict);
673   fh_unref (fh);
674   free (encoding);
675   return CMD_SUCCESS;
676
677  error:
678   data_parser_destroy (parser);
679   dict_destroy (dict);
680   fh_unref (fh);
681   free (name);
682   free (encoding);
683   return CMD_CASCADING_FAILURE;
684 }
685
686
687 static void 
688 destroy_spreadsheet_read_info (struct spreadsheet_read_options *opts)
689 {
690   free (opts->cell_range);
691   free (opts->sheet_name);
692 }