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 <libpspp/alloc.h>
43 #include <libpspp/compiler.h>
44 #include <libpspp/message.h>
45 #include <libpspp/message.h>
46 #include <libpspp/misc.h>
47 #include <libpspp/str.h>
48 #include <output/table.h>
51 #define _(msgid) gettext (msgid)
53 /* Utility function. */
55 /* Describes how to parse one variable. */
58 struct dls_var_spec *next; /* Next specification in list. */
60 /* Both free and fixed formats. */
61 struct fmt_spec input; /* Input format of this field. */
62 struct variable *v; /* Associated variable. Used only in
63 parsing. Not safe later. */
64 int fv; /* First value in case. */
66 /* Fixed format only. */
67 int rec; /* Record number (1-based). */
68 int fc, lc; /* Column numbers in record. */
70 /* Free format only. */
71 char name[LONG_NAME_LEN + 1]; /* Name of variable. */
74 /* Constants for DATA LIST type. */
75 /* Must match table in cmd_data_list(). */
83 /* DATA LIST private data structure. */
86 struct dls_var_spec *first, *last; /* Variable parsing specifications. */
87 struct dfm_reader *reader; /* Data file reader. */
89 int type; /* A DLS_* constant. */
90 struct variable *end; /* Variable specified on END subcommand. */
91 int rec_cnt; /* Number of records. */
92 size_t case_size; /* Case size in bytes. */
93 char *delims; /* Delimiters if any; not null-terminated. */
94 size_t delim_cnt; /* Number of delimiter, or 0 for spaces. */
97 static const struct case_source_class data_list_source_class;
99 static int parse_fixed (struct data_list_pgm *);
100 static int parse_free (struct dls_var_spec **, struct dls_var_spec **);
101 static void dump_fixed_table (const struct dls_var_spec *,
102 const struct file_handle *, int rec_cnt);
103 static void dump_free_table (const struct data_list_pgm *,
104 const struct file_handle *);
105 static void destroy_dls_var_spec (struct dls_var_spec *);
107 static trns_free_func data_list_trns_free;
108 static trns_proc_func data_list_trns_proc;
113 struct data_list_pgm *dls;
114 int table = -1; /* Print table if nonzero, -1=undecided. */
115 struct file_handle *fh = fh_inline_file ();
117 if (!in_input_program ())
118 discard_variables ();
120 dls = xmalloc (sizeof *dls);
127 dls->first = dls->last = NULL;
131 if (lex_match_id ("FILE"))
134 fh = fh_parse (FH_REF_FILE | FH_REF_INLINE);
138 else if (lex_match_id ("RECORDS"))
142 if (!lex_force_int ())
144 dls->rec_cnt = lex_integer ();
148 else if (lex_match_id ("END"))
152 msg (SE, _("The END subcommand may only be specified once."));
157 if (!lex_force_id ())
159 dls->end = dict_lookup_var (default_dict, tokid);
161 dls->end = dict_create_var_assert (default_dict, tokid, 0);
164 else if (token == T_ID)
166 if (lex_match_id ("NOTABLE"))
168 else if (lex_match_id ("TABLE"))
173 if (lex_match_id ("FIXED"))
175 else if (lex_match_id ("FREE"))
177 else if (lex_match_id ("LIST"))
187 msg (SE, _("Only one of FIXED, FREE, or LIST may "
193 if ((dls->type == DLS_FREE || dls->type == DLS_LIST)
196 while (!lex_match (')'))
200 if (lex_match_id ("TAB"))
202 else if (token == T_STRING && tokstr.length == 1)
204 delim = tokstr.string[0];
213 dls->delims = xrealloc (dls->delims, dls->delim_cnt + 1);
214 dls->delims[dls->delim_cnt++] = 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. *FIELD is set to the field content.
907 After parsing the field, sets the current position in the
908 record to just past the field and any trailing delimiter.
909 END_BLANK is used internally; it should be initialized by the
910 caller to 0 and left alone afterward. Returns 0 on failure or
911 a 1-based column number indicating the beginning of the field
914 cut_field (const struct data_list_pgm *dls, struct fixed_string *field,
917 struct fixed_string line;
921 if (dfm_eof (dls->reader))
923 if (dls->delim_cnt == 0)
924 dfm_expand_tabs (dls->reader);
925 dfm_get_record (dls->reader, &line);
927 cp = ls_c_str (&line);
928 if (dls->delim_cnt == 0)
930 /* Skip leading whitespace. */
931 while (cp < ls_end (&line) && isspace ((unsigned char) *cp))
933 if (cp >= ls_end (&line))
936 /* Handle actual data, whether quoted or unquoted. */
937 if (*cp == '\'' || *cp == '"')
941 field->string = ++cp;
942 while (cp < ls_end (&line) && *cp != quote)
944 field->length = cp - field->string;
945 if (cp < ls_end (&line))
948 msg (SW, _("Quoted string missing terminating `%c'."), quote);
953 while (cp < ls_end (&line)
954 && !isspace ((unsigned char) *cp) && *cp != ',')
956 field->length = cp - field->string;
959 /* Skip trailing whitespace and a single comma if present. */
960 while (cp < ls_end (&line) && isspace ((unsigned char) *cp))
962 if (cp < ls_end (&line) && *cp == ',')
967 if (cp >= ls_end (&line))
969 int column = dfm_column_start (dls->reader);
970 /* A blank line or a line that ends in \t has a
971 trailing blank field. */
972 if (column == 1 || (column > 1 && cp[-1] == '\t'))
977 field->string = ls_end (&line);
979 dfm_forward_record (dls->reader);
994 while (cp < ls_end (&line)
995 && memchr (dls->delims, *cp, dls->delim_cnt) == NULL)
997 field->length = cp - field->string;
998 if (cp < ls_end (&line))
1003 dfm_forward_columns (dls->reader, field->string - line.string);
1004 column_start = dfm_column_start (dls->reader);
1006 dfm_forward_columns (dls->reader, cp - field->string);
1008 return column_start;
1011 static bool read_from_data_list_fixed (const struct data_list_pgm *,
1013 static bool read_from_data_list_free (const struct data_list_pgm *,
1015 static bool read_from_data_list_list (const struct data_list_pgm *,
1018 /* Reads a case from DLS into C.
1019 Returns true if successful, false at end of file or on I/O error. */
1021 read_from_data_list (const struct data_list_pgm *dls, struct ccase *c)
1025 dfm_push (dls->reader);
1029 retval = read_from_data_list_fixed (dls, c);
1032 retval = read_from_data_list_free (dls, c);
1035 retval = read_from_data_list_list (dls, c);
1040 dfm_pop (dls->reader);
1045 /* Reads a case from the data file into C, parsing it according
1046 to fixed-format syntax rules in DLS.
1047 Returns true if successful, false at end of file or on I/O error. */
1049 read_from_data_list_fixed (const struct data_list_pgm *dls, struct ccase *c)
1051 struct dls_var_spec *var_spec = dls->first;
1054 if (dfm_eof (dls->reader))
1056 for (i = 1; i <= dls->rec_cnt; i++)
1058 struct fixed_string line;
1060 if (dfm_eof (dls->reader))
1062 /* Note that this can't occur on the first record. */
1063 msg (SW, _("Partial case of %d of %d records discarded."),
1064 i - 1, dls->rec_cnt);
1067 dfm_expand_tabs (dls->reader);
1068 dfm_get_record (dls->reader, &line);
1070 for (; var_spec && i == var_spec->rec; var_spec = var_spec->next)
1074 data_in_finite_line (&di, ls_c_str (&line), ls_length (&line),
1075 var_spec->fc, var_spec->lc);
1076 di.v = case_data_rw (c, var_spec->fv);
1077 di.flags = DI_IMPLIED_DECIMALS;
1078 di.f1 = var_spec->fc;
1079 di.format = var_spec->input;
1084 dfm_forward_record (dls->reader);
1090 /* Reads a case from the data file into C, parsing it according
1091 to free-format syntax rules in DLS.
1092 Returns true if successful, false at end of file or on I/O error. */
1094 read_from_data_list_free (const struct data_list_pgm *dls, struct ccase *c)
1096 struct dls_var_spec *var_spec;
1099 for (var_spec = dls->first; var_spec; var_spec = var_spec->next)
1101 struct fixed_string field;
1104 /* Cut out a field and read in a new record if necessary. */
1107 column = cut_field (dls, &field, &end_blank);
1111 if (!dfm_eof (dls->reader))
1112 dfm_forward_record (dls->reader);
1113 if (dfm_eof (dls->reader))
1115 if (var_spec != dls->first)
1116 msg (SW, _("Partial case discarded. The first variable "
1117 "missing was %s."), var_spec->name);
1125 di.s = ls_c_str (&field);
1126 di.e = ls_end (&field);
1127 di.v = case_data_rw (c, var_spec->fv);
1130 di.format = var_spec->input;
1137 /* Reads a case from the data file and parses it according to
1138 list-format syntax rules.
1139 Returns true if successful, false at end of file or on I/O error. */
1141 read_from_data_list_list (const struct data_list_pgm *dls, struct ccase *c)
1143 struct dls_var_spec *var_spec;
1146 if (dfm_eof (dls->reader))
1149 for (var_spec = dls->first; var_spec; var_spec = var_spec->next)
1151 struct fixed_string field;
1154 /* Cut out a field and check for end-of-line. */
1155 column = cut_field (dls, &field, &end_blank);
1158 if (get_undefined ())
1159 msg (SW, _("Missing value(s) for all variables from %s onward. "
1160 "These will be filled with the system-missing value "
1161 "or blanks, as appropriate."),
1163 for (; var_spec; var_spec = var_spec->next)
1165 int width = get_format_var_width (&var_spec->input);
1167 case_data_rw (c, var_spec->fv)->f = SYSMIS;
1169 memset (case_data_rw (c, var_spec->fv)->s, ' ', width);
1177 di.s = ls_c_str (&field);
1178 di.e = ls_end (&field);
1179 di.v = case_data_rw (c, var_spec->fv);
1182 di.format = var_spec->input;
1187 dfm_forward_record (dls->reader);
1191 /* Destroys SPEC. */
1193 destroy_dls_var_spec (struct dls_var_spec *spec)
1195 struct dls_var_spec *next;
1197 while (spec != NULL)
1205 /* Destroys DATA LIST transformation DLS.
1206 Returns true if successful, false if an I/O error occurred. */
1208 data_list_trns_free (void *dls_)
1210 struct data_list_pgm *dls = dls_;
1212 destroy_dls_var_spec (dls->first);
1213 dfm_close_reader (dls->reader);
1218 /* Handle DATA LIST transformation DLS, parsing data into C. */
1220 data_list_trns_proc (void *dls_, struct ccase *c, int case_num UNUSED)
1222 struct data_list_pgm *dls = dls_;
1225 if (read_from_data_list (dls, c))
1226 retval = TRNS_CONTINUE;
1227 else if (dfm_reader_error (dls->reader) || dfm_eof (dls->reader) > 1)
1229 /* An I/O error, or encountering end of file for a second
1230 time, should be escalated into a more serious error. */
1231 retval = TRNS_ERROR;
1234 retval = TRNS_END_FILE;
1236 /* If there was an END subcommand handle it. */
1237 if (dls->end != NULL)
1239 double *end = &case_data_rw (c, dls->end->fv)->f;
1240 if (retval == TRNS_DROP_CASE)
1243 retval = TRNS_END_FILE;
1252 /* Reads all the records from the data file and passes them to
1254 Returns true if successful, false if an I/O error occurred. */
1256 data_list_source_read (struct case_source *source,
1258 write_case_func *write_case, write_case_data wc_data)
1260 struct data_list_pgm *dls = source->aux;
1266 if (!read_from_data_list (dls, c))
1267 return !dfm_reader_error (dls->reader);
1269 dfm_push (dls->reader);
1270 ok = write_case (wc_data);
1271 dfm_pop (dls->reader);
1277 /* Destroys the source's internal data. */
1279 data_list_source_destroy (struct case_source *source)
1281 data_list_trns_free (source->aux);
1284 static const struct case_source_class data_list_source_class =
1288 data_list_source_read,
1289 data_list_source_destroy,