- v = dict_create_var (default_dict, name[i], width);
-
- if (!v)
- {
- msg (SE, _("%s is a duplicate variable name."), name[i]);
- return 0;
- }
- v->print = v->write = output;
-
- spec = xmalloc (sizeof *spec);
- spec->input = input;
- spec->v = v;
- spec->fv = v->fv;
- str_copy_trunc (spec->name, sizeof spec->name, v->name);
- append_var_spec (first, last, spec);
- }
- for (i = 0; i < name_cnt; i++)
- free (name[i]);
- free (name);
- }
-
- return lex_end_of_command () == CMD_SUCCESS;
-}
-
-/* Displays a table giving information on free-format variable parsing
- on DATA LIST. */
-static void
-dump_free_table (const struct data_list_pgm *dls,
- const struct file_handle *fh)
-{
- struct tab_table *t;
- int i;
-
- {
- struct dls_var_spec *spec;
- for (i = 0, spec = dls->first; spec; spec = spec->next)
- i++;
- }
-
- t = tab_create (2, i + 1, 0);
- tab_columns (t, TAB_COL_DOWN, 1);
- tab_headers (t, 0, 0, 1, 0);
- tab_text (t, 0, 0, TAB_CENTER | TAT_TITLE, _("Variable"));
- tab_text (t, 1, 0, TAB_CENTER | TAT_TITLE, _("Format"));
- tab_box (t, TAL_1, TAL_1, TAL_0, TAL_1, 0, 0, 1, i);
- tab_hline (t, TAL_2, 0, 1, 1);
- tab_dim (t, tab_natural_dimensions);
-
- {
- struct dls_var_spec *spec;
-
- for (i = 1, spec = dls->first; spec; spec = spec->next, i++)
- {
- tab_text (t, 0, i, TAB_LEFT, spec->v->name);
- tab_text (t, 1, i, TAB_LEFT | TAB_FIX, fmt_to_string (&spec->input));
- }
- }
-
- tab_title (t, _("Reading free-form data from %s."), fh_get_name (fh));
-
- tab_submit (t);
-}
-\f
-/* Input procedure. */
-
-/* Extracts a field from the current position in the current
- record. Fields can be unquoted or quoted with single- or
- double-quote characters. *FIELD is set to the field content.
- After parsing the field, sets the current position in the
- record to just past the field and any trailing delimiter.
- END_BLANK is used internally; it should be initialized by the
- caller to 0 and left alone afterward. Returns 0 on failure or
- a 1-based column number indicating the beginning of the field
- on success. */
-static int
-cut_field (const struct data_list_pgm *dls, struct fixed_string *field,
- int *end_blank)
-{
- struct fixed_string line;
- char *cp;
- size_t column_start;
-
- if (dfm_eof (dls->reader))
- return 0;
- if (dls->delim_cnt == 0)
- dfm_expand_tabs (dls->reader);
- dfm_get_record (dls->reader, &line);
-
- cp = ls_c_str (&line);
- if (dls->delim_cnt == 0)
- {
- /* Skip leading whitespace. */
- while (cp < ls_end (&line) && isspace ((unsigned char) *cp))
- cp++;
- if (cp >= ls_end (&line))
- return 0;
-
- /* Handle actual data, whether quoted or unquoted. */
- if (*cp == '\'' || *cp == '"')
- {
- int quote = *cp;
-
- field->string = ++cp;
- while (cp < ls_end (&line) && *cp != quote)
- cp++;
- field->length = cp - field->string;
- if (cp < ls_end (&line))
- cp++;
- else
- msg (SW, _("Quoted string missing terminating `%c'."), quote);
- }
- else
- {
- field->string = cp;
- while (cp < ls_end (&line)
- && !isspace ((unsigned char) *cp) && *cp != ',')
- cp++;
- field->length = cp - field->string;
- }
-
- /* Skip trailing whitespace and a single comma if present. */
- while (cp < ls_end (&line) && isspace ((unsigned char) *cp))
- cp++;
- if (cp < ls_end (&line) && *cp == ',')
- cp++;
- }
- else
- {
- if (cp >= ls_end (&line))
- {
- int column = dfm_column_start (dls->reader);
- /* A blank line or a line that ends in \t has a
- trailing blank field. */
- if (column == 1 || (column > 1 && cp[-1] == '\t'))