- /* Ugly. The parser opens the input file mutliple times, so we
- have to always use the FILE * that's passed to m_getfld(). */
- m->iob = iob;
- pos = ftello (iob);
-
- /* Rely on Restriction that the first call to m_getfld (), etc.,
- is with the read position for the file stream set to 0. */
- if (pos == 0) {
- /* A new file stream, so reset the buffer state. */
- m->iob = iob;
- m->readpos = m->end = m->msg_buf;
- m->total_bytes_read = 0;
- m->last_caller_pos = m->last_internal_pos = ftello (iob);
- m->pat_map = NULL;
- m->fdelim = m->delimend = m->edelim = NULL;
- m->msg_style = MS_DEFAULT;
- m->msg_delim = "";
- m->fdelimlen = m->edelimlen = 0;
- m->eom_action = NULL;
- } else {
- off_t pos_movement = pos - m->last_caller_pos; /* Can be < 0. */
-
- if (pos_movement == 0) {
- pos = m->last_internal_pos;
- } else {
- /* The current file stream position differs from the last one, so
- caller must have called ftell/o(). Adjust accordingly. */
- if (m->readpos + pos_movement >= m->msg_buf &&
- m->readpos + pos_movement < m->end) {
- /* We can shift readpos and remain within the bounds of
- msg_buf. */
- m->readpos += pos_movement;
- m->total_bytes_read += pos_movement;
- pos = m->last_internal_pos;
- } else {
- size_t num_read;
-
- /* This seek skips past an integral number of chunks of
- size MSG_INPUT_SIZE. */
- fseeko (iob, pos / MSG_INPUT_SIZE * MSG_INPUT_SIZE, SEEK_SET);
- num_read = fread (m->msg_buf, 1, MSG_INPUT_SIZE, iob);
- m->readpos = m->msg_buf + pos % MSG_INPUT_SIZE;
- m->end = m->msg_buf + num_read;
- m->total_bytes_read = pos;
- }
- }
+ if (! *gstate) {
+ m_getfld_state_init (gstate, iob);
+ }
+ s = *gstate;
+ s->bytes_read = 0;
+
+ /* This is ugly and no longer necessary, but is retained just in
+ case it's needed again. The parser used to open the input file
+ multiple times, so we had to always use the FILE * that's
+ passed to m_getfld(). Now the parser inits a new
+ m_getfld_state for each file. See comment below about the
+ readpos shift code being currently unused. */
+ s->iob = iob;
+
+ if (!s->track_filepos)
+ return;
+
+ pos = ftello(iob);
+ if (pos == 0 && s->last_internal_pos == 0)
+ return;
+
+ if (s->last_internal_pos == 0) {
+ s->total_bytes_read = pos;
+ return;
+ }