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