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/assertion.h>
45 #include <libpspp/compiler.h>
46 #include <libpspp/message.h>
47 #include <libpspp/message.h>
48 #include <libpspp/misc.h>
49 #include <libpspp/str.h>
50 #include <output/table.h>
55 #define _(msgid) gettext (msgid)
57 /* Utility function. */
59 /* Describes how to parse one variable. */
62 struct dls_var_spec *next; /* Next specification in list. */
64 /* Both free and fixed formats. */
65 struct fmt_spec input; /* Input format of this field. */
66 struct variable *v; /* Associated variable. Used only in
67 parsing. Not safe later. */
68 int fv; /* First value in case. */
70 /* Fixed format only. */
71 int rec; /* Record number (1-based). */
72 int fc, lc; /* Column numbers in record. */
74 /* Free format only. */
75 char name[LONG_NAME_LEN + 1]; /* Name of variable. */
78 /* Constants for DATA LIST type. */
79 /* Must match table in cmd_data_list(). */
87 /* DATA LIST private data structure. */
90 struct dls_var_spec *first, *last; /* Variable parsing specifications. */
91 struct dfm_reader *reader; /* Data file reader. */
93 int type; /* A DLS_* constant. */
94 struct variable *end; /* Variable specified on END subcommand. */
95 int rec_cnt; /* Number of records. */
96 size_t case_size; /* Case size in bytes. */
97 struct string delims; /* Field delimiters. */
100 static const struct case_source_class data_list_source_class;
102 static int parse_fixed (struct data_list_pgm *);
103 static int parse_free (struct dls_var_spec **, struct dls_var_spec **);
104 static void dump_fixed_table (const struct dls_var_spec *,
105 const struct file_handle *, int rec_cnt);
106 static void dump_free_table (const struct data_list_pgm *,
107 const struct file_handle *);
108 static void destroy_dls_var_spec (struct dls_var_spec *);
110 static trns_free_func data_list_trns_free;
111 static trns_proc_func data_list_trns_proc;
116 struct data_list_pgm *dls;
117 int table = -1; /* Print table if nonzero, -1=undecided. */
118 struct file_handle *fh = fh_inline_file ();
120 if (!in_input_program ())
121 discard_variables ();
123 dls = xmalloc (sizeof *dls);
128 ds_init_empty (&dls->delims);
129 dls->first = dls->last = NULL;
133 if (lex_match_id ("FILE"))
136 fh = fh_parse (FH_REF_FILE | FH_REF_INLINE);
140 else if (lex_match_id ("RECORDS"))
144 if (!lex_force_int ())
146 dls->rec_cnt = lex_integer ();
150 else if (lex_match_id ("END"))
154 msg (SE, _("The END subcommand may only be specified once."));
159 if (!lex_force_id ())
161 dls->end = dict_lookup_var (default_dict, tokid);
163 dls->end = dict_create_var_assert (default_dict, tokid, 0);
166 else if (token == T_ID)
168 if (lex_match_id ("NOTABLE"))
170 else if (lex_match_id ("TABLE"))
175 if (lex_match_id ("FIXED"))
177 else if (lex_match_id ("FREE"))
179 else if (lex_match_id ("LIST"))
189 msg (SE, _("Only one of FIXED, FREE, or LIST may "
195 if ((dls->type == DLS_FREE || dls->type == DLS_LIST)
198 while (!lex_match (')'))
202 if (lex_match_id ("TAB"))
204 else if (token == T_STRING && ds_length (&tokstr) == 1)
206 delim = ds_first (&tokstr);
215 ds_put_char (&dls->delims, delim);
229 dls->case_size = dict_get_case_size (default_dict);
230 fh_set_default_handle (fh);
233 dls->type = DLS_FIXED;
237 if (dls->type == DLS_FREE)
243 if (dls->type == DLS_FIXED)
245 if (!parse_fixed (dls))
248 dump_fixed_table (dls->first, fh, dls->rec_cnt);
252 if (!parse_free (&dls->first, &dls->last))
255 dump_free_table (dls, fh);
258 dls->reader = dfm_open_reader (fh);
259 if (dls->reader == NULL)
262 if (in_input_program ())
263 add_transformation (data_list_trns_proc, data_list_trns_free, dls);
265 proc_set_source (create_case_source (&data_list_source_class, dls));
270 data_list_trns_free (dls);
271 return CMD_CASCADING_FAILURE;
274 /* Adds SPEC to the linked list with head at FIRST and tail at
277 append_var_spec (struct dls_var_spec **first, struct dls_var_spec **last,
278 struct dls_var_spec *spec)
285 (*last)->next = spec;
289 /* Fixed-format parsing. */
291 /* Used for chaining together fortran-like format specifiers. */
294 struct fmt_list *next;
297 struct fmt_list *down;
300 /* State of parsing DATA LIST. */
301 struct fixed_parsing_state
303 char **name; /* Variable names. */
304 size_t name_cnt; /* Number of names. */
306 int recno; /* Index of current record. */
307 int sc; /* 1-based column number of starting column for
308 next field to output. */
311 static int fixed_parse_compatible (struct fixed_parsing_state *,
312 struct dls_var_spec **,
313 struct dls_var_spec **);
314 static int fixed_parse_fortran (struct fixed_parsing_state *,
315 struct dls_var_spec **,
316 struct dls_var_spec **);
318 /* Parses all the variable specifications for DATA LIST FIXED,
319 storing them into DLS. Returns nonzero if successful. */
321 parse_fixed (struct data_list_pgm *dls)
323 struct fixed_parsing_state fx;
331 while (lex_match ('/'))
334 if (lex_is_integer ())
336 if (lex_integer () < fx.recno)
338 msg (SE, _("The record number specified, %ld, is "
339 "before the previous record, %d. Data "
340 "fields must be listed in order of "
341 "increasing record number."),
342 lex_integer (), fx.recno - 1);
346 fx.recno = lex_integer ();
352 if (!parse_DATA_LIST_vars (&fx.name, &fx.name_cnt, PV_NONE))
355 if (lex_is_number ())
357 if (!fixed_parse_compatible (&fx, &dls->first, &dls->last))
360 else if (token == '(')
362 if (!fixed_parse_fortran (&fx, &dls->first, &dls->last))
367 msg (SE, _("SPSS-like or FORTRAN-like format "
368 "specification expected after variable names."));
372 for (i = 0; i < fx.name_cnt; i++)
376 if (dls->first == NULL)
378 msg (SE, _("At least one variable must be specified."));
381 if (dls->rec_cnt && dls->last->rec > dls->rec_cnt)
383 msg (SE, _("Variables are specified on records that "
384 "should not exist according to RECORDS subcommand."));
387 else if (!dls->rec_cnt)
388 dls->rec_cnt = dls->last->rec;
389 return lex_end_of_command () == CMD_SUCCESS;
392 for (i = 0; i < fx.name_cnt; i++)
398 /* Parses a variable specification in the form 1-10 (A) based on
399 FX and adds specifications to the linked list with head at
400 FIRST and tail at LAST. */
402 fixed_parse_compatible (struct fixed_parsing_state *fx,
403 struct dls_var_spec **first, struct dls_var_spec **last)
405 struct fmt_spec input;
411 if (!lex_force_int ())
416 msg (SE, _("Column positions for fields must be positive."));
422 lex_negative_to_dash ();
425 if (!lex_force_int ())
430 msg (SE, _("Column positions for fields must be positive."));
435 msg (SE, _("The ending column for a field must be "
436 "greater than the starting column."));
445 /* Divide columns evenly. */
446 input.w = (lc - fc + 1) / fx->name_cnt;
447 if ((lc - fc + 1) % fx->name_cnt)
449 msg (SE, _("The %d columns %d-%d "
450 "can't be evenly divided into %d fields."),
451 lc - fc + 1, fc, lc, fx->name_cnt);
455 /* Format specifier. */
458 struct fmt_desc *fdp;
464 input.type = parse_format_specifier_name (&cp, 0);
465 if (input.type == -1)
469 msg (SE, _("A format specifier on this line "
470 "has extra characters on the end."));
480 if (lex_is_integer ())
482 if (lex_integer () < 1)
484 msg (SE, _("The value for number of decimal places "
485 "must be at least 1."));
489 input.d = lex_integer ();
495 fdp = &formats[input.type];
496 if (fdp->n_args < 2 && input.d)
498 msg (SE, _("Input format %s doesn't accept decimal places."),
506 if (!lex_force_match (')'))
514 if (!check_input_specifier (&input, 1))
517 /* Start column for next specification. */
520 /* Width of variables to create. */
521 if (input.type == FMT_A || input.type == FMT_AHEX)
526 /* Create variables and var specs. */
527 for (i = 0; i < fx->name_cnt; i++)
529 struct dls_var_spec *spec;
532 v = dict_create_var (default_dict, fx->name[i], width);
535 convert_fmt_ItoO (&input, &v->print);
540 v = dict_lookup_var_assert (default_dict, fx->name[i]);
541 if (!in_input_program ())
543 msg (SE, _("%s is a duplicate variable name."), fx->name[i]);
546 if ((width != 0) != (v->width != 0))
548 msg (SE, _("There is already a variable %s of a "
553 if (width != 0 && width != v->width)
555 msg (SE, _("There is already a string variable %s of a "
556 "different width."), fx->name[i]);
561 spec = xmalloc (sizeof *spec);
565 spec->rec = fx->recno;
566 spec->fc = fc + input.w * i;
567 spec->lc = spec->fc + input.w - 1;
568 append_var_spec (first, last, spec);
573 /* Destroy format list F and, if RECURSE is nonzero, all its
576 destroy_fmt_list (struct fmt_list *f, int recurse)
578 struct fmt_list *next;
583 if (recurse && f->f.type == FMT_DESCEND)
584 destroy_fmt_list (f->down, 1);
589 /* Takes a hierarchically structured fmt_list F as constructed by
590 fixed_parse_fortran(), and flattens it, adding the variable
591 specifications to the linked list with head FIRST and tail
592 LAST. NAME_IDX is used to take values from the list of names
593 in FX; it should initially point to a value of 0. */
595 dump_fmt_list (struct fixed_parsing_state *fx, struct fmt_list *f,
596 struct dls_var_spec **first, struct dls_var_spec **last,
601 for (; f; f = f->next)
602 if (f->f.type == FMT_X)
604 else if (f->f.type == FMT_T)
606 else if (f->f.type == FMT_NEWREC)
608 fx->recno += f->count;
612 for (i = 0; i < f->count; i++)
613 if (f->f.type == FMT_DESCEND)
615 if (!dump_fmt_list (fx, f->down, first, last, name_idx))
620 struct dls_var_spec *spec;
624 if (formats[f->f.type].cat & FCAT_STRING)
628 if (*name_idx >= fx->name_cnt)
630 msg (SE, _("The number of format "
631 "specifications exceeds the given number of "
636 v = dict_create_var (default_dict, fx->name[(*name_idx)++], width);
639 msg (SE, _("%s is a duplicate variable name."), fx->name[i]);
643 spec = xmalloc (sizeof *spec);
647 spec->rec = fx->recno;
649 spec->lc = fx->sc + f->f.w - 1;
650 append_var_spec (first, last, spec);
652 convert_fmt_ItoO (&spec->input, &v->print);
660 /* Recursively parses a FORTRAN-like format specification into
661 the linked list with head FIRST and tail TAIL. LEVEL is the
662 level of recursion, starting from 0. Returns the parsed
663 specification if successful, or a null pointer on failure. */
664 static struct fmt_list *
665 fixed_parse_fortran_internal (struct fixed_parsing_state *fx,
666 struct dls_var_spec **first,
667 struct dls_var_spec **last)
669 struct fmt_list *head = NULL;
670 struct fmt_list *tail = NULL;
672 lex_force_match ('(');
676 struct fmt_list *new = xmalloc (sizeof *new);
679 /* Append new to list. */
687 if (lex_is_integer ())
689 new->count = lex_integer ();
695 /* Parse format specifier. */
698 new->f.type = FMT_DESCEND;
699 new->down = fixed_parse_fortran_internal (fx, first, last);
700 if (new->down == NULL)
703 else if (lex_match ('/'))
704 new->f.type = FMT_NEWREC;
705 else if (!parse_format_specifier (&new->f, FMTP_ALLOW_XT)
706 || !check_input_specifier (&new->f, 1))
711 lex_force_match (')');
716 destroy_fmt_list (head, 0);
721 /* Parses a FORTRAN-like format specification into the linked
722 list with head FIRST and tail LAST. Returns nonzero if
725 fixed_parse_fortran (struct fixed_parsing_state *fx,
726 struct dls_var_spec **first, struct dls_var_spec **last)
728 struct fmt_list *list;
731 list = fixed_parse_fortran_internal (fx, first, last);
736 dump_fmt_list (fx, list, first, last, &name_idx);
737 destroy_fmt_list (list, 1);
738 if (name_idx < fx->name_cnt)
740 msg (SE, _("There aren't enough format specifications "
741 "to match the number of variable names given."));
748 /* Displays a table giving information on fixed-format variable
749 parsing on DATA LIST. */
750 /* FIXME: The `Columns' column should be divided into three columns,
751 one for the starting column, one for the dash, one for the ending
752 column; then right-justify the starting column and left-justify the
755 dump_fixed_table (const struct dls_var_spec *specs,
756 const struct file_handle *fh, int rec_cnt)
758 const struct dls_var_spec *spec;
762 for (i = 0, spec = specs; spec; spec = spec->next)
764 t = tab_create (4, i + 1, 0);
765 tab_columns (t, TAB_COL_DOWN, 1);
766 tab_headers (t, 0, 0, 1, 0);
767 tab_text (t, 0, 0, TAB_CENTER | TAT_TITLE, _("Variable"));
768 tab_text (t, 1, 0, TAB_CENTER | TAT_TITLE, _("Record"));
769 tab_text (t, 2, 0, TAB_CENTER | TAT_TITLE, _("Columns"));
770 tab_text (t, 3, 0, TAB_CENTER | TAT_TITLE, _("Format"));
771 tab_box (t, TAL_1, TAL_1, TAL_0, TAL_1, 0, 0, 3, i);
772 tab_hline (t, TAL_2, 0, 3, 1);
773 tab_dim (t, tab_natural_dimensions);
775 for (i = 1, spec = specs; spec; spec = spec->next, i++)
777 tab_text (t, 0, i, TAB_LEFT, spec->v->name);
778 tab_text (t, 1, i, TAT_PRINTF, "%d", spec->rec);
779 tab_text (t, 2, i, TAT_PRINTF, "%3d-%3d",
781 tab_text (t, 3, i, TAB_LEFT | TAB_FIX,
782 fmt_to_string (&spec->input));
785 tab_title (t, ngettext ("Reading %d record from %s.",
786 "Reading %d records from %s.", rec_cnt),
787 rec_cnt, fh_get_name (fh));
791 /* Free-format parsing. */
793 /* Parses variable specifications for DATA LIST FREE and adds
794 them to the linked list with head FIRST and tail LAST.
795 Returns nonzero only if successful. */
797 parse_free (struct dls_var_spec **first, struct dls_var_spec **last)
802 struct fmt_spec input, output;
808 if (!parse_DATA_LIST_vars (&name, &name_cnt, PV_NONE))
813 if (!parse_format_specifier (&input, 0)
814 || !check_input_specifier (&input, 1)
815 || !lex_force_match (')'))
817 for (i = 0; i < name_cnt; i++)
822 convert_fmt_ItoO (&input, &output);
827 input = make_input_format (FMT_F, 8, 0);
828 output = *get_format ();
831 if (input.type == FMT_A || input.type == FMT_AHEX)
835 for (i = 0; i < name_cnt; i++)
837 struct dls_var_spec *spec;
840 v = dict_create_var (default_dict, name[i], width);
844 msg (SE, _("%s is a duplicate variable name."), name[i]);
847 v->print = v->write = output;
849 spec = xmalloc (sizeof *spec);
853 str_copy_trunc (spec->name, sizeof spec->name, v->name);
854 append_var_spec (first, last, spec);
856 for (i = 0; i < name_cnt; i++)
861 return lex_end_of_command () == CMD_SUCCESS;
864 /* Displays a table giving information on free-format variable parsing
867 dump_free_table (const struct data_list_pgm *dls,
868 const struct file_handle *fh)
874 struct dls_var_spec *spec;
875 for (i = 0, spec = dls->first; spec; spec = spec->next)
879 t = tab_create (2, i + 1, 0);
880 tab_columns (t, TAB_COL_DOWN, 1);
881 tab_headers (t, 0, 0, 1, 0);
882 tab_text (t, 0, 0, TAB_CENTER | TAT_TITLE, _("Variable"));
883 tab_text (t, 1, 0, TAB_CENTER | TAT_TITLE, _("Format"));
884 tab_box (t, TAL_1, TAL_1, TAL_0, TAL_1, 0, 0, 1, i);
885 tab_hline (t, TAL_2, 0, 1, 1);
886 tab_dim (t, tab_natural_dimensions);
889 struct dls_var_spec *spec;
891 for (i = 1, spec = dls->first; spec; spec = spec->next, i++)
893 tab_text (t, 0, i, TAB_LEFT, spec->v->name);
894 tab_text (t, 1, i, TAB_LEFT | TAB_FIX, fmt_to_string (&spec->input));
898 tab_title (t, _("Reading free-form data from %s."), fh_get_name (fh));
903 /* Input procedure. */
905 /* Extracts a field from the current position in the current
906 record. Fields can be unquoted or quoted with single- or
907 double-quote characters.
909 *FIELD is set to the field content. The caller must not
910 or destroy this constant string.
912 After parsing the field, sets the current position in the
913 record to just past the field and any trailing delimiter.
914 Returns 0 on failure or a 1-based column number indicating the
915 beginning of the field on success. */
917 cut_field (const struct data_list_pgm *dls, struct substring *field)
919 struct substring line, p;
921 if (dfm_eof (dls->reader))
923 if (ds_is_empty (&dls->delims))
924 dfm_expand_tabs (dls->reader);
925 line = p = dfm_get_record (dls->reader);
927 if (ds_is_empty (&dls->delims))
929 bool missing_quote = false;
931 /* Skip leading whitespace. */
932 ss_ltrim (&p, ss_cstr (CC_SPACES));
936 /* Handle actual data, whether quoted or unquoted. */
937 if (ss_match_char (&p, '\''))
938 missing_quote = !ss_get_until (&p, '\'', field);
939 else if (ss_match_char (&p, '"'))
940 missing_quote = !ss_get_until (&p, '"', field);
942 ss_get_chars (&p, ss_cspan (p, ss_cstr ("," CC_SPACES)), field);
944 msg (SW, _("Quoted string extends beyond end of line."));
946 /* Skip trailing whitespace and a single comma if present. */
947 ss_ltrim (&p, ss_cstr (CC_SPACES));
948 ss_match_char (&p, ',');
950 dfm_forward_columns (dls->reader, ss_length (line) - ss_length (p));
954 if (!ss_is_empty (p))
955 ss_get_chars (&p, ss_cspan (p, ds_ss (&dls->delims)), field);
956 else if (dfm_columns_past_end (dls->reader) == 0)
958 /* A blank line or a line that ends in a delimiter has a
959 trailing blank field. */
965 /* Advance past the field.
967 Also advance past a trailing delimiter, regardless of
968 whether one actually existed. If we "skip" a delimiter
969 that was not actually there, then we will return
970 end-of-line on our next call, which is what we want. */
971 dfm_forward_columns (dls->reader, ss_length (line) - ss_length (p) + 1);
976 static bool read_from_data_list_fixed (const struct data_list_pgm *,
978 static bool read_from_data_list_free (const struct data_list_pgm *,
980 static bool read_from_data_list_list (const struct data_list_pgm *,
983 /* Reads a case from DLS into C.
984 Returns true if successful, false at end of file or on I/O error. */
986 read_from_data_list (const struct data_list_pgm *dls, struct ccase *c)
990 dfm_push (dls->reader);
994 retval = read_from_data_list_fixed (dls, c);
997 retval = read_from_data_list_free (dls, c);
1000 retval = read_from_data_list_list (dls, c);
1005 dfm_pop (dls->reader);
1010 /* Reads a case from the data file into C, parsing it according
1011 to fixed-format syntax rules in DLS.
1012 Returns true if successful, false at end of file or on I/O error. */
1014 read_from_data_list_fixed (const struct data_list_pgm *dls, struct ccase *c)
1016 struct dls_var_spec *var_spec = dls->first;
1019 if (dfm_eof (dls->reader))
1021 for (i = 1; i <= dls->rec_cnt; i++)
1023 struct substring line;
1025 if (dfm_eof (dls->reader))
1027 /* Note that this can't occur on the first record. */
1028 msg (SW, _("Partial case of %d of %d records discarded."),
1029 i - 1, dls->rec_cnt);
1032 dfm_expand_tabs (dls->reader);
1033 line = dfm_get_record (dls->reader);
1035 for (; var_spec && i == var_spec->rec; var_spec = var_spec->next)
1039 data_in_finite_line (&di, ss_data (line), ss_length (line),
1040 var_spec->fc, var_spec->lc);
1041 di.v = case_data_rw (c, var_spec->fv);
1042 di.flags = DI_IMPLIED_DECIMALS;
1043 di.f1 = var_spec->fc;
1044 di.format = var_spec->input;
1049 dfm_forward_record (dls->reader);
1055 /* Reads a case from the data file into C, parsing it according
1056 to free-format syntax rules in DLS.
1057 Returns true if successful, false at end of file or on I/O error. */
1059 read_from_data_list_free (const struct data_list_pgm *dls, struct ccase *c)
1061 struct dls_var_spec *var_spec;
1063 for (var_spec = dls->first; var_spec; var_spec = var_spec->next)
1065 struct substring field;
1068 /* Cut out a field and read in a new record if necessary. */
1069 while (!cut_field (dls, &field))
1071 if (!dfm_eof (dls->reader))
1072 dfm_forward_record (dls->reader);
1073 if (dfm_eof (dls->reader))
1075 if (var_spec != dls->first)
1076 msg (SW, _("Partial case discarded. The first variable "
1077 "missing was %s."), var_spec->name);
1082 di.s = ss_data (field);
1083 di.e = ss_end (field);
1084 di.v = case_data_rw (c, var_spec->fv);
1086 di.f1 = dfm_get_column (dls->reader, ss_data (field));
1087 di.format = var_spec->input;
1093 /* Reads a case from the data file and parses it according to
1094 list-format syntax rules.
1095 Returns true if successful, false at end of file or on I/O error. */
1097 read_from_data_list_list (const struct data_list_pgm *dls, struct ccase *c)
1099 struct dls_var_spec *var_spec;
1101 if (dfm_eof (dls->reader))
1104 for (var_spec = dls->first; var_spec; var_spec = var_spec->next)
1106 struct substring field;
1109 if (!cut_field (dls, &field))
1111 if (get_undefined ())
1112 msg (SW, _("Missing value(s) for all variables from %s onward. "
1113 "These will be filled with the system-missing value "
1114 "or blanks, as appropriate."),
1116 for (; var_spec; var_spec = var_spec->next)
1118 int width = get_format_var_width (&var_spec->input);
1120 case_data_rw (c, var_spec->fv)->f = SYSMIS;
1122 memset (case_data_rw (c, var_spec->fv)->s, ' ', width);
1127 di.s = ss_data (field);
1128 di.e = ss_end (field);
1129 di.v = case_data_rw (c, var_spec->fv);
1131 di.f1 = dfm_get_column (dls->reader, ss_data (field));
1132 di.format = var_spec->input;
1136 dfm_forward_record (dls->reader);
1140 /* Destroys SPEC. */
1142 destroy_dls_var_spec (struct dls_var_spec *spec)
1144 struct dls_var_spec *next;
1146 while (spec != NULL)
1154 /* Destroys DATA LIST transformation DLS.
1155 Returns true if successful, false if an I/O error occurred. */
1157 data_list_trns_free (void *dls_)
1159 struct data_list_pgm *dls = dls_;
1160 ds_destroy (&dls->delims);
1161 destroy_dls_var_spec (dls->first);
1162 dfm_close_reader (dls->reader);
1167 /* Handle DATA LIST transformation DLS, parsing data into C. */
1169 data_list_trns_proc (void *dls_, struct ccase *c, int case_num UNUSED)
1171 struct data_list_pgm *dls = dls_;
1174 if (read_from_data_list (dls, c))
1175 retval = TRNS_CONTINUE;
1176 else if (dfm_reader_error (dls->reader) || dfm_eof (dls->reader) > 1)
1178 /* An I/O error, or encountering end of file for a second
1179 time, should be escalated into a more serious error. */
1180 retval = TRNS_ERROR;
1183 retval = TRNS_END_FILE;
1185 /* If there was an END subcommand handle it. */
1186 if (dls->end != NULL)
1188 double *end = &case_data_rw (c, dls->end->fv)->f;
1189 if (retval == TRNS_DROP_CASE)
1192 retval = TRNS_END_FILE;
1201 /* Reads all the records from the data file and passes them to
1203 Returns true if successful, false if an I/O error occurred. */
1205 data_list_source_read (struct case_source *source,
1207 write_case_func *write_case, write_case_data wc_data)
1209 struct data_list_pgm *dls = source->aux;
1215 if (!read_from_data_list (dls, c))
1216 return !dfm_reader_error (dls->reader);
1218 dfm_push (dls->reader);
1219 ok = write_case (wc_data);
1220 dfm_pop (dls->reader);
1226 /* Destroys the source's internal data. */
1228 data_list_source_destroy (struct case_source *source)
1230 data_list_trns_free (source->aux);
1233 static const struct case_source_class data_list_source_class =
1237 data_list_source_read,
1238 data_list_source_destroy,