work on datasets
[pspp] / src / language / data-io / data-parser.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2007, 2009, 2010, 2011, 2012, 2013, 2016 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 "language/data-io/data-parser.h"
20
21 #include <stdint.h>
22 #include <stdlib.h>
23
24 #include "data/casereader-provider.h"
25 #include "data/data-in.h"
26 #include "data/dataset.h"
27 #include "data/dictionary.h"
28 #include "data/format.h"
29 #include "data/file-handle-def.h"
30 #include "data/session.h"
31 #include "data/settings.h"
32 #include "language/data-io/data-reader.h"
33 #include "libpspp/message.h"
34 #include "libpspp/str.h"
35 #include "output/tab.h"
36
37 #include "gl/xalloc.h"
38
39 #include "gettext.h"
40 #define _(msgid) gettext (msgid)
41
42 /* Data parser for textual data like that read by DATA LIST. */
43 struct data_parser
44   {
45     const struct dictionary *dict; /*Dictionary of destination */
46     enum data_parser_type type; /* Type of data to parse. */
47     int skip_records;           /* Records to skip before first real data. */
48
49     struct field *fields;       /* Fields to parse. */
50     size_t field_cnt;           /* Number of fields. */
51     size_t field_allocated;     /* Number of fields spaced allocated for. */
52
53     /* DP_DELIMITED parsers only. */
54     bool span;                  /* May cases span multiple records? */
55     bool empty_line_has_field;  /* Does an empty line have an (empty) field? */
56     struct substring quotes;    /* Characters that can quote separators. */
57     bool quote_escape;          /* Doubled quote acts as escape? */
58     struct substring soft_seps; /* Two soft separators act like just one. */
59     struct substring hard_seps; /* Two hard separators yield empty fields. */
60     struct string any_sep;      /* Concatenation of soft_seps and hard_seps. */
61
62     /* DP_FIXED parsers only. */
63     int records_per_case;       /* Number of records in each case. */
64   };
65
66 /* How to parse one variable. */
67 struct field
68   {
69     struct fmt_spec format;     /* Input format of this field. */
70     int case_idx;               /* First value in case. */
71     char *name;                 /* Var name for error messages and tables. */
72
73     /* DP_FIXED only. */
74     int record;                 /* Record number (1-based). */
75     int first_column;           /* First column in record (1-based). */
76   };
77
78 static void set_any_sep (struct data_parser *parser);
79
80 /* Creates and returns a new data parser. */
81 struct data_parser *
82 data_parser_create (const struct dictionary *dict)
83 {
84   struct data_parser *parser = xmalloc (sizeof *parser);
85
86   parser->type = DP_FIXED;
87   parser->skip_records = 0;
88
89   parser->fields = NULL;
90   parser->field_cnt = 0;
91   parser->field_allocated = 0;
92   parser->dict = dict;
93
94   parser->span = true;
95   parser->empty_line_has_field = false;
96   ss_alloc_substring (&parser->quotes, ss_cstr ("\"'"));
97   parser->quote_escape = false;
98   ss_alloc_substring (&parser->soft_seps, ss_cstr (CC_SPACES));
99   ss_alloc_substring (&parser->hard_seps, ss_cstr (","));
100   ds_init_empty (&parser->any_sep);
101   set_any_sep (parser);
102
103   parser->records_per_case = 0;
104
105   return parser;
106 }
107
108 /* Destroys PARSER. */
109 void
110 data_parser_destroy (struct data_parser *parser)
111 {
112   if (parser != NULL)
113     {
114       size_t i;
115
116       for (i = 0; i < parser->field_cnt; i++)
117         free (parser->fields[i].name);
118       free (parser->fields);
119       ss_dealloc (&parser->quotes);
120       ss_dealloc (&parser->soft_seps);
121       ss_dealloc (&parser->hard_seps);
122       ds_destroy (&parser->any_sep);
123       free (parser);
124     }
125 }
126
127 /* Returns the type of PARSER (either DP_DELIMITED or DP_FIXED). */
128 enum data_parser_type
129 data_parser_get_type (const struct data_parser *parser)
130 {
131   return parser->type;
132 }
133
134 /* Sets the type of PARSER to TYPE (either DP_DELIMITED or
135    DP_FIXED). */
136 void
137 data_parser_set_type (struct data_parser *parser, enum data_parser_type type)
138 {
139   assert (parser->field_cnt == 0);
140   assert (type == DP_FIXED || type == DP_DELIMITED);
141   parser->type = type;
142 }
143
144 /* Configures PARSER to skip the specified number of
145    INITIAL_RECORDS_TO_SKIP before parsing any data.  By default,
146    no records are skipped. */
147 void
148 data_parser_set_skip (struct data_parser *parser, int initial_records_to_skip)
149 {
150   assert (initial_records_to_skip >= 0);
151   parser->skip_records = initial_records_to_skip;
152 }
153
154 /* Returns true if PARSER is configured to allow cases to span
155    multiple records. */
156 bool
157 data_parser_get_span (const struct data_parser *parser)
158 {
159   return parser->span;
160 }
161
162 /* If MAY_CASES_SPAN_RECORDS is true, configures PARSER to allow
163    a single case to span multiple records and multiple cases to
164    occupy a single record.  If MAY_CASES_SPAN_RECORDS is false,
165    configures PARSER to require each record to contain exactly
166    one case.
167
168    This setting affects parsing of DP_DELIMITED files only. */
169 void
170 data_parser_set_span (struct data_parser *parser, bool may_cases_span_records)
171 {
172   parser->span = may_cases_span_records;
173 }
174
175 /* If EMPTY_LINE_HAS_FIELD is true, configures PARSER to parse an
176    empty line as an empty field and to treat a hard delimiter
177    followed by end-of-line as an empty field.  If
178    EMPTY_LINE_HAS_FIELD is false, PARSER will skip empty lines
179    and hard delimiters at the end of lines without emitting empty
180    fields.
181
182    This setting affects parsing of DP_DELIMITED files only. */
183 void
184 data_parser_set_empty_line_has_field (struct data_parser *parser,
185                                       bool empty_line_has_field)
186 {
187   parser->empty_line_has_field = empty_line_has_field;
188 }
189
190 /* Sets the characters that may be used for quoting field
191    contents to QUOTES.  If QUOTES is empty, quoting will be
192    disabled.
193
194    The caller retains ownership of QUOTES.
195
196    This setting affects parsing of DP_DELIMITED files only. */
197 void
198 data_parser_set_quotes (struct data_parser *parser, struct substring quotes)
199 {
200   ss_dealloc (&parser->quotes);
201   ss_alloc_substring (&parser->quotes, quotes);
202 }
203
204 /* If ESCAPE is false (the default setting), a character used for
205    quoting cannot itself be embedded within a quoted field.  If
206    ESCAPE is true, then a quote character can be embedded within
207    a quoted field by doubling it.
208
209    This setting affects parsing of DP_DELIMITED files only, and
210    only when at least one quote character has been set (with
211    data_parser_set_quotes). */
212 void
213 data_parser_set_quote_escape (struct data_parser *parser, bool escape)
214 {
215   parser->quote_escape = escape;
216 }
217
218 /* Sets PARSER's soft delimiters to DELIMITERS.  Soft delimiters
219    separate fields, but consecutive soft delimiters do not yield
220    empty fields.  (Ordinarily, only white space characters are
221    appropriate soft delimiters.)
222
223    The caller retains ownership of DELIMITERS.
224
225    This setting affects parsing of DP_DELIMITED files only. */
226 void
227 data_parser_set_soft_delimiters (struct data_parser *parser,
228                                  struct substring delimiters)
229 {
230   ss_dealloc (&parser->soft_seps);
231   ss_alloc_substring (&parser->soft_seps, delimiters);
232   set_any_sep (parser);
233 }
234
235 /* Sets PARSER's hard delimiters to DELIMITERS.  Hard delimiters
236    separate fields.  A consecutive pair of hard delimiters yield
237    an empty field.
238
239    The caller retains ownership of DELIMITERS.
240
241    This setting affects parsing of DP_DELIMITED files only. */
242 void
243 data_parser_set_hard_delimiters (struct data_parser *parser,
244                                  struct substring delimiters)
245 {
246   ss_dealloc (&parser->hard_seps);
247   ss_alloc_substring (&parser->hard_seps, delimiters);
248   set_any_sep (parser);
249 }
250
251 /* Returns the number of records per case. */
252 int
253 data_parser_get_records (const struct data_parser *parser)
254 {
255   return parser->records_per_case;
256 }
257
258 /* Sets the number of records per case to RECORDS_PER_CASE.
259
260    This setting affects parsing of DP_FIXED files only. */
261 void
262 data_parser_set_records (struct data_parser *parser, int records_per_case)
263 {
264   assert (records_per_case >= 0);
265   assert (records_per_case >= parser->records_per_case);
266   parser->records_per_case = records_per_case;
267 }
268
269 static void
270 add_field (struct data_parser *p, const struct fmt_spec *format, int case_idx,
271            const char *name, int record, int first_column)
272 {
273   struct field *field;
274
275   if (p->field_cnt == p->field_allocated)
276     p->fields = x2nrealloc (p->fields, &p->field_allocated, sizeof *p->fields);
277   field = &p->fields[p->field_cnt++];
278   field->format = *format;
279   field->case_idx = case_idx;
280   field->name = xstrdup (name);
281   field->record = record;
282   field->first_column = first_column;
283 }
284
285 /* Adds a delimited field to the field parsed by PARSER, which
286    must be configured as a DP_DELIMITED parser.  The field is
287    parsed as input format FORMAT.  Its data will be stored into case
288    index CASE_INDEX.  Errors in input data will be reported
289    against variable NAME. */
290 void
291 data_parser_add_delimited_field (struct data_parser *parser,
292                                  const struct fmt_spec *format, int case_idx,
293                                  const char *name)
294 {
295   assert (parser->type == DP_DELIMITED);
296   add_field (parser, format, case_idx, name, 0, 0);
297 }
298
299 /* Adds a fixed field to the field parsed by PARSER, which
300    must be configured as a DP_FIXED parser.  The field is
301    parsed as input format FORMAT.  Its data will be stored into case
302    index CASE_INDEX.  Errors in input data will be reported
303    against variable NAME.  The field will be drawn from the
304    FORMAT->w columns in 1-based RECORD starting at 1-based
305    column FIRST_COLUMN.
306
307    RECORD must be at least as great as that of any field already
308    added; that is, fields must be added in increasing order of
309    record number.  If RECORD is greater than the current number
310    of records per case, the number of records per case are
311    increased as needed.  */
312 void
313 data_parser_add_fixed_field (struct data_parser *parser,
314                              const struct fmt_spec *format, int case_idx,
315                              const char *name,
316                              int record, int first_column)
317 {
318   assert (parser->type == DP_FIXED);
319   assert (parser->field_cnt == 0
320           || record >= parser->fields[parser->field_cnt - 1].record);
321   if (record > parser->records_per_case)
322     parser->records_per_case = record;
323   add_field (parser, format, case_idx, name, record, first_column);
324 }
325
326 /* Returns true if any fields have been added to PARSER, false
327    otherwise. */
328 bool
329 data_parser_any_fields (const struct data_parser *parser)
330 {
331   return parser->field_cnt > 0;
332 }
333
334 static void
335 set_any_sep (struct data_parser *parser)
336 {
337   ds_assign_substring (&parser->any_sep, parser->soft_seps);
338   ds_put_substring (&parser->any_sep, parser->hard_seps);
339 }
340 \f
341 static bool parse_delimited_span (const struct data_parser *,
342                                   struct dfm_reader *, struct ccase *);
343 static bool parse_delimited_no_span (const struct data_parser *,
344                                      struct dfm_reader *, struct ccase *);
345 static bool parse_fixed (const struct data_parser *,
346                          struct dfm_reader *, struct ccase *);
347
348 /* Reads a case from DFM into C, parsing it with PARSER.  Returns
349    true if successful, false at end of file or on I/O error.
350
351    Case C must not be shared. */
352 bool
353 data_parser_parse (struct data_parser *parser, struct dfm_reader *reader,
354                    struct ccase *c)
355 {
356   bool retval;
357
358   assert (!case_is_shared (c));
359   assert (data_parser_any_fields (parser));
360
361   /* Skip the requested number of records before reading the
362      first case. */
363   for (; parser->skip_records > 0; parser->skip_records--)
364     {
365       if (dfm_eof (reader))
366         return false;
367       dfm_forward_record (reader);
368     }
369
370   /* Limit cases. */
371   if (parser->type == DP_DELIMITED)
372     {
373       if (parser->span)
374         retval = parse_delimited_span (parser, reader, c);
375       else
376         retval = parse_delimited_no_span (parser, reader, c);
377     }
378   else
379     retval = parse_fixed (parser, reader, c);
380
381   return retval;
382 }
383
384 /* Extracts a delimited field from the current position in the
385    current record according to PARSER, reading data from READER.
386
387    *FIELD is set to the field content.  The caller must not or
388    destroy this constant string.
389
390    After parsing the field, sets the current position in the
391    record to just past the field and any trailing delimiter.
392    Returns 0 on failure or a 1-based column number indicating the
393    beginning of the field on success. */
394 static bool
395 cut_field (const struct data_parser *parser, struct dfm_reader *reader,
396            int *first_column, int *last_column, struct string *tmp,
397            struct substring *field)
398 {
399   size_t length_before_separators;
400   struct substring line, p;
401   bool quoted;
402
403   if (dfm_eof (reader))
404     return false;
405   if (ss_is_empty (parser->hard_seps))
406     dfm_expand_tabs (reader);
407   line = p = dfm_get_record (reader);
408
409   /* Skip leading soft separators. */
410   ss_ltrim (&p, parser->soft_seps);
411
412   /* Handle empty or completely consumed lines. */
413   if (ss_is_empty (p))
414     {
415       if (!parser->empty_line_has_field || dfm_columns_past_end (reader) > 0)
416         return false;
417       else
418         {
419           *field = p;
420           *first_column = dfm_column_start (reader);
421           *last_column = *first_column + 1;
422           dfm_forward_columns (reader, 1);
423           return true;
424         }
425     }
426
427   *first_column = dfm_column_start (reader);
428   quoted = ss_find_byte (parser->quotes, ss_first (p)) != SIZE_MAX;
429   if (quoted)
430     {
431       /* Quoted field. */
432       int quote = ss_get_byte (&p);
433       if (!ss_get_until (&p, quote, field))
434         msg (DW, _("Quoted string extends beyond end of line."));
435       if (parser->quote_escape && ss_first (p) == quote)
436         {
437           ds_assign_substring (tmp, *field);
438           while (ss_match_byte (&p, quote))
439             {
440               struct substring ss;
441               ds_put_byte (tmp, quote);
442               if (!ss_get_until (&p, quote, &ss))
443                 msg (DW, _("Quoted string extends beyond end of line."));
444               ds_put_substring (tmp, ss);
445             }
446           *field = ds_ss (tmp);
447         }
448       *last_column = *first_column + (ss_length (line) - ss_length (p));
449     }
450   else
451     {
452       /* Regular field. */
453       ss_get_bytes (&p, ss_cspan (p, ds_ss (&parser->any_sep)), field);
454       *last_column = *first_column + ss_length (*field);
455     }
456
457   /* Skip trailing soft separator and a single hard separator if present. */
458   length_before_separators = ss_length (p);
459   ss_ltrim (&p, parser->soft_seps);
460   if (!ss_is_empty (p)
461       && ss_find_byte (parser->hard_seps, ss_first (p)) != SIZE_MAX)
462     {
463       ss_advance (&p, 1);
464       ss_ltrim (&p, parser->soft_seps);
465     }
466   if (ss_is_empty (p))
467     dfm_forward_columns (reader, 1);
468   else if (quoted && length_before_separators == ss_length (p))
469     msg (DW, _("Missing delimiter following quoted string."));
470   dfm_forward_columns (reader, ss_length (line) - ss_length (p));
471
472   return true;
473 }
474
475 static void
476 parse_error (const struct dfm_reader *reader, const struct field *field,
477              int first_column, int last_column, char *error)
478 {
479   struct msg m;
480
481   m.category = MSG_C_DATA;
482   m.severity = MSG_S_WARNING;
483   m.file_name = CONST_CAST (char *, dfm_get_file_name (reader));
484   m.first_line = dfm_get_line_number (reader);
485   m.last_line = m.first_line + 1;
486   m.first_column = first_column;
487   m.last_column = last_column;
488   m.text = xasprintf (_("Data for variable %s is not valid as format %s: %s"),
489                       field->name, fmt_name (field->format.type), error);
490   msg_emit (&m);
491
492   free (error);
493 }
494
495 /* Reads a case from READER into C, parsing it according to
496    fixed-format syntax rules in PARSER.
497    Returns true if successful, false at end of file or on I/O error. */
498 static bool
499 parse_fixed (const struct data_parser *parser, struct dfm_reader *reader,
500              struct ccase *c)
501 {
502   const char *input_encoding = dfm_reader_get_encoding (reader);
503   const char *output_encoding = dict_get_encoding (parser->dict);
504   struct field *f;
505   int row;
506
507   if (dfm_eof (reader))
508     return false;
509
510   f = parser->fields;
511   for (row = 1; row <= parser->records_per_case; row++)
512     {
513       struct substring line;
514
515       if (dfm_eof (reader))
516         {
517           msg (DW, _("Partial case of %d of %d records discarded."),
518                row - 1, parser->records_per_case);
519           return false;
520         }
521       dfm_expand_tabs (reader);
522       line = dfm_get_record (reader);
523
524       for (; f < &parser->fields[parser->field_cnt] && f->record == row; f++)
525         {
526           struct substring s = ss_substr (line, f->first_column - 1,
527                                           f->format.w);
528           union value *value = case_data_rw_idx (c, f->case_idx);
529           char *error = data_in (s, input_encoding, f->format.type,
530                                  value, fmt_var_width (&f->format),
531                                  output_encoding);
532
533           if (error == NULL)
534             data_in_imply_decimals (s, input_encoding, f->format.type,
535                                     f->format.d, value);
536           else
537             parse_error (reader, f, f->first_column,
538                          f->first_column + f->format.w, error);
539         }
540
541       dfm_forward_record (reader);
542     }
543
544   return true;
545 }
546
547 /* Reads a case from READER into C, parsing it according to
548    free-format syntax rules in PARSER.
549    Returns true if successful, false at end of file or on I/O error. */
550 static bool
551 parse_delimited_span (const struct data_parser *parser,
552                       struct dfm_reader *reader, struct ccase *c)
553 {
554   const char *output_encoding = dict_get_encoding (parser->dict);
555   struct string tmp = DS_EMPTY_INITIALIZER;
556   struct field *f;
557
558   for (f = parser->fields; f < &parser->fields[parser->field_cnt]; f++)
559     {
560       struct substring s;
561       int first_column, last_column;
562       char *error;
563
564       /* Cut out a field and read in a new record if necessary. */
565       while (!cut_field (parser, reader,
566                          &first_column, &last_column, &tmp, &s))
567         {
568           if (!dfm_eof (reader))
569             dfm_forward_record (reader);
570           if (dfm_eof (reader))
571             {
572               if (f > parser->fields)
573                 msg (DW, _("Partial case discarded.  The first variable "
574                            "missing was %s."), f->name);
575               ds_destroy (&tmp);
576               return false;
577             }
578         }
579
580       const char *input_encoding = dfm_reader_get_encoding (reader);
581       error = data_in (s, input_encoding, f->format.type,
582                        case_data_rw_idx (c, f->case_idx),
583                        fmt_var_width (&f->format), output_encoding);
584       if (error != NULL)
585         parse_error (reader, f, first_column, last_column, error);
586     }
587   ds_destroy (&tmp);
588   return true;
589 }
590
591 /* Reads a case from READER into C, parsing it according to
592    delimited syntax rules with one case per record in PARSER.
593    Returns true if successful, false at end of file or on I/O error. */
594 static bool
595 parse_delimited_no_span (const struct data_parser *parser,
596                          struct dfm_reader *reader, struct ccase *c)
597 {
598   const char *output_encoding = dict_get_encoding (parser->dict);
599   struct string tmp = DS_EMPTY_INITIALIZER;
600   struct substring s;
601   struct field *f, *end;
602
603   if (dfm_eof (reader))
604     return false;
605
606   end = &parser->fields[parser->field_cnt];
607   for (f = parser->fields; f < end; f++)
608     {
609       int first_column, last_column;
610       char *error;
611
612       if (!cut_field (parser, reader, &first_column, &last_column, &tmp, &s))
613         {
614           if (f < end - 1 && settings_get_undefined ())
615             msg (DW, _("Missing value(s) for all variables from %s onward.  "
616                        "These will be filled with the system-missing value "
617                        "or blanks, as appropriate."),
618                  f->name);
619           for (; f < end; f++)
620             value_set_missing (case_data_rw_idx (c, f->case_idx),
621                                fmt_var_width (&f->format));
622           goto exit;
623         }
624
625       const char *input_encoding = dfm_reader_get_encoding (reader);
626       error = data_in (s, input_encoding, f->format.type,
627                        case_data_rw_idx (c, f->case_idx),
628                        fmt_var_width (&f->format), output_encoding);
629       if (error != NULL)
630         parse_error (reader, f, first_column, last_column, error);
631     }
632
633   s = dfm_get_record (reader);
634   ss_ltrim (&s, parser->soft_seps);
635   if (!ss_is_empty (s))
636     msg (DW, _("Record ends in data not part of any field."));
637
638 exit:
639   dfm_forward_record (reader);
640   ds_destroy (&tmp);
641   return true;
642 }
643 \f
644 /* Displays a table giving information on fixed-format variable
645    parsing on DATA LIST. */
646 static void
647 dump_fixed_table (const struct data_parser *parser,
648                   const struct file_handle *fh)
649 {
650   struct tab_table *t;
651   size_t i;
652
653   t = tab_create (4, parser->field_cnt + 1);
654   tab_headers (t, 0, 0, 1, 0);
655   tab_text (t, 0, 0, TAB_CENTER | TAT_TITLE, _("Variable"));
656   tab_text (t, 1, 0, TAB_CENTER | TAT_TITLE, _("Record"));
657   tab_text (t, 2, 0, TAB_CENTER | TAT_TITLE, _("Columns"));
658   tab_text (t, 3, 0, TAB_CENTER | TAT_TITLE, _("Format"));
659   tab_box (t, TAL_1, TAL_1, TAL_0, TAL_1, 0, 0, 3, parser->field_cnt);
660   tab_hline (t, TAL_2, 0, 3, 1);
661
662   for (i = 0; i < parser->field_cnt; i++)
663     {
664       struct field *f = &parser->fields[i];
665       char fmt_string[FMT_STRING_LEN_MAX + 1];
666       int row = i + 1;
667
668       tab_text (t, 0, row, TAB_LEFT, f->name);
669       tab_text_format (t, 1, row, 0, "%d", f->record);
670       tab_text_format (t, 2, row, 0, "%3d-%3d",
671                        f->first_column, f->first_column + f->format.w - 1);
672       tab_text (t, 3, row, TAB_LEFT | TAB_FIX,
673                 fmt_to_string (&f->format, fmt_string));
674     }
675
676   tab_title (t, ngettext ("Reading %d record from %s.",
677                           "Reading %d records from %s.",
678                           parser->records_per_case),
679              parser->records_per_case, fh_get_name (fh));
680   tab_submit (t);
681 }
682
683 /* Displays a table giving information on free-format variable parsing
684    on DATA LIST. */
685 static void
686 dump_delimited_table (const struct data_parser *parser,
687                       const struct file_handle *fh)
688 {
689   struct tab_table *t;
690   size_t i;
691
692   t = tab_create (2, parser->field_cnt + 1);
693   tab_headers (t, 0, 0, 1, 0);
694   tab_text (t, 0, 0, TAB_CENTER | TAT_TITLE, _("Variable"));
695   tab_text (t, 1, 0, TAB_CENTER | TAT_TITLE, _("Format"));
696   tab_box (t, TAL_1, TAL_1, TAL_0, TAL_1, 0, 0, 1, parser->field_cnt);
697   tab_hline (t, TAL_2, 0, 1, 1);
698
699   for (i = 0; i < parser->field_cnt; i++)
700     {
701       struct field *f = &parser->fields[i];
702       char str[FMT_STRING_LEN_MAX + 1];
703       int row = i + 1;
704
705       tab_text (t, 0, row, TAB_LEFT, f->name);
706       tab_text (t, 1, row, TAB_LEFT | TAB_FIX,
707                 fmt_to_string (&f->format, str));
708     }
709
710   tab_title (t, _("Reading free-form data from %s."), fh_get_name (fh));
711
712   tab_submit (t);
713 }
714
715 /* Displays a table giving information on how PARSER will read
716    data from FH. */
717 void
718 data_parser_output_description (struct data_parser *parser,
719                                 const struct file_handle *fh)
720 {
721   if (parser->type == DP_FIXED)
722     dump_fixed_table (parser, fh);
723   else
724     dump_delimited_table (parser, fh);
725 }
726 \f
727 /* Data parser input program. */
728 struct data_parser_casereader
729   {
730     struct data_parser *parser; /* Parser. */
731     struct dfm_reader *reader;  /* Data file reader. */
732     struct caseproto *proto;    /* Format of cases. */
733   };
734
735 static const struct casereader_class data_parser_casereader_class;
736
737 /* Creates a new unnamed dataset in SESSION.  The new dataset has an input
738    program that reads data from READER according to the rules in PARSER, using
739    DICT as the underlying dictionary.  Transfers ownership of PARSER and READER
740    is to the input program, and ownership of DICT to the dataset. */
741 void
742 data_parser_make_active_file (struct data_parser *parser,
743                               struct session *session,
744                               struct dfm_reader *reader,
745                               struct dictionary *dict)
746 {
747   struct data_parser_casereader *r;
748   struct casereader *casereader;
749
750   r = xmalloc (sizeof *r);
751   r->parser = parser;
752   r->reader = reader;
753   r->proto = caseproto_ref (dict_get_proto (dict));
754   casereader = casereader_create_sequential (NULL, r->proto,
755                                              CASENUMBER_MAX,
756                                              &data_parser_casereader_class, r);
757
758   struct dataset *ds = dataset_create (session, "");
759   dataset_set_dict (ds, dict);
760   dataset_set_source (ds, casereader);
761   session_set_active_dataset (session, ds);
762 }
763
764 static struct ccase *
765 data_parser_casereader_read (struct casereader *reader UNUSED, void *r_)
766 {
767   struct data_parser_casereader *r = r_;
768   struct ccase *c = case_create (r->proto);
769   if (data_parser_parse (r->parser, r->reader, c))
770     return c;
771   else
772     {
773       case_unref (c);
774       return NULL;
775     }
776 }
777
778 static void
779 data_parser_casereader_destroy (struct casereader *reader UNUSED, void *r_)
780 {
781   struct data_parser_casereader *r = r_;
782   if (dfm_reader_error (r->reader))
783     casereader_force_error (reader);
784   data_parser_destroy (r->parser);
785   dfm_close_reader (r->reader);
786   caseproto_unref (r->proto);
787   free (r);
788 }
789
790 static const struct casereader_class data_parser_casereader_class =
791   {
792     data_parser_casereader_read,
793     data_parser_casereader_destroy,
794     NULL,
795     NULL,
796   };