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