1 /* PSPP - computes sample statistics.
2 Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
3 Written by Ben Pfaff <blp@gnu.org>.
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
27 #include <data/case-source.h>
28 #include <data/case.h>
29 #include <data/case-source.h>
30 #include <data/data-in.h>
31 #include <data/dictionary.h>
32 #include <data/format.h>
33 #include <data/procedure.h>
34 #include <data/settings.h>
35 #include <data/transformations.h>
36 #include <data/variable.h>
37 #include <language/command.h>
38 #include <language/data-io/data-reader.h>
39 #include <language/data-io/file-handle.h>
40 #include <language/data-io/inpt-pgm.h>
41 #include <language/lexer/lexer.h>
42 #include <language/lexer/variable-parser.h>
43 #include <libpspp/alloc.h>
44 #include <libpspp/compiler.h>
45 #include <libpspp/message.h>
46 #include <libpspp/message.h>
47 #include <libpspp/misc.h>
48 #include <libpspp/str.h>
49 #include <output/table.h>
54 #define _(msgid) gettext (msgid)
56 /* Utility function. */
58 /* Describes how to parse one variable. */
61 struct dls_var_spec *next; /* Next specification in list. */
63 /* Both free and fixed formats. */
64 struct fmt_spec input; /* Input format of this field. */
65 struct variable *v; /* Associated variable. Used only in
66 parsing. Not safe later. */
67 int fv; /* First value in case. */
69 /* Fixed format only. */
70 int rec; /* Record number (1-based). */
71 int fc, lc; /* Column numbers in record. */
73 /* Free format only. */
74 char name[LONG_NAME_LEN + 1]; /* Name of variable. */
77 /* Constants for DATA LIST type. */
78 /* Must match table in cmd_data_list(). */
86 /* DATA LIST private data structure. */
89 struct dls_var_spec *first, *last; /* Variable parsing specifications. */
90 struct dfm_reader *reader; /* Data file reader. */
92 int type; /* A DLS_* constant. */
93 struct variable *end; /* Variable specified on END subcommand. */
94 int rec_cnt; /* Number of records. */
95 size_t case_size; /* Case size in bytes. */
96 struct string delims; /* Field delimiters. */
99 static const struct case_source_class data_list_source_class;
101 static int parse_fixed (struct data_list_pgm *);
102 static int parse_free (struct dls_var_spec **, struct dls_var_spec **);
103 static void dump_fixed_table (const struct dls_var_spec *,
104 const struct file_handle *, int rec_cnt);
105 static void dump_free_table (const struct data_list_pgm *,
106 const struct file_handle *);
107 static void destroy_dls_var_spec (struct dls_var_spec *);
109 static trns_free_func data_list_trns_free;
110 static trns_proc_func data_list_trns_proc;
115 struct data_list_pgm *dls;
116 int table = -1; /* Print table if nonzero, -1=undecided. */
117 struct file_handle *fh = fh_inline_file ();
119 if (!in_input_program ())
120 discard_variables ();
122 dls = xmalloc (sizeof *dls);
127 ds_init_empty (&dls->delims);
128 dls->first = dls->last = NULL;
132 if (lex_match_id ("FILE"))
135 fh = fh_parse (FH_REF_FILE | FH_REF_INLINE);
139 else if (lex_match_id ("RECORDS"))
143 if (!lex_force_int ())
145 dls->rec_cnt = lex_integer ();
149 else if (lex_match_id ("END"))
153 msg (SE, _("The END subcommand may only be specified once."));
158 if (!lex_force_id ())
160 dls->end = dict_lookup_var (default_dict, tokid);
162 dls->end = dict_create_var_assert (default_dict, tokid, 0);
165 else if (token == T_ID)
167 if (lex_match_id ("NOTABLE"))
169 else if (lex_match_id ("TABLE"))
174 if (lex_match_id ("FIXED"))
176 else if (lex_match_id ("FREE"))
178 else if (lex_match_id ("LIST"))
188 msg (SE, _("Only one of FIXED, FREE, or LIST may "
194 if ((dls->type == DLS_FREE || dls->type == DLS_LIST)
197 while (!lex_match (')'))
201 if (lex_match_id ("TAB"))
203 else if (token == T_STRING && ds_length (&tokstr) == 1)
205 delim = ds_first (&tokstr);
214 ds_put_char (&dls->delims, delim);
228 dls->case_size = dict_get_case_size (default_dict);
229 fh_set_default_handle (fh);
232 dls->type = DLS_FIXED;
236 if (dls->type == DLS_FREE)
242 if (dls->type == DLS_FIXED)
244 if (!parse_fixed (dls))
247 dump_fixed_table (dls->first, fh, dls->rec_cnt);
251 if (!parse_free (&dls->first, &dls->last))
254 dump_free_table (dls, fh);
257 dls->reader = dfm_open_reader (fh);
258 if (dls->reader == NULL)
261 if (in_input_program ())
262 add_transformation (data_list_trns_proc, data_list_trns_free, dls);
264 proc_set_source (create_case_source (&data_list_source_class, dls));
269 data_list_trns_free (dls);
270 return CMD_CASCADING_FAILURE;
273 /* Adds SPEC to the linked list with head at FIRST and tail at
276 append_var_spec (struct dls_var_spec **first, struct dls_var_spec **last,
277 struct dls_var_spec *spec)
284 (*last)->next = spec;
288 /* Fixed-format parsing. */
290 /* Used for chaining together fortran-like format specifiers. */
293 struct fmt_list *next;
296 struct fmt_list *down;
299 /* State of parsing DATA LIST. */
300 struct fixed_parsing_state
302 char **name; /* Variable names. */
303 size_t name_cnt; /* Number of names. */
305 int recno; /* Index of current record. */
306 int sc; /* 1-based column number of starting column for
307 next field to output. */
310 static int fixed_parse_compatible (struct fixed_parsing_state *,
311 struct dls_var_spec **,
312 struct dls_var_spec **);
313 static int fixed_parse_fortran (struct fixed_parsing_state *,
314 struct dls_var_spec **,
315 struct dls_var_spec **);
317 /* Parses all the variable specifications for DATA LIST FIXED,
318 storing them into DLS. Returns nonzero if successful. */
320 parse_fixed (struct data_list_pgm *dls)
322 struct fixed_parsing_state fx;
330 while (lex_match ('/'))
333 if (lex_is_integer ())
335 if (lex_integer () < fx.recno)
337 msg (SE, _("The record number specified, %ld, is "
338 "before the previous record, %d. Data "
339 "fields must be listed in order of "
340 "increasing record number."),
341 lex_integer (), fx.recno - 1);
345 fx.recno = lex_integer ();
351 if (!parse_DATA_LIST_vars (&fx.name, &fx.name_cnt, PV_NONE))
354 if (lex_is_number ())
356 if (!fixed_parse_compatible (&fx, &dls->first, &dls->last))
359 else if (token == '(')
361 if (!fixed_parse_fortran (&fx, &dls->first, &dls->last))
366 msg (SE, _("SPSS-like or FORTRAN-like format "
367 "specification expected after variable names."));
371 for (i = 0; i < fx.name_cnt; i++)
375 if (dls->first == NULL)
377 msg (SE, _("At least one variable must be specified."));
380 if (dls->rec_cnt && dls->last->rec > dls->rec_cnt)
382 msg (SE, _("Variables are specified on records that "
383 "should not exist according to RECORDS subcommand."));
386 else if (!dls->rec_cnt)
387 dls->rec_cnt = dls->last->rec;
388 return lex_end_of_command () == CMD_SUCCESS;
391 for (i = 0; i < fx.name_cnt; i++)
397 /* Parses a variable specification in the form 1-10 (A) based on
398 FX and adds specifications to the linked list with head at
399 FIRST and tail at LAST. */
401 fixed_parse_compatible (struct fixed_parsing_state *fx,
402 struct dls_var_spec **first, struct dls_var_spec **last)
404 struct fmt_spec input;
410 if (!lex_force_int ())
415 msg (SE, _("Column positions for fields must be positive."));
421 lex_negative_to_dash ();
424 if (!lex_force_int ())
429 msg (SE, _("Column positions for fields must be positive."));
434 msg (SE, _("The ending column for a field must be "
435 "greater than the starting column."));
444 /* Divide columns evenly. */
445 input.w = (lc - fc + 1) / fx->name_cnt;
446 if ((lc - fc + 1) % fx->name_cnt)
448 msg (SE, _("The %d columns %d-%d "
449 "can't be evenly divided into %d fields."),
450 lc - fc + 1, fc, lc, fx->name_cnt);
454 /* Format specifier. */
457 struct fmt_desc *fdp;
463 input.type = parse_format_specifier_name (&cp, 0);
464 if (input.type == -1)
468 msg (SE, _("A format specifier on this line "
469 "has extra characters on the end."));
479 if (lex_is_integer ())
481 if (lex_integer () < 1)
483 msg (SE, _("The value for number of decimal places "
484 "must be at least 1."));
488 input.d = lex_integer ();
494 fdp = &formats[input.type];
495 if (fdp->n_args < 2 && input.d)
497 msg (SE, _("Input format %s doesn't accept decimal places."),
505 if (!lex_force_match (')'))
513 if (!check_input_specifier (&input, 1))
516 /* Start column for next specification. */
519 /* Width of variables to create. */
520 if (input.type == FMT_A || input.type == FMT_AHEX)
525 /* Create variables and var specs. */
526 for (i = 0; i < fx->name_cnt; i++)
528 struct dls_var_spec *spec;
531 v = dict_create_var (default_dict, fx->name[i], width);
534 convert_fmt_ItoO (&input, &v->print);
539 v = dict_lookup_var_assert (default_dict, fx->name[i]);
540 if (!in_input_program ())
542 msg (SE, _("%s is a duplicate variable name."), fx->name[i]);
545 if ((width != 0) != (v->width != 0))
547 msg (SE, _("There is already a variable %s of a "
552 if (width != 0 && width != v->width)
554 msg (SE, _("There is already a string variable %s of a "
555 "different width."), fx->name[i]);
560 spec = xmalloc (sizeof *spec);
564 spec->rec = fx->recno;
565 spec->fc = fc + input.w * i;
566 spec->lc = spec->fc + input.w - 1;
567 append_var_spec (first, last, spec);
572 /* Destroy format list F and, if RECURSE is nonzero, all its
575 destroy_fmt_list (struct fmt_list *f, int recurse)
577 struct fmt_list *next;
582 if (recurse && f->f.type == FMT_DESCEND)
583 destroy_fmt_list (f->down, 1);
588 /* Takes a hierarchically structured fmt_list F as constructed by
589 fixed_parse_fortran(), and flattens it, adding the variable
590 specifications to the linked list with head FIRST and tail
591 LAST. NAME_IDX is used to take values from the list of names
592 in FX; it should initially point to a value of 0. */
594 dump_fmt_list (struct fixed_parsing_state *fx, struct fmt_list *f,
595 struct dls_var_spec **first, struct dls_var_spec **last,
600 for (; f; f = f->next)
601 if (f->f.type == FMT_X)
603 else if (f->f.type == FMT_T)
605 else if (f->f.type == FMT_NEWREC)
607 fx->recno += f->count;
611 for (i = 0; i < f->count; i++)
612 if (f->f.type == FMT_DESCEND)
614 if (!dump_fmt_list (fx, f->down, first, last, name_idx))
619 struct dls_var_spec *spec;
623 if (formats[f->f.type].cat & FCAT_STRING)
627 if (*name_idx >= fx->name_cnt)
629 msg (SE, _("The number of format "
630 "specifications exceeds the given number of "
635 v = dict_create_var (default_dict, fx->name[(*name_idx)++], width);
638 msg (SE, _("%s is a duplicate variable name."), fx->name[i]);
642 spec = xmalloc (sizeof *spec);
646 spec->rec = fx->recno;
648 spec->lc = fx->sc + f->f.w - 1;
649 append_var_spec (first, last, spec);
651 convert_fmt_ItoO (&spec->input, &v->print);
659 /* Recursively parses a FORTRAN-like format specification into
660 the linked list with head FIRST and tail TAIL. LEVEL is the
661 level of recursion, starting from 0. Returns the parsed
662 specification if successful, or a null pointer on failure. */
663 static struct fmt_list *
664 fixed_parse_fortran_internal (struct fixed_parsing_state *fx,
665 struct dls_var_spec **first,
666 struct dls_var_spec **last)
668 struct fmt_list *head = NULL;
669 struct fmt_list *tail = NULL;
671 lex_force_match ('(');
675 struct fmt_list *new = xmalloc (sizeof *new);
678 /* Append new to list. */
686 if (lex_is_integer ())
688 new->count = lex_integer ();
694 /* Parse format specifier. */
697 new->f.type = FMT_DESCEND;
698 new->down = fixed_parse_fortran_internal (fx, first, last);
699 if (new->down == NULL)
702 else if (lex_match ('/'))
703 new->f.type = FMT_NEWREC;
704 else if (!parse_format_specifier (&new->f, FMTP_ALLOW_XT)
705 || !check_input_specifier (&new->f, 1))
710 lex_force_match (')');
715 destroy_fmt_list (head, 0);
720 /* Parses a FORTRAN-like format specification into the linked
721 list with head FIRST and tail LAST. Returns nonzero if
724 fixed_parse_fortran (struct fixed_parsing_state *fx,
725 struct dls_var_spec **first, struct dls_var_spec **last)
727 struct fmt_list *list;
730 list = fixed_parse_fortran_internal (fx, first, last);
735 dump_fmt_list (fx, list, first, last, &name_idx);
736 destroy_fmt_list (list, 1);
737 if (name_idx < fx->name_cnt)
739 msg (SE, _("There aren't enough format specifications "
740 "to match the number of variable names given."));
747 /* Displays a table giving information on fixed-format variable
748 parsing on DATA LIST. */
749 /* FIXME: The `Columns' column should be divided into three columns,
750 one for the starting column, one for the dash, one for the ending
751 column; then right-justify the starting column and left-justify the
754 dump_fixed_table (const struct dls_var_spec *specs,
755 const struct file_handle *fh, int rec_cnt)
757 const struct dls_var_spec *spec;
761 for (i = 0, spec = specs; spec; spec = spec->next)
763 t = tab_create (4, i + 1, 0);
764 tab_columns (t, TAB_COL_DOWN, 1);
765 tab_headers (t, 0, 0, 1, 0);
766 tab_text (t, 0, 0, TAB_CENTER | TAT_TITLE, _("Variable"));
767 tab_text (t, 1, 0, TAB_CENTER | TAT_TITLE, _("Record"));
768 tab_text (t, 2, 0, TAB_CENTER | TAT_TITLE, _("Columns"));
769 tab_text (t, 3, 0, TAB_CENTER | TAT_TITLE, _("Format"));
770 tab_box (t, TAL_1, TAL_1, TAL_0, TAL_1, 0, 0, 3, i);
771 tab_hline (t, TAL_2, 0, 3, 1);
772 tab_dim (t, tab_natural_dimensions);
774 for (i = 1, spec = specs; spec; spec = spec->next, i++)
776 tab_text (t, 0, i, TAB_LEFT, spec->v->name);
777 tab_text (t, 1, i, TAT_PRINTF, "%d", spec->rec);
778 tab_text (t, 2, i, TAT_PRINTF, "%3d-%3d",
780 tab_text (t, 3, i, TAB_LEFT | TAB_FIX,
781 fmt_to_string (&spec->input));
784 tab_title (t, ngettext ("Reading %d record from %s.",
785 "Reading %d records from %s.", rec_cnt),
786 rec_cnt, fh_get_name (fh));
790 /* Free-format parsing. */
792 /* Parses variable specifications for DATA LIST FREE and adds
793 them to the linked list with head FIRST and tail LAST.
794 Returns nonzero only if successful. */
796 parse_free (struct dls_var_spec **first, struct dls_var_spec **last)
801 struct fmt_spec input, output;
807 if (!parse_DATA_LIST_vars (&name, &name_cnt, PV_NONE))
812 if (!parse_format_specifier (&input, 0)
813 || !check_input_specifier (&input, 1)
814 || !lex_force_match (')'))
816 for (i = 0; i < name_cnt; i++)
821 convert_fmt_ItoO (&input, &output);
826 input = make_input_format (FMT_F, 8, 0);
827 output = *get_format ();
830 if (input.type == FMT_A || input.type == FMT_AHEX)
834 for (i = 0; i < name_cnt; i++)
836 struct dls_var_spec *spec;
839 v = dict_create_var (default_dict, name[i], width);
843 msg (SE, _("%s is a duplicate variable name."), name[i]);
846 v->print = v->write = output;
848 spec = xmalloc (sizeof *spec);
852 str_copy_trunc (spec->name, sizeof spec->name, v->name);
853 append_var_spec (first, last, spec);
855 for (i = 0; i < name_cnt; i++)
860 return lex_end_of_command () == CMD_SUCCESS;
863 /* Displays a table giving information on free-format variable parsing
866 dump_free_table (const struct data_list_pgm *dls,
867 const struct file_handle *fh)
873 struct dls_var_spec *spec;
874 for (i = 0, spec = dls->first; spec; spec = spec->next)
878 t = tab_create (2, i + 1, 0);
879 tab_columns (t, TAB_COL_DOWN, 1);
880 tab_headers (t, 0, 0, 1, 0);
881 tab_text (t, 0, 0, TAB_CENTER | TAT_TITLE, _("Variable"));
882 tab_text (t, 1, 0, TAB_CENTER | TAT_TITLE, _("Format"));
883 tab_box (t, TAL_1, TAL_1, TAL_0, TAL_1, 0, 0, 1, i);
884 tab_hline (t, TAL_2, 0, 1, 1);
885 tab_dim (t, tab_natural_dimensions);
888 struct dls_var_spec *spec;
890 for (i = 1, spec = dls->first; spec; spec = spec->next, i++)
892 tab_text (t, 0, i, TAB_LEFT, spec->v->name);
893 tab_text (t, 1, i, TAB_LEFT | TAB_FIX, fmt_to_string (&spec->input));
897 tab_title (t, _("Reading free-form data from %s."), fh_get_name (fh));
902 /* Input procedure. */
904 /* Extracts a field from the current position in the current
905 record. Fields can be unquoted or quoted with single- or
906 double-quote characters.
908 *FIELD is set to the field content. The caller must not
909 or destroy this constant string.
911 After parsing the field, sets the current position in the
912 record to just past the field and any trailing delimiter.
913 Returns 0 on failure or a 1-based column number indicating the
914 beginning of the field on success. */
916 cut_field (const struct data_list_pgm *dls, struct substring *field)
918 struct substring line, p;
920 if (dfm_eof (dls->reader))
922 if (ds_is_empty (&dls->delims))
923 dfm_expand_tabs (dls->reader);
924 line = p = dfm_get_record (dls->reader);
926 if (ds_is_empty (&dls->delims))
928 bool missing_quote = false;
930 /* Skip leading whitespace. */
931 ss_ltrim (&p, ss_cstr (CC_SPACES));
935 /* Handle actual data, whether quoted or unquoted. */
936 if (ss_match_char (&p, '\''))
937 missing_quote = !ss_get_until (&p, '\'', field);
938 else if (ss_match_char (&p, '"'))
939 missing_quote = !ss_get_until (&p, '"', field);
941 ss_get_chars (&p, ss_cspan (p, ss_cstr ("," CC_SPACES)), field);
943 msg (SW, _("Quoted string extends beyond end of line."));
945 /* Skip trailing whitespace and a single comma if present. */
946 ss_ltrim (&p, ss_cstr (CC_SPACES));
947 ss_match_char (&p, ',');
949 dfm_forward_columns (dls->reader, ss_length (line) - ss_length (p));
953 if (!ss_is_empty (p))
954 ss_get_chars (&p, ss_cspan (p, ds_ss (&dls->delims)), field);
955 else if (dfm_columns_past_end (dls->reader) == 0)
957 /* A blank line or a line that ends in a delimiter has a
958 trailing blank field. */
964 /* Advance past the field.
966 Also advance past a trailing delimiter, regardless of
967 whether one actually existed. If we "skip" a delimiter
968 that was not actually there, then we will return
969 end-of-line on our next call, which is what we want. */
970 dfm_forward_columns (dls->reader, ss_length (line) - ss_length (p) + 1);
975 static bool read_from_data_list_fixed (const struct data_list_pgm *,
977 static bool read_from_data_list_free (const struct data_list_pgm *,
979 static bool read_from_data_list_list (const struct data_list_pgm *,
982 /* Reads a case from DLS into C.
983 Returns true if successful, false at end of file or on I/O error. */
985 read_from_data_list (const struct data_list_pgm *dls, struct ccase *c)
989 dfm_push (dls->reader);
993 retval = read_from_data_list_fixed (dls, c);
996 retval = read_from_data_list_free (dls, c);
999 retval = read_from_data_list_list (dls, c);
1004 dfm_pop (dls->reader);
1009 /* Reads a case from the data file into C, parsing it according
1010 to fixed-format syntax rules in DLS.
1011 Returns true if successful, false at end of file or on I/O error. */
1013 read_from_data_list_fixed (const struct data_list_pgm *dls, struct ccase *c)
1015 struct dls_var_spec *var_spec = dls->first;
1018 if (dfm_eof (dls->reader))
1020 for (i = 1; i <= dls->rec_cnt; i++)
1022 struct substring line;
1024 if (dfm_eof (dls->reader))
1026 /* Note that this can't occur on the first record. */
1027 msg (SW, _("Partial case of %d of %d records discarded."),
1028 i - 1, dls->rec_cnt);
1031 dfm_expand_tabs (dls->reader);
1032 line = dfm_get_record (dls->reader);
1034 for (; var_spec && i == var_spec->rec; var_spec = var_spec->next)
1038 data_in_finite_line (&di, ss_data (line), ss_length (line),
1039 var_spec->fc, var_spec->lc);
1040 di.v = case_data_rw (c, var_spec->fv);
1041 di.flags = DI_IMPLIED_DECIMALS;
1042 di.f1 = var_spec->fc;
1043 di.format = var_spec->input;
1048 dfm_forward_record (dls->reader);
1054 /* Reads a case from the data file into C, parsing it according
1055 to free-format syntax rules in DLS.
1056 Returns true if successful, false at end of file or on I/O error. */
1058 read_from_data_list_free (const struct data_list_pgm *dls, struct ccase *c)
1060 struct dls_var_spec *var_spec;
1062 for (var_spec = dls->first; var_spec; var_spec = var_spec->next)
1064 struct substring field;
1067 /* Cut out a field and read in a new record if necessary. */
1068 while (!cut_field (dls, &field))
1070 if (!dfm_eof (dls->reader))
1071 dfm_forward_record (dls->reader);
1072 if (dfm_eof (dls->reader))
1074 if (var_spec != dls->first)
1075 msg (SW, _("Partial case discarded. The first variable "
1076 "missing was %s."), var_spec->name);
1081 di.s = ss_data (field);
1082 di.e = ss_end (field);
1083 di.v = case_data_rw (c, var_spec->fv);
1085 di.f1 = dfm_get_column (dls->reader, ss_data (field));
1086 di.format = var_spec->input;
1092 /* Reads a case from the data file and parses it according to
1093 list-format syntax rules.
1094 Returns true if successful, false at end of file or on I/O error. */
1096 read_from_data_list_list (const struct data_list_pgm *dls, struct ccase *c)
1098 struct dls_var_spec *var_spec;
1100 if (dfm_eof (dls->reader))
1103 for (var_spec = dls->first; var_spec; var_spec = var_spec->next)
1105 struct substring field;
1108 if (!cut_field (dls, &field))
1110 if (get_undefined ())
1111 msg (SW, _("Missing value(s) for all variables from %s onward. "
1112 "These will be filled with the system-missing value "
1113 "or blanks, as appropriate."),
1115 for (; var_spec; var_spec = var_spec->next)
1117 int width = get_format_var_width (&var_spec->input);
1119 case_data_rw (c, var_spec->fv)->f = SYSMIS;
1121 memset (case_data_rw (c, var_spec->fv)->s, ' ', width);
1126 di.s = ss_data (field);
1127 di.e = ss_end (field);
1128 di.v = case_data_rw (c, var_spec->fv);
1130 di.f1 = dfm_get_column (dls->reader, ss_data (field));
1131 di.format = var_spec->input;
1135 dfm_forward_record (dls->reader);
1139 /* Destroys SPEC. */
1141 destroy_dls_var_spec (struct dls_var_spec *spec)
1143 struct dls_var_spec *next;
1145 while (spec != NULL)
1153 /* Destroys DATA LIST transformation DLS.
1154 Returns true if successful, false if an I/O error occurred. */
1156 data_list_trns_free (void *dls_)
1158 struct data_list_pgm *dls = dls_;
1159 ds_destroy (&dls->delims);
1160 destroy_dls_var_spec (dls->first);
1161 dfm_close_reader (dls->reader);
1166 /* Handle DATA LIST transformation DLS, parsing data into C. */
1168 data_list_trns_proc (void *dls_, struct ccase *c, int case_num UNUSED)
1170 struct data_list_pgm *dls = dls_;
1173 if (read_from_data_list (dls, c))
1174 retval = TRNS_CONTINUE;
1175 else if (dfm_reader_error (dls->reader) || dfm_eof (dls->reader) > 1)
1177 /* An I/O error, or encountering end of file for a second
1178 time, should be escalated into a more serious error. */
1179 retval = TRNS_ERROR;
1182 retval = TRNS_END_FILE;
1184 /* If there was an END subcommand handle it. */
1185 if (dls->end != NULL)
1187 double *end = &case_data_rw (c, dls->end->fv)->f;
1188 if (retval == TRNS_DROP_CASE)
1191 retval = TRNS_END_FILE;
1200 /* Reads all the records from the data file and passes them to
1202 Returns true if successful, false if an I/O error occurred. */
1204 data_list_source_read (struct case_source *source,
1206 write_case_func *write_case, write_case_data wc_data)
1208 struct data_list_pgm *dls = source->aux;
1214 if (!read_from_data_list (dls, c))
1215 return !dfm_reader_error (dls->reader);
1217 dfm_push (dls->reader);
1218 ok = write_case (wc_data);
1219 dfm_pop (dls->reader);
1225 /* Destroys the source's internal data. */
1227 data_list_source_destroy (struct case_source *source)
1229 data_list_trns_free (source->aux);
1232 static const struct case_source_class data_list_source_class =
1236 data_list_source_read,
1237 data_list_source_destroy,