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