dataset: Rename functions with "dataset_" prefix.
[pspp-builds.git] / src / language / data-io / get-data.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2007, 2008, 2009, 2010, 2011 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 "data/dataset.h"
22 #include "data/dictionary.h"
23 #include "data/format.h"
24 #include "data/gnumeric-reader.h"
25 #include "data/psql-reader.h"
26 #include "data/settings.h"
27 #include "language/command.h"
28 #include "language/data-io/data-parser.h"
29 #include "language/data-io/data-reader.h"
30 #include "language/data-io/file-handle.h"
31 #include "language/data-io/placement-parser.h"
32 #include "language/lexer/format-parser.h"
33 #include "language/lexer/lexer.h"
34 #include "libpspp/i18n.h"
35 #include "libpspp/message.h"
36
37 #include "gl/xalloc.h"
38
39 #include "gettext.h"
40 #define _(msgid) gettext (msgid)
41 #define N_(msgid) (msgid)
42
43 static int parse_get_gnm (struct lexer *lexer, struct dataset *);
44 static int parse_get_txt (struct lexer *lexer, struct dataset *);
45 static int parse_get_psql (struct lexer *lexer, struct dataset *);
46
47 int
48 cmd_get_data (struct lexer *lexer, struct dataset *ds)
49 {
50   lex_force_match (lexer, T_SLASH);
51
52   if (!lex_force_match_id (lexer, "TYPE"))
53     return CMD_FAILURE;
54
55   lex_force_match (lexer, T_EQUALS);
56
57   if (lex_match_id (lexer, "GNM"))
58     return parse_get_gnm (lexer, ds);
59   else if (lex_match_id (lexer, "TXT"))
60     return parse_get_txt (lexer, ds);
61   else if (lex_match_id (lexer, "PSQL"))
62     return parse_get_psql (lexer, ds);
63
64   msg (SE, _("Unsupported TYPE %s."), lex_tokcstr (lexer));
65   return CMD_FAILURE;
66 }
67
68 static int
69 parse_get_psql (struct lexer *lexer, struct dataset *ds)
70 {
71   struct psql_read_info psql;
72   psql.allow_clear = false;
73   psql.conninfo = NULL;
74   psql.str_width = -1;
75   psql.bsize = -1;
76   ds_init_empty (&psql.sql);
77
78   lex_force_match (lexer, T_SLASH);
79
80   if (!lex_force_match_id (lexer, "CONNECT"))
81     goto error;
82
83   lex_force_match (lexer, T_EQUALS);
84
85   if (!lex_force_string (lexer))
86     goto error;
87
88   psql.conninfo = ss_xstrdup (lex_tokss (lexer));
89
90   lex_get (lexer);
91
92   while (lex_match (lexer, T_SLASH) )
93     {
94       if ( lex_match_id (lexer, "ASSUMEDSTRWIDTH"))
95         {
96           lex_match (lexer, T_EQUALS);
97           psql.str_width = lex_integer (lexer);
98           lex_get (lexer);
99         }
100       else if ( lex_match_id (lexer, "BSIZE"))
101         {
102           lex_match (lexer, T_EQUALS);
103           psql.bsize = lex_integer (lexer);
104           lex_get (lexer);
105         }
106       else if ( lex_match_id (lexer, "UNENCRYPTED"))
107         {
108           psql.allow_clear = true;
109         }
110       else if (lex_match_id (lexer, "SQL"))
111         {
112           lex_match (lexer, T_EQUALS);
113           if ( ! lex_force_string (lexer) )
114             goto error;
115
116           ds_put_substring (&psql.sql, lex_tokss (lexer));
117           lex_get (lexer);
118         }
119      }
120   {
121     struct dictionary *dict = NULL;
122     struct casereader *reader = psql_open_reader (&psql, &dict);
123
124     if ( reader )
125       {
126         dataset_set_dict (ds, dict);
127         dataset_set_source (ds, reader);
128       }
129   }
130
131   ds_destroy (&psql.sql);
132   free (psql.conninfo);
133
134   return CMD_SUCCESS;
135
136  error:
137
138   ds_destroy (&psql.sql);
139   free (psql.conninfo);
140
141   return CMD_FAILURE;
142 }
143
144 static int
145 parse_get_gnm (struct lexer *lexer, struct dataset *ds)
146 {
147   struct gnumeric_read_info gri  = {NULL, NULL, NULL, 1, true, -1};
148
149   lex_force_match (lexer, T_SLASH);
150
151   if (!lex_force_match_id (lexer, "FILE"))
152     goto error;
153
154   lex_force_match (lexer, T_EQUALS);
155
156   if (!lex_force_string (lexer))
157     goto error;
158
159   gri.file_name = utf8_to_filename (lex_tokcstr (lexer));
160
161   lex_get (lexer);
162
163   while (lex_match (lexer, T_SLASH) )
164     {
165       if ( lex_match_id (lexer, "ASSUMEDSTRWIDTH"))
166         {
167           lex_match (lexer, T_EQUALS);
168           gri.asw = lex_integer (lexer);
169           lex_get (lexer);
170         }
171       else if (lex_match_id (lexer, "SHEET"))
172         {
173           lex_match (lexer, T_EQUALS);
174           if (lex_match_id (lexer, "NAME"))
175             {
176               if ( ! lex_force_string (lexer) )
177                 goto error;
178
179               gri.sheet_name = ss_xstrdup (lex_tokss (lexer));
180               gri.sheet_index = -1;
181
182               lex_get (lexer);
183             }
184           else if (lex_match_id (lexer, "INDEX"))
185             {
186               gri.sheet_index = lex_integer (lexer);
187               lex_get (lexer);
188             }
189           else
190             goto error;
191         }
192       else if (lex_match_id (lexer, "CELLRANGE"))
193         {
194           lex_match (lexer, T_EQUALS);
195
196           if (lex_match_id (lexer, "FULL"))
197             {
198               gri.cell_range = NULL;
199             }
200           else if (lex_match_id (lexer, "RANGE"))
201             {
202               if ( ! lex_force_string (lexer) )
203                 goto error;
204
205               gri.cell_range = ss_xstrdup (lex_tokss (lexer));
206               lex_get (lexer);
207             }
208           else
209             goto error;
210         }
211       else if (lex_match_id (lexer, "READNAMES"))
212         {
213           lex_match (lexer, T_EQUALS);
214
215           if ( lex_match_id (lexer, "ON"))
216             {
217               gri.read_names = true;
218             }
219           else if (lex_match_id (lexer, "OFF"))
220             {
221               gri.read_names = false;
222             }
223           else
224             goto error;
225         }
226       else
227         {
228           lex_error (lexer, NULL);
229           goto error;
230         }
231     }
232
233   {
234     struct dictionary *dict = NULL;
235     struct casereader *reader = gnumeric_open_reader (&gri, &dict);
236
237     if ( reader )
238       {
239         dataset_set_dict (ds, dict);
240         dataset_set_source (ds, reader);
241       }
242   }
243
244   free (gri.file_name);
245   free (gri.sheet_name);
246   free (gri.cell_range);
247   return CMD_SUCCESS;
248
249  error:
250
251   free (gri.file_name);
252   free (gri.sheet_name);
253   free (gri.cell_range);
254   return CMD_FAILURE;
255 }
256
257 static bool
258 set_type (struct data_parser *parser, const char *subcommand,
259           enum data_parser_type type, bool *has_type)
260 {
261   if (!*has_type)
262     {
263       data_parser_set_type (parser, type);
264       *has_type = true;
265     }
266   else if (type != data_parser_get_type (parser))
267     {
268       msg (SE, _("%s is allowed only with %s arrangement, but %s arrangement "
269                  "was stated or implied earlier in this command."),
270            subcommand,
271            type == DP_FIXED ? "FIXED" : "DELIMITED",
272            type == DP_FIXED ? "DELIMITED" : "FIXED");
273       return false;
274     }
275   return true;
276 }
277
278 static int
279 parse_get_txt (struct lexer *lexer, struct dataset *ds)
280 {
281   struct data_parser *parser = NULL;
282   struct dictionary *dict = dict_create ();
283   struct file_handle *fh = NULL;
284   struct dfm_reader *reader = NULL;
285   char *name = NULL;
286
287   int record;
288   enum data_parser_type type;
289   bool has_type;
290
291   lex_force_match (lexer, T_SLASH);
292
293   if (!lex_force_match_id (lexer, "FILE"))
294     goto error;
295   lex_force_match (lexer, T_EQUALS);
296   fh = fh_parse (lexer, FH_REF_FILE | FH_REF_INLINE);
297   if (fh == NULL)
298     goto error;
299
300   parser = data_parser_create (dict);
301   has_type = false;
302   data_parser_set_type (parser, DP_DELIMITED);
303   data_parser_set_span (parser, false);
304   data_parser_set_quotes (parser, ss_empty ());
305   data_parser_set_empty_line_has_field (parser, true);
306
307   for (;;)
308     {
309       if (!lex_force_match (lexer, T_SLASH))
310         goto error;
311
312       if (lex_match_id (lexer, "ARRANGEMENT"))
313         {
314           bool ok;
315
316           lex_match (lexer, T_EQUALS);
317           if (lex_match_id (lexer, "FIXED"))
318             ok = set_type (parser, "ARRANGEMENT=FIXED", DP_FIXED, &has_type);
319           else if (lex_match_id (lexer, "DELIMITED"))
320             ok = set_type (parser, "ARRANGEMENT=DELIMITED",
321                            DP_DELIMITED, &has_type);
322           else
323             {
324               lex_error (lexer, _("expecting %s or %s"), "FIXED", "DELIMITED");
325               goto error;
326             }
327           if (!ok)
328             goto error;
329         }
330       else if (lex_match_id (lexer, "FIRSTCASE"))
331         {
332           lex_match (lexer, T_EQUALS);
333           if (!lex_force_int (lexer))
334             goto error;
335           if (lex_integer (lexer) < 1)
336             {
337               msg (SE, _("Value of FIRSTCASE must be 1 or greater."));
338               goto error;
339             }
340           data_parser_set_skip (parser, lex_integer (lexer) - 1);
341           lex_get (lexer);
342         }
343       else if (lex_match_id_n (lexer, "DELCASE", 4))
344         {
345           if (!set_type (parser, "DELCASE", DP_DELIMITED, &has_type))
346             goto error;
347           lex_match (lexer, T_EQUALS);
348           if (lex_match_id (lexer, "LINE"))
349             data_parser_set_span (parser, false);
350           else if (lex_match_id (lexer, "VARIABLES"))
351             {
352               data_parser_set_span (parser, true);
353
354               /* VARIABLES takes an integer argument, but for no
355                  good reason.  We just ignore it. */
356               if (!lex_force_int (lexer))
357                 goto error;
358               lex_get (lexer);
359             }
360           else
361             {
362               lex_error (lexer, _("expecting %s or %s"), "LINE", "VARIABLES");
363               goto error;
364             }
365         }
366       else if (lex_match_id (lexer, "FIXCASE"))
367         {
368           if (!set_type (parser, "FIXCASE", DP_FIXED, &has_type))
369             goto error;
370           lex_match (lexer, T_EQUALS);
371           if (!lex_force_int (lexer))
372             goto error;
373           if (lex_integer (lexer) < 1)
374             {
375               msg (SE, _("Value of FIXCASE must be at least 1."));
376               goto error;
377             }
378           data_parser_set_records (parser, lex_integer (lexer));
379           lex_get (lexer);
380         }
381       else if (lex_match_id (lexer, "IMPORTCASES"))
382         {
383           lex_match (lexer, T_EQUALS);
384           if (lex_match (lexer, T_ALL))
385             {
386               data_parser_set_case_limit (parser, -1);
387               data_parser_set_case_percent (parser, 100);
388             }
389           else if (lex_match_id (lexer, "FIRST"))
390             {
391               if (!lex_force_int (lexer))
392                 goto error;
393               if (lex_integer (lexer) < 1)
394                 {
395                   msg (SE, _("Value of FIRST must be at least 1."));
396                   goto error;
397                 }
398               data_parser_set_case_limit (parser, lex_integer (lexer));
399               lex_get (lexer);
400             }
401           else if (lex_match_id (lexer, "PERCENT"))
402             {
403               if (!lex_force_int (lexer))
404                 goto error;
405               if (lex_integer (lexer) < 1 || lex_integer (lexer) > 100)
406                 {
407                   msg (SE, _("Value of PERCENT must be between 1 and 100."));
408                   goto error;
409                 }
410               data_parser_set_case_percent (parser, lex_integer (lexer));
411               lex_get (lexer);
412             }
413         }
414       else if (lex_match_id_n (lexer, "DELIMITERS", 4))
415         {
416           struct string hard_seps = DS_EMPTY_INITIALIZER;
417           const char *soft_seps = "";
418           struct substring s;
419           int c;
420
421           if (!set_type (parser, "DELIMITERS", DP_DELIMITED, &has_type))
422             goto error;
423           lex_match (lexer, T_EQUALS);
424
425           if (!lex_force_string (lexer))
426             goto error;
427
428           /* XXX should support multibyte UTF-8 characters */
429           s = lex_tokss (lexer);
430           if (ss_match_string (&s, ss_cstr ("\\t")))
431             ds_put_cstr (&hard_seps, "\t");
432           if (ss_match_string (&s, ss_cstr ("\\\\")))
433             ds_put_cstr (&hard_seps, "\\");
434           while ((c = ss_get_byte (&s)) != EOF)
435             if (c == ' ')
436               soft_seps = " ";
437             else
438               ds_put_byte (&hard_seps, c);
439           data_parser_set_soft_delimiters (parser, ss_cstr (soft_seps));
440           data_parser_set_hard_delimiters (parser, ds_ss (&hard_seps));
441           ds_destroy (&hard_seps);
442
443           lex_get (lexer);
444         }
445       else if (lex_match_id (lexer, "QUALIFIERS"))
446         {
447           if (!set_type (parser, "QUALIFIERS", DP_DELIMITED, &has_type))
448             goto error;
449           lex_match (lexer, T_EQUALS);
450
451           if (!lex_force_string (lexer))
452             goto error;
453
454           /* XXX should support multibyte UTF-8 characters */
455           if (settings_get_syntax () == COMPATIBLE
456               && ss_length (lex_tokss (lexer)) != 1)
457             {
458               msg (SE, _("In compatible syntax mode, the QUALIFIER string "
459                          "must contain exactly one character."));
460               goto error;
461             }
462
463           data_parser_set_quotes (parser, lex_tokss (lexer));
464           lex_get (lexer);
465         }
466       else if (settings_get_syntax () == ENHANCED
467                && lex_match_id (lexer, "ESCAPE"))
468         data_parser_set_quote_escape (parser, true);
469       else if (lex_match_id (lexer, "VARIABLES"))
470         break;
471       else
472         {
473           lex_error (lexer, _("expecting %s"), "VARIABLES");
474           goto error;
475         }
476     }
477   lex_match (lexer, T_EQUALS);
478
479   record = 1;
480   type = data_parser_get_type (parser);
481   do
482     {
483       struct fmt_spec input, output;
484       struct variable *v;
485       int fc, lc;
486
487       while (type == DP_FIXED && lex_match (lexer, T_SLASH))
488         {
489           if (!lex_force_int (lexer))
490             goto error;
491           if (lex_integer (lexer) < record)
492             {
493               msg (SE, _("The record number specified, %ld, is at or "
494                          "before the previous record, %d.  Data "
495                          "fields must be listed in order of "
496                          "increasing record number."),
497                    lex_integer (lexer), record);
498               goto error;
499             }
500           if (lex_integer (lexer) > data_parser_get_records (parser))
501             {
502               msg (SE, _("The record number specified, %ld, exceeds "
503                          "the number of records per case specified "
504                          "on FIXCASE, %d."),
505                    lex_integer (lexer), data_parser_get_records (parser));
506               goto error;
507             }
508           record = lex_integer (lexer);
509           lex_get (lexer);
510         }
511
512       if (!lex_force_id (lexer)
513           || !dict_id_is_valid (dict, lex_tokcstr (lexer), true))
514         goto error;
515       name = xstrdup (lex_tokcstr (lexer));
516       lex_get (lexer);
517
518       if (type == DP_DELIMITED)
519         {
520           if (!parse_format_specifier (lexer, &input)
521               || !fmt_check_input (&input))
522             goto error;
523         }
524       else
525         {
526           if (!parse_column_range (lexer, 0, &fc, &lc, NULL))
527             goto error;
528           if (!parse_format_specifier_name (lexer, &input.type))
529             goto error;
530           input.w = lc - fc + 1;
531           input.d = 0;
532           if (!fmt_check_input (&input))
533             goto error;
534         }
535       output = fmt_for_output_from_input (&input);
536
537       v = dict_create_var (dict, name, fmt_var_width (&input));
538       if (v == NULL)
539         {
540           msg (SE, _("%s is a duplicate variable name."), name);
541           goto error;
542         }
543       var_set_both_formats (v, &output);
544
545       if (type == DP_DELIMITED)
546         data_parser_add_delimited_field (parser, &input,
547                                          var_get_case_index (v),
548                                          name);
549       else
550         data_parser_add_fixed_field (parser, &input, var_get_case_index (v),
551                                      name, record, fc);
552       free (name);
553       name = NULL;
554     }
555   while (lex_token (lexer) != T_ENDCMD);
556
557   reader = dfm_open_reader (fh, lexer);
558   if (reader == NULL)
559     goto error;
560
561   data_parser_make_active_file (parser, ds, reader, dict);
562   fh_unref (fh);
563   return CMD_SUCCESS;
564
565  error:
566   data_parser_destroy (parser);
567   dict_destroy (dict);
568   fh_unref (fh);
569   free (name);
570   return CMD_CASCADING_FAILURE;
571 }