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