X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdfm.c;h=8216079b47a627e26fdc1d5fec7f9f2fe1556b9f;hb=205eaea8e2d95e20baa2c00a495b0ac4f9646372;hp=9f62029466b8c4072f06984c7d5176a55fe9b3d6;hpb=1c7efcb9a47f141c7bb6a50def0bb88dbaa0c38f;p=pspp-builds.git diff --git a/src/dfm.c b/src/dfm.c index 9f620294..8216079b 100644 --- a/src/dfm.c +++ b/src/dfm.c @@ -36,54 +36,66 @@ #include "debug-print.h" +/* Flags for DFM readers. */ +enum dfm_reader_flags + { + DFM_EOF = 001, /* At end-of-file? */ + DFM_ADVANCE = 002, /* Read next line on dfm_get_record() call? */ + DFM_SAW_BEGIN_DATA = 004, /* For inline_file only, whether we've + already read a BEGIN DATA line. */ + DFM_TABS_EXPANDED = 010, /* Tabs have been expanded. */ + }; + /* file_handle extension structure. */ -struct dfm_fhuser_ext +struct dfm_reader_ext { struct file_ext file; /* Associated file. */ struct file_locator where; /* Current location in data file. */ - char *line; /* Current line, not null-terminated. */ - size_t size; /* Number of bytes allocated for line. */ - size_t len; /* Length of line. */ - - char *ptr; /* Pointer into line that is returned by - dfm_get_record(). */ - int advance; /* Nonzero=dfm_get_record() reads a new - record; otherwise returns current record. */ - int saw_begin_data; /* For inline_file only, whether we've - already read a BEGIN DATA line. */ + struct string line; /* Current line. */ + size_t pos; /* Offset in line of current character. */ + struct string scratch; /* Extra line buffer. */ + enum dfm_reader_flags flags; /* Zero or more of DFM_*. */ }; -/* These are defined at the end of this file. */ static struct fh_ext_class dfm_r_class; -static struct fh_ext_class dfm_w_class; static void read_record (struct file_handle *h); - -/* Internal (low level). */ -/* Closes the file handle H which was opened by open_file_r() or - open_file_w(). */ +/* Asserts that H represents a DFM reader and returns H->ext + converted to a struct dfm_reader_ext *. */ +static inline struct dfm_reader_ext * +get_reader (struct file_handle *h) +{ + assert (h != NULL); + assert (h->class == &dfm_r_class); + assert (h->ext != NULL); + + return h->ext; +} + +/* Closes file handle H opened by dfm_open_for_reading(). */ static void -dfm_close (struct file_handle *h) +close_reader (struct file_handle *h) { - struct dfm_fhuser_ext *ext = h->ext; + struct dfm_reader_ext *ext = get_reader (h); /* Skip any remaining data on the inline file. */ if (h == inline_file) - while (ext->line != NULL) + while ((ext->flags & DFM_EOF) == 0) read_record (h); msg (VM (2), _("%s: Closing data-file handle %s."), handle_get_filename (h), handle_get_name (h)); - assert (h->class == &dfm_r_class || h->class == &dfm_w_class); + assert (h->class == &dfm_r_class); if (ext->file.file) { fn_close_ext (&ext->file); free (ext->file.filename); ext->file.filename = NULL; } - free (ext->line); + ds_destroy (&ext->line); + ds_destroy (&ext->scratch); free (ext); } @@ -92,7 +104,7 @@ dfm_close (struct file_handle *h) int dfm_open_for_reading (struct file_handle *h) { - struct dfm_fhuser_ext *ext; + struct dfm_reader_ext *ext; if (h->class != NULL) { @@ -110,12 +122,9 @@ dfm_open_for_reading (struct file_handle *h) ext->where.filename = handle_get_filename (h); ext->where.line_number = 0; ext->file.file = NULL; - ext->line = xmalloc (128); - ext->len = 0; - ext->ptr = NULL; - ext->size = 128; - ext->advance = 1; - ext->saw_begin_data = 0; + ds_init (&ext->line, 64); + ds_init (&ext->scratch, 0); + ext->flags = DFM_ADVANCE; msg (VM (1), _("%s: Opening data-file handle %s for reading."), handle_get_filename (h), handle_get_name (h)); @@ -149,190 +158,6 @@ dfm_open_for_reading (struct file_handle *h) return 0; } -/* Opens a file handle for writing as a data file. */ -int -dfm_open_for_writing (struct file_handle *h) -{ - struct dfm_fhuser_ext *ext; - - if (h->class != NULL) - { - if (h->class == &dfm_w_class) - return 1; - else - { - msg (ME, _("Cannot write to file %s already opened for %s."), - handle_get_name (h), gettext (h->class->name)); - err_cond_fail (); - return 0; - } - } - - ext = xmalloc (sizeof *ext); - ext->where.filename = handle_get_filename (h); - ext->where.line_number = 0; - ext->file.file = NULL; - ext->line = NULL; - ext->len = 0; - ext->ptr = NULL; - ext->size = 0; - ext->advance = 0; - - msg (VM (1), _("%s: Opening data-file handle %s for writing."), - handle_get_filename (h), handle_get_name (h)); - - assert (h != NULL); - if (h == inline_file) - { - msg (ME, _("Cannot open the inline file for writing.")); - goto error; - } - - ext->file.filename = xstrdup (handle_get_filename (h)); - ext->file.mode = "wb"; - ext->file.file = NULL; - ext->file.sequence_no = NULL; - ext->file.param = NULL; - ext->file.postopen = NULL; - ext->file.preclose = NULL; - - if (!fn_open_ext (&ext->file)) - { - msg (ME, _("An error occurred while opening \"%s\" for writing " - "as a data file: %s."), - handle_get_filename (h), strerror (errno)); - goto error; - } - - h->class = &dfm_w_class; - h->ext = ext; - return 1; - - error: - free (ext); - err_cond_fail (); - return 0; -} - -/* Ensures that the line buffer in file handle with extension EXT is - big enough to hold a line of length EXT->LEN characters not - including null terminator. */ -#define force_line_buffer_expansion() \ - do \ - { \ - if (ext->len + 1 > ext->size) \ - { \ - ext->size = ext->len * 2; \ - ext->line = xrealloc (ext->line, ext->size); \ - } \ - } \ - while (0) - -/* Counts the number of tabs in string STRING of length LEN. */ -static inline int -count_tabs (char *s, size_t len) -{ - int n_tabs = 0; - - for (;;) - { - char *cp = memchr (s, '\t', len); - if (cp == NULL) - return n_tabs; - n_tabs++; - len -= cp - s + 1; - s = cp + 1; - } -} - -/* Converts all the tabs in H->EXT->LINE to an equivalent number of - spaces, if necessary. */ -static void -tabs_to_spaces (struct file_handle *h) -{ - struct dfm_fhuser_ext *ext = h->ext; - - char *first_tab; /* Location of first tab (if any). */ - char *second_tab; /* Location of second tab (if any). */ - size_t orig_len; /* Line length at function entry. */ - - /* If there aren't any tabs then there's nothing to do. */ - first_tab = memchr (ext->line, '\t', ext->len); - if (first_tab == NULL) - return; - orig_len = ext->len; - - /* If there's just one tab then expand it inline. Otherwise do a - full string copy to another buffer. */ - second_tab = memchr (first_tab + 1, '\t', - ext->len - (first_tab - ext->line + 1)); - if (second_tab == NULL) - { - int n_spaces = 8 - (first_tab - ext->line) % 8; - - ext->len += n_spaces - 1; - - /* Expand the line if necessary, keeping the first_tab pointer - valid. */ - { - size_t ofs = first_tab - ext->line; - force_line_buffer_expansion (); - first_tab = ext->line + ofs; - } - - memmove (first_tab + n_spaces, first_tab + 1, - orig_len - (first_tab - ext->line + 1)); - memset (first_tab, ' ', n_spaces); - } else { - /* Make a local copy of original text. */ - char *orig_line = local_alloc (ext->len + 1); - memcpy (orig_line, ext->line, ext->len); - - /* Allocate memory assuming we need to add 8 spaces for every tab. */ - ext->len += 2 + count_tabs (second_tab + 1, - ext->len - (second_tab - ext->line + 1)); - - /* Expand the line if necessary, keeping the first_tab pointer - valid. */ - { - size_t ofs = first_tab - ext->line; - force_line_buffer_expansion (); - first_tab = ext->line + ofs; - } - - /* Walk through orig_line, expanding tabs into ext->line. */ - { - char *src_p = orig_line + (first_tab - ext->line); - char *dest_p = first_tab; - - for (; src_p < orig_line + orig_len; src_p++) - { - /* Most characters simply pass through untouched. */ - if (*src_p != '\t') - { - *dest_p++ = *src_p; - continue; - } - - /* Tabs are expanded into an equivalent number of - spaces. */ - { - int n_spaces = 8 - (dest_p - ext->line) % 8; - - memset (dest_p, ' ', n_spaces); - dest_p += n_spaces; - } - } - - /* Supply null terminator and actual string length. */ - *dest_p = 0; - ext->len = dest_p - ext->line; - } - - local_free (orig_line); - } -} - /* Reads a record from H->EXT->FILE into H->EXT->LINE, setting H->EXT->PTR to H->EXT->LINE, and setting H->EXT-LEN to the length of the line. The line is not null-terminated. If an error occurs @@ -340,15 +165,15 @@ tabs_to_spaces (struct file_handle *h) static void read_record (struct file_handle *h) { - struct dfm_fhuser_ext *ext = h->ext; + struct dfm_reader_ext *ext = get_reader (h); if (h == inline_file) { - if (!ext->saw_begin_data) + if ((ext->flags & DFM_SAW_BEGIN_DATA) == 0) { char *s; - ext->saw_begin_data = 1; + ext->flags |= DFM_SAW_BEGIN_DATA; /* FIXME: WTF can't this just be done with tokens? Is this really a special case? */ @@ -362,9 +187,10 @@ read_record (struct file_handle *h) err_failure (); } - /* Skip leading whitespace, separate out first word, so that - S points to a single word reduced to lowercase. */ - s = ds_value (&getl_buf); + /* Skip leading whitespace, separate out first + word, so that S points to a single word reduced + to lowercase. */ + s = ds_c_str (&getl_buf); while (isspace ((unsigned char) *s)) s++; for (cp = s; isalpha ((unsigned char) *cp); cp++) @@ -385,36 +211,31 @@ read_record (struct file_handle *h) if (!getl_read_line ()) { msg (SE, _("Unexpected end-of-file while reading data in BEGIN " - "DATA. This probably indicates " - "a missing or misformatted END DATA command. " - "END DATA must appear by itself on a single line " - "with exactly one space between words.")); + "DATA. This probably indicates " + "a missing or misformatted END DATA command. " + "END DATA must appear by itself on a single line " + "with exactly one space between words.")); err_failure (); } ext->where.line_number++; if (ds_length (&getl_buf) >= 8 - && !strncasecmp (ds_value (&getl_buf), "end data", 8)) + && !strncasecmp (ds_c_str (&getl_buf), "end data", 8)) { - lex_set_prog (ds_value (&getl_buf) + ds_length (&getl_buf)); + lex_set_prog (ds_c_str (&getl_buf) + ds_length (&getl_buf)); goto eof; } - ext->len = ds_length (&getl_buf); - force_line_buffer_expansion (); - strcpy (ext->line, ds_value (&getl_buf)); + ds_replace (&ext->line, ds_c_str (&getl_buf)); } else { if (handle_get_mode (h) == MODE_TEXT) { - /* PORTME: here you should adapt the routine to your - system's concept of a "line" of text. */ - int read_len = getline (&ext->line, &ext->size, ext->file.file); - - if (read_len == -1) - { + ds_clear (&ext->line); + if (!ds_gets (&ext->line, ext->file.file)) + { if (ferror (ext->file.file)) { msg (ME, _("Error reading file %s: %s."), @@ -423,19 +244,17 @@ read_record (struct file_handle *h) } goto eof; } - ext->len = (size_t) read_len; } else if (handle_get_mode (h) == MODE_BINARY) { size_t record_width = handle_get_record_width (h); size_t amt; - if (ext->size < record_width) - { - ext->size = record_width; - ext->line = xmalloc (ext->size); - } - amt = fread (ext->line, 1, record_width, ext->file.file); + if (ds_length (&ext->line) < record_width) + ds_rpad (&ext->line, record_width, 0); + + amt = fread (ds_c_str (&ext->line), 1, record_width, + ext->file.file); if (record_width != amt) { if (ferror (ext->file.file)) @@ -457,117 +276,246 @@ read_record (struct file_handle *h) ext->where.line_number++; } - /* Strip trailing whitespace, I forget why. But there's a good - reason, I'm sure. I'm too scared to eliminate this code. */ - if (handle_get_mode (h) == MODE_TEXT) - { - while (ext->len && isspace ((unsigned char) ext->line[ext->len - 1])) - ext->len--; - - /* Convert tabs to spaces. */ - - ext->ptr = ext->line; - } + ext->pos = 0; return; eof: /* Hit eof or an error, clean up everything. */ - if (ext->line) - free (ext->line); - ext->size = 0; - ext->line = ext->ptr = NULL; - return; + ext->flags |= DFM_EOF; } - -/* Public (high level). */ - -/* Returns the current record in the file corresponding to HANDLE. - Opens files and reads records, etc., as necessary. Sets *LEN to - the length of the line. The line returned is not null-terminated. - Returns NULL at end of file. Calls fail() on attempt to read past - end of file. */ -char * -dfm_get_record (struct file_handle *h, int *len) -{ - struct dfm_fhuser_ext *ext; - - assert (h != NULL); - assert (h->class == &dfm_r_class); - assert (h->ext != NULL); - ext = h->ext; - if (ext->advance) +/* Returns nonzero if end of file has been reached on HANDLE. + Reads forward in HANDLE's file, if necessary to tell. */ +int +dfm_eof (struct file_handle *h) +{ + struct dfm_reader_ext *ext = get_reader (h); + if (ext->flags & DFM_ADVANCE) { - if (ext->line) + ext->flags &= ~DFM_ADVANCE; + if ((ext->flags & DFM_EOF) == 0) read_record (h); else { msg (SE, _("Attempt to read beyond end-of-file on file %s."), handle_get_name (h)); - goto lossage; + err_cond_fail (); } } - ext->advance = 0; - if (len) - *len = ext->len - (ext->ptr - ext->line); - return ext->ptr; + return (ext->flags & DFM_EOF) != 0; +} -lossage: - /* Come here on reading beyond eof or reading from a file already - open for something else. */ - err_cond_fail (); +/* Returns the current record in the file corresponding to + HANDLE. Aborts if reading from the file is necessary or at + end of file, so call dfm_eof() first. Sets *LINE to the line, + which is not null-terminated. The caller must not free or + modify the returned string. */ +void +dfm_get_record (struct file_handle *h, struct len_string *line) +{ + struct dfm_reader_ext *ext = get_reader (h); + assert ((ext->flags & DFM_ADVANCE) == 0); + assert ((ext->flags & DFM_EOF) == 0); + assert (ext->pos <= ds_length (&ext->line)); + + line->string = ds_data (&ext->line) + ext->pos; + line->length = ds_length (&ext->line) - ext->pos; +} + +/* Expands tabs in the current line into the equivalent number of + spaces, if appropriate for this kind of file. Aborts if + reading from the file is necessary or at end of file, so call + dfm_eof() first.*/ +void +dfm_expand_tabs (struct file_handle *h) +{ + struct dfm_reader_ext *ext = get_reader (h); + struct string temp; + size_t ofs, new_pos, tab_width; + + assert ((ext->flags & DFM_ADVANCE) == 0); + assert ((ext->flags & DFM_EOF) == 0); + assert (ext->pos <= ds_length (&ext->line)); + + if (ext->flags & DFM_TABS_EXPANDED) + return; + ext->flags |= DFM_TABS_EXPANDED; + + if (handle_get_mode (h) == MODE_BINARY + || handle_get_tab_width (h) == 0 + || memchr (ds_c_str (&ext->line), '\t', ds_length (&ext->line)) == NULL) + return; + + /* Expand tabs from ext->line into ext->scratch, and figure out + new value for ext->pos. */ + tab_width = handle_get_tab_width (h); + ds_clear (&ext->scratch); + new_pos = 0; + for (ofs = 0; ofs < ds_length (&ext->line); ofs++) + { + unsigned char c; + + if (ofs == ext->pos) + new_pos = ds_length (&ext->scratch); + + c = ds_c_str (&ext->line)[ofs]; + if (c != '\t') + ds_putc (&ext->scratch, c); + else + { + do + ds_putc (&ext->scratch, ' '); + while (ds_length (&ext->scratch) % tab_width != 0); + } + } - return NULL; + /* Swap ext->line and ext->scratch and set new ext->pos. */ + temp = ext->line; + ext->line = ext->scratch; + ext->scratch = temp; + ext->pos = new_pos; } /* Causes dfm_get_record() to read in the next record the next time it is executed on file HANDLE. */ void -dfm_fwd_record (struct file_handle *h) +dfm_forward_record (struct file_handle *h) { - struct dfm_fhuser_ext *ext = h->ext; + struct dfm_reader_ext *ext = get_reader (h); + ext->flags |= DFM_ADVANCE; +} - assert (h->class == &dfm_r_class); - ext->advance = 1; +/* Cancels the effect of any previous dfm_fwd_record() executed + on file HANDLE. Sets the current line to begin in the 1-based + column COLUMN. */ +void +dfm_reread_record (struct file_handle *h, size_t column) +{ + struct dfm_reader_ext *ext = get_reader (h); + ext->flags &= ~DFM_ADVANCE; + if (column < 1) + ext->pos = 0; + else if (column > ds_length (&ext->line)) + ext->pos = ds_length (&ext->line); + else + ext->pos = column - 1; } -/* Cancels the effect of any previous dfm_fwd_record() executed on - file HANDLE. Sets the current line to begin in the 1-based column - COLUMN, as with dfm_set_record but based on a column number instead - of a character pointer. */ +/* Sets the current line to begin COLUMNS characters following + the current start. */ void -dfm_bkwd_record (struct file_handle *h, int column) +dfm_forward_columns (struct file_handle *h, size_t columns) { - struct dfm_fhuser_ext *ext = h->ext; + struct dfm_reader_ext *ext = get_reader (h); + dfm_reread_record (h, (ext->pos + 1) + columns); +} - assert (h->class == &dfm_r_class); - ext->advance = 0; - ext->ptr = ext->line + min ((int) ext->len + 1, column) - 1; +/* Returns the 1-based column to which the line pointer in HANDLE + is set. Unless dfm_reread_record() or dfm_forward_columns() + have been called, this is 1. */ +size_t +dfm_column_start (struct file_handle *h) +{ + struct dfm_reader_ext *ext = get_reader (h); + return ext->pos + 1; } -/* Sets the current line in HANDLE to NEW_LINE, which must point - somewhere in the line last returned by dfm_get_record(). Used by - DATA LIST FREE to strip the leading portion off the current line. */ +/* Pushes the filename and line number on the fn/ln stack. */ void -dfm_set_record (struct file_handle *h, char *new_line) +dfm_push (struct file_handle *h) { - struct dfm_fhuser_ext *ext = h->ext; + struct dfm_reader_ext *ext = get_reader (h); + if (h != inline_file) + err_push_file_locator (&ext->where); +} - assert (h->class == &dfm_r_class); - ext->ptr = new_line; +/* Pops the filename and line number from the fn/ln stack. */ +void +dfm_pop (struct file_handle *h) +{ + struct dfm_reader_ext *ext = get_reader (h); + if (h != inline_file) + err_pop_file_locator (&ext->where); } -/* Returns the 0-based current column to which the line pointer in - HANDLE is set. Unless dfm_set_record() or dfm_bkwd_record() have - been called, this is 0. */ +/* DFM reader class. */ +static struct fh_ext_class dfm_r_class = +{ + 1, + N_("reading as a data file"), + close_reader, +}; + +/* file_handle extension structure. */ +struct dfm_writer_ext + { + struct file_ext file; /* Associated file. */ + struct file_locator where; /* Current location in data file. */ + char *bounce; /* Bounce buffer for fixed-size fields. */ + }; + +static struct fh_ext_class dfm_w_class; + +/* Opens a file handle for writing as a data file. */ int -dfm_get_cur_col (struct file_handle *h) +dfm_open_for_writing (struct file_handle *h) { - struct dfm_fhuser_ext *ext = h->ext; + struct dfm_writer_ext *ext; + + if (h->class != NULL) + { + if (h->class == &dfm_w_class) + return 1; + else + { + msg (ME, _("Cannot write to file %s already opened for %s."), + handle_get_name (h), gettext (h->class->name)); + err_cond_fail (); + return 0; + } + } - assert (h->class == &dfm_r_class); - return ext->ptr - ext->line; + ext = xmalloc (sizeof *ext); + ext->where.filename = handle_get_filename (h); + ext->where.line_number = 0; + ext->file.file = NULL; + ext->bounce = NULL; + + msg (VM (1), _("%s: Opening data-file handle %s for writing."), + handle_get_filename (h), handle_get_name (h)); + + assert (h != NULL); + if (h == inline_file) + { + msg (ME, _("Cannot open the inline file for writing.")); + goto error; + } + + ext->file.filename = xstrdup (handle_get_filename (h)); + ext->file.mode = "wb"; + ext->file.file = NULL; + ext->file.sequence_no = NULL; + ext->file.param = NULL; + ext->file.postopen = NULL; + ext->file.preclose = NULL; + + if (!fn_open_ext (&ext->file)) + { + msg (ME, _("An error occurred while opening \"%s\" for writing " + "as a data file: %s."), + handle_get_filename (h), strerror (errno)); + goto error; + } + + h->class = &dfm_w_class; + h->ext = ext; + return 1; + + error: + free (ext); + err_cond_fail (); + return 0; } /* Writes record REC having length LEN to the file corresponding to @@ -576,9 +524,7 @@ dfm_get_cur_col (struct file_handle *h) int dfm_put_record (struct file_handle *h, const char *rec, size_t len) { - struct dfm_fhuser_ext *ext; - char *ptr; - size_t amt; + struct dfm_writer_ext *ext; assert (h != NULL); assert (h->class == &dfm_w_class); @@ -587,18 +533,16 @@ dfm_put_record (struct file_handle *h, const char *rec, size_t len) ext = h->ext; if (handle_get_mode (h) == MODE_BINARY && len < handle_get_record_width (h)) { - amt = handle_get_record_width (h); - ptr = local_alloc (amt); - memcpy (ptr, rec, len); - memset (&ptr[len], 0, amt - len); - } - else - { - ptr = (char *) rec; - amt = len; + size_t rec_width = handle_get_record_width (h); + if (ext->bounce == NULL) + ext->bounce = xmalloc (rec_width); + memcpy (ext->bounce, rec, len); + memset (&ext->bounce[len], 0, rec_width - len); + rec = ext->bounce; + len = rec_width; } - if (1 != fwrite (ptr, amt, 1, ext->file.file)) + if (fwrite (rec, len, 1, ext->file.file) != 1) { msg (ME, _("Error writing file %s: %s."), handle_get_name (h), strerror (errno)); @@ -606,35 +550,37 @@ dfm_put_record (struct file_handle *h, const char *rec, size_t len) return 0; } - if (ptr != rec) - local_free (ptr); - return 1; } -/* Pushes the filename and line number on the fn/ln stack. */ -void -dfm_push (struct file_handle *h) +/* Closes file handle H opened by dfm_open_for_writing(). */ +static void +close_writer (struct file_handle *h) { - struct dfm_fhuser_ext *ext = h->ext; + struct dfm_writer_ext *ext; - assert (h->class == &dfm_r_class || h->class == &dfm_w_class); - assert (ext != NULL); - if (h != inline_file) - err_push_file_locator (&ext->where); + assert (h->class == &dfm_w_class); + ext = h->ext; + + msg (VM (2), _("%s: Closing data-file handle %s."), + handle_get_filename (h), handle_get_name (h)); + if (ext->file.file) + { + fn_close_ext (&ext->file); + free (ext->file.filename); + ext->file.filename = NULL; + } + free (ext->bounce); + free (ext); } -/* Pops the filename and line number from the fn/ln stack. */ -void -dfm_pop (struct file_handle *h) +/* DFM writer class. */ +static struct fh_ext_class dfm_w_class = { - struct dfm_fhuser_ext *ext = h->ext; - - assert (h->class == &dfm_r_class || h->class == &dfm_w_class); - assert (ext != NULL); - if (h != inline_file) - err_pop_file_locator (&ext->where); -} + 2, + N_("writing as a data file"), + close_writer, +}; /* BEGIN DATA...END DATA procedure. */ @@ -642,16 +588,15 @@ dfm_pop (struct file_handle *h) int cmd_begin_data (void) { - struct dfm_fhuser_ext *ext; + struct dfm_reader_ext *ext; /* FIXME: figure out the *exact* conditions, not these really lenient conditions. */ if (vfm_source == NULL - || case_source_is_class (vfm_source, &storage_source_class) - || case_source_is_class (vfm_source, &sort_source_class)) + || case_source_is_class (vfm_source, &storage_source_class)) { msg (SE, _("This command is not valid here since the current " - "input program does not access the inline file.")); + "input program does not access the inline file.")); err_cond_fail (); return CMD_FAILURE; } @@ -660,7 +605,7 @@ cmd_begin_data (void) msg (VM (1), _("inline file: Opening for reading.")); dfm_open_for_reading (inline_file); ext = inline_file->ext; - ext->saw_begin_data = 1; + ext->flags |= DFM_SAW_BEGIN_DATA; /* We don't actually read from the inline file. The input procedure is what reads from it. */ @@ -668,27 +613,13 @@ cmd_begin_data (void) procedure (NULL, NULL); ext = inline_file->ext; - if (ext && ext->line) + if (ext && (ext->flags & DFM_EOF) == 0) { msg (MW, _("Skipping remaining inline data.")); - for (read_record (inline_file); ext->line; read_record (inline_file)) - ; + while ((ext->flags & DFM_EOF) == 0) + read_record (inline_file); } assert (inline_file->ext == NULL); return CMD_SUCCESS; } - -static struct fh_ext_class dfm_r_class = -{ - 1, - N_("reading as a data file"), - dfm_close, -}; - -static struct fh_ext_class dfm_w_class = -{ - 2, - N_("writing as a data file"), - dfm_close, -};