Commit 15877a88 by Janne Blomqvist

Part 1 of PR 25561.

2008-05-15  Janne Blomqvist  <jb@gcc.gnu.org>

	PR libfortran/25561
	* Makefile.am: Add fbuf.c to gfor_io_src.
	* Makefile.in: Regenerate.
	* io/io.h (read_block): Remove.
	(struct stream): Remove alloc_r_at function pointer.
	(salloc_r): Remove.
	(salloc_r_at): Remove.
	(salloc_w_at): Remove.
	(salloc_w): Remove offset argument.
	(struct fbuf): New struct for format buffer.
	(struct gfc_unit): Add fbuf.
	(read_block_form): New prototype.
	(fbuf_init): Likewise.
	(fbuf_destroy): Likewise.
	(fbuf_reset): Likewise.
	(fbuf_alloc): Likewise.
	(fbuf_flush): Likewise.
	(fbuf_seek): Likewise.
	* io/file_pos.c (formatted_backspace): Change to use sread.
	(unformatted_backspace): Likewise.
	(st_backspace): Flush format buffer.
	(st_rewind): Likewise.
	* io/list_read.c (next_char): Likewise.
	(nml_query): Tidying, flush format buffer.
	* io/open.c (new_unit): Init format buffer.
	* io/read.c (read_l): Change to use read_block_form.
	(read_a): Likewise.
	(read_decimal): Likewise.
	(read_radix): Likewise.
	(read_f): Likewise.
	(read_x): Empty reads also for stream I/O.
	* io/transfer.c (read_sf): Change to use sread.
	(read_block): Rename to read_block_form, change prototype, use sread.
	(read_block_direct): Don't seek stream files.
	(write_block): Change to use fbuf if external file, don't seek stream
	files.
	(write_buf): Don't seek stream files.
	(formatted_transfer_scalar): Use fbuf for external files.
	(us_read): Change to use sread.
	(pre_position): Do nothing for stream I/O.
	(data_transfer_init): Flush fbuf when switching from write to read, if
	POS is specified, seek stream file to correct offset.
	(skip_record): Change to use sread.
	(min_off): New function.
	(next_record_r): Change to use sread.
	(next_record_w): Change to use sset/sseek, flush fbuf.
	(finalize_transfer): Flush fbuf.
	* io/unit.c (init_units): Init fbuf for stdout, stderr.
	(close_unit_1): Destroy fbuf.
	(finish_last_advance_record): Flush fbuf, no need to seek.
	* io/unix.c (fd_alloc_r_at): Remove unused where argument.
	(fd_alloc_w_at): Likewise.
	(fd_read): Remove third argument to fd_alloc_r_at.
	(fd_write): Remove third argument to fd_alloc_w_at.
	(fd_sset): Likewise.
	(fd_open): Don't set alloc_r_at.
	(mem_alloc_r_at): Remove unused where argument.
	(mem_alloc_w_at): Likewise.
	(mem_read): Don't incorrectly return previous errno, remove unused
	third argument to alloc function.
	(mem_write): Likewise.
	(mem_set): Likewise.
	(open_internal): Don't set alloc_r_at pointer.
	* io/fbuf.c: New file.

From-SVN: r135373
parent 2819ae08
...@@ -47,7 +47,8 @@ io/size_from_kind.c \ ...@@ -47,7 +47,8 @@ io/size_from_kind.c \
io/transfer.c \ io/transfer.c \
io/unit.c \ io/unit.c \
io/unix.c \ io/unix.c \
io/write.c io/write.c \
io/fbuf.c
gfor_io_headers= \ gfor_io_headers= \
io/io.h io/io.h
......
...@@ -401,8 +401,8 @@ am__libgfortran_la_SOURCES_DIST = runtime/backtrace.c \ ...@@ -401,8 +401,8 @@ am__libgfortran_la_SOURCES_DIST = runtime/backtrace.c \
fpu-target.h io/close.c io/file_pos.c io/format.c io/inquire.c \ fpu-target.h io/close.c io/file_pos.c io/format.c io/inquire.c \
io/intrinsics.c io/list_read.c io/lock.c io/open.c io/read.c \ io/intrinsics.c io/list_read.c io/lock.c io/open.c io/read.c \
io/size_from_kind.c io/transfer.c io/unit.c io/unix.c \ io/size_from_kind.c io/transfer.c io/unit.c io/unix.c \
io/write.c intrinsics/associated.c intrinsics/abort.c \ io/write.c io/fbuf.c intrinsics/associated.c \
intrinsics/access.c intrinsics/args.c \ intrinsics/abort.c intrinsics/access.c intrinsics/args.c \
intrinsics/c99_functions.c intrinsics/chdir.c \ intrinsics/c99_functions.c intrinsics/chdir.c \
intrinsics/chmod.c intrinsics/clock.c intrinsics/cpu_time.c \ intrinsics/chmod.c intrinsics/clock.c intrinsics/cpu_time.c \
intrinsics/cshift0.c intrinsics/ctime.c \ intrinsics/cshift0.c intrinsics/ctime.c \
...@@ -691,7 +691,7 @@ am__objects_33 = $(am__objects_2) $(am__objects_3) $(am__objects_4) \ ...@@ -691,7 +691,7 @@ am__objects_33 = $(am__objects_2) $(am__objects_3) $(am__objects_4) \
$(am__objects_32) $(am__objects_32)
am__objects_34 = close.lo file_pos.lo format.lo inquire.lo \ am__objects_34 = close.lo file_pos.lo format.lo inquire.lo \
intrinsics.lo list_read.lo lock.lo open.lo read.lo \ intrinsics.lo list_read.lo lock.lo open.lo read.lo \
size_from_kind.lo transfer.lo unit.lo unix.lo write.lo size_from_kind.lo transfer.lo unit.lo unix.lo write.lo fbuf.lo
am__objects_35 = associated.lo abort.lo access.lo args.lo \ am__objects_35 = associated.lo abort.lo access.lo args.lo \
c99_functions.lo chdir.lo chmod.lo clock.lo cpu_time.lo \ c99_functions.lo chdir.lo chmod.lo clock.lo cpu_time.lo \
cshift0.lo ctime.lo date_and_time.lo dtime.lo env.lo \ cshift0.lo ctime.lo date_and_time.lo dtime.lo env.lo \
...@@ -946,7 +946,8 @@ io/size_from_kind.c \ ...@@ -946,7 +946,8 @@ io/size_from_kind.c \
io/transfer.c \ io/transfer.c \
io/unit.c \ io/unit.c \
io/unix.c \ io/unix.c \
io/write.c io/write.c \
io/fbuf.c
gfor_io_headers = \ gfor_io_headers = \
io/io.h io/io.h
...@@ -1791,6 +1792,7 @@ distclean-compile: ...@@ -1791,6 +1792,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exponent_r16.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exponent_r16.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exponent_r4.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exponent_r4.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exponent_r8.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exponent_r8.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fbuf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_pos.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file_pos.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fmain.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fmain.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fnum.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fnum.Plo@am__quote@
...@@ -5124,6 +5126,13 @@ write.lo: io/write.c ...@@ -5124,6 +5126,13 @@ write.lo: io/write.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o write.lo `test -f 'io/write.c' || echo '$(srcdir)/'`io/write.c @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o write.lo `test -f 'io/write.c' || echo '$(srcdir)/'`io/write.c
fbuf.lo: io/fbuf.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fbuf.lo -MD -MP -MF "$(DEPDIR)/fbuf.Tpo" -c -o fbuf.lo `test -f 'io/fbuf.c' || echo '$(srcdir)/'`io/fbuf.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/fbuf.Tpo" "$(DEPDIR)/fbuf.Plo"; else rm -f "$(DEPDIR)/fbuf.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io/fbuf.c' object='fbuf.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fbuf.lo `test -f 'io/fbuf.c' || echo '$(srcdir)/'`io/fbuf.c
associated.lo: intrinsics/associated.c associated.lo: intrinsics/associated.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT associated.lo -MD -MP -MF "$(DEPDIR)/associated.Tpo" -c -o associated.lo `test -f 'intrinsics/associated.c' || echo '$(srcdir)/'`intrinsics/associated.c; \ @am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT associated.lo -MD -MP -MF "$(DEPDIR)/associated.Tpo" -c -o associated.lo `test -f 'intrinsics/associated.c' || echo '$(srcdir)/'`intrinsics/associated.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/associated.Tpo" "$(DEPDIR)/associated.Plo"; else rm -f "$(DEPDIR)/associated.Tpo"; exit 1; fi @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/associated.Tpo" "$(DEPDIR)/associated.Plo"; else rm -f "$(DEPDIR)/associated.Tpo"; exit 1; fi
......
...@@ -39,14 +39,14 @@ Boston, MA 02110-1301, USA. */ ...@@ -39,14 +39,14 @@ Boston, MA 02110-1301, USA. */
record, and we have to sift backwards to find the newline before record, and we have to sift backwards to find the newline before
that or the start of the file, whichever comes first. */ that or the start of the file, whichever comes first. */
#define READ_CHUNK 4096 static const unsigned int READ_CHUNK = 4096;
static void static void
formatted_backspace (st_parameter_filepos *fpp, gfc_unit *u) formatted_backspace (st_parameter_filepos *fpp, gfc_unit *u)
{ {
gfc_offset base; gfc_offset base;
char *p; char p[READ_CHUNK];
int n; size_t n;
base = file_position (u->s) - 1; base = file_position (u->s) - 1;
...@@ -54,9 +54,9 @@ formatted_backspace (st_parameter_filepos *fpp, gfc_unit *u) ...@@ -54,9 +54,9 @@ formatted_backspace (st_parameter_filepos *fpp, gfc_unit *u)
{ {
n = (base < READ_CHUNK) ? base : READ_CHUNK; n = (base < READ_CHUNK) ? base : READ_CHUNK;
base -= n; base -= n;
if (sseek (u->s, base) == FAILURE)
p = salloc_r_at (u->s, &n, base); goto io_error;
if (p == NULL) if (sread (u->s, p, &n) != 0)
goto io_error; goto io_error;
/* We have moved backwards from the current position, it should /* We have moved backwards from the current position, it should
...@@ -66,15 +66,14 @@ formatted_backspace (st_parameter_filepos *fpp, gfc_unit *u) ...@@ -66,15 +66,14 @@ formatted_backspace (st_parameter_filepos *fpp, gfc_unit *u)
/* There is no memrchr() in the C library, so we have to do it /* There is no memrchr() in the C library, so we have to do it
ourselves. */ ourselves. */
n--; while (n > 0)
while (n >= 0)
{ {
n--;
if (p[n] == '\n') if (p[n] == '\n')
{ {
base += n + 1; base += n + 1;
goto done; goto done;
} }
n--;
} }
} }
...@@ -104,9 +103,9 @@ unformatted_backspace (st_parameter_filepos *fpp, gfc_unit *u) ...@@ -104,9 +103,9 @@ unformatted_backspace (st_parameter_filepos *fpp, gfc_unit *u)
gfc_offset m, new; gfc_offset m, new;
GFC_INTEGER_4 m4; GFC_INTEGER_4 m4;
GFC_INTEGER_8 m8; GFC_INTEGER_8 m8;
int length, length_read; size_t length;
int continued; int continued;
char *p; char p[sizeof (GFC_INTEGER_8)];
if (compile_options.record_marker == 0) if (compile_options.record_marker == 0)
length = sizeof (GFC_INTEGER_4); length = sizeof (GFC_INTEGER_4);
...@@ -115,12 +114,10 @@ unformatted_backspace (st_parameter_filepos *fpp, gfc_unit *u) ...@@ -115,12 +114,10 @@ unformatted_backspace (st_parameter_filepos *fpp, gfc_unit *u)
do do
{ {
length_read = length; if (sseek (u->s, file_position (u->s) - length) == FAILURE)
goto io_error;
p = salloc_r_at (u->s, &length_read, if (sread (u->s, p, &length) != 0)
file_position (u->s) - length); goto io_error;
if (p == NULL || length_read != length)
goto io_error;
/* Only GFC_CONVERT_NATIVE and GFC_CONVERT_SWAP are valid here. */ /* Only GFC_CONVERT_NATIVE and GFC_CONVERT_SWAP are valid here. */
if (u->flags.convert == GFC_CONVERT_NATIVE) if (u->flags.convert == GFC_CONVERT_NATIVE)
...@@ -216,6 +213,9 @@ st_backspace (st_parameter_filepos *fpp) ...@@ -216,6 +213,9 @@ st_backspace (st_parameter_filepos *fpp)
goto done; goto done;
} }
/* Make sure format buffer is flushed. */
fbuf_flush (u, 1);
/* Check for special cases involving the ENDFILE record first. */ /* Check for special cases involving the ENDFILE record first. */
if (u->endfile == AFTER_ENDFILE) if (u->endfile == AFTER_ENDFILE)
......
...@@ -49,8 +49,7 @@ struct st_parameter_dt; ...@@ -49,8 +49,7 @@ struct st_parameter_dt;
typedef struct stream typedef struct stream
{ {
char *(*alloc_w_at) (struct stream *, int *, gfc_offset); char *(*alloc_w_at) (struct stream *, int *);
char *(*alloc_r_at) (struct stream *, int *, gfc_offset);
try (*sfree) (struct stream *); try (*sfree) (struct stream *);
try (*close) (struct stream *); try (*close) (struct stream *);
try (*seek) (struct stream *, gfc_offset); try (*seek) (struct stream *, gfc_offset);
...@@ -70,11 +69,7 @@ io_mode; ...@@ -70,11 +69,7 @@ io_mode;
#define sfree(s) ((s)->sfree)(s) #define sfree(s) ((s)->sfree)(s)
#define sclose(s) ((s)->close)(s) #define sclose(s) ((s)->close)(s)
#define salloc_r(s, len) ((s)->alloc_r_at)(s, len, -1) #define salloc_w(s, len) ((s)->alloc_w_at)(s, len)
#define salloc_w(s, len) ((s)->alloc_w_at)(s, len, -1)
#define salloc_r_at(s, len, where) ((s)->alloc_r_at)(s, len, where)
#define salloc_w_at(s, len, where) ((s)->alloc_w_at)(s, len, where)
#define sseek(s, pos) ((s)->seek)(s, pos) #define sseek(s, pos) ((s)->seek)(s, pos)
#define struncate(s) ((s)->trunc)(s) #define struncate(s) ((s)->trunc)(s)
...@@ -528,6 +523,25 @@ typedef struct ...@@ -528,6 +523,25 @@ typedef struct
unit_flags; unit_flags;
/* Formatting buffer. This is a temporary scratch buffer. Currently used only
by formatted writes. After every
formatted write statement, this buffer is flushed. This buffer is needed since
not all devices are seekable, and T or TL edit descriptors require
moving backwards in the record. However, advance='no' complicates the
situation, so the buffer must only be partially flushed from the end of the
last flush until the current position in the record. */
typedef struct fbuf
{
char *buf; /* Start of buffer. */
size_t len; /* Length of buffer. */
size_t act; /* Active bytes in buffer. */
size_t flushed; /* Flushed bytes from beginning of buffer. */
char *ptr; /* Current position in buffer. */
}
fbuf;
typedef struct gfc_unit typedef struct gfc_unit
{ {
int unit_number; int unit_number;
...@@ -578,6 +592,9 @@ typedef struct gfc_unit ...@@ -578,6 +592,9 @@ typedef struct gfc_unit
int file_len; int file_len;
char *file; char *file;
/* Formatting buffer. */
struct fbuf *fbuf;
} }
gfc_unit; gfc_unit;
...@@ -812,8 +829,8 @@ internal_proto(free_format_data); ...@@ -812,8 +829,8 @@ internal_proto(free_format_data);
extern const char *type_name (bt); extern const char *type_name (bt);
internal_proto(type_name); internal_proto(type_name);
extern void *read_block (st_parameter_dt *, int *); extern try read_block_form (st_parameter_dt *, void *, size_t *);
internal_proto(read_block); internal_proto(read_block_form);
extern char *read_sf (st_parameter_dt *, int *, int); extern char *read_sf (st_parameter_dt *, int *, int);
internal_proto(read_sf); internal_proto(read_sf);
...@@ -931,6 +948,25 @@ internal_proto(size_from_real_kind); ...@@ -931,6 +948,25 @@ internal_proto(size_from_real_kind);
extern size_t size_from_complex_kind (int); extern size_t size_from_complex_kind (int);
internal_proto(size_from_complex_kind); internal_proto(size_from_complex_kind);
/* fbuf.c */
extern void fbuf_init (gfc_unit *, size_t);
internal_proto(fbuf_init);
extern void fbuf_destroy (gfc_unit *);
internal_proto(fbuf_destroy);
extern void fbuf_reset (gfc_unit *);
internal_proto(fbuf_reset);
extern char * fbuf_alloc (gfc_unit *, size_t);
internal_proto(fbuf_alloc);
extern int fbuf_flush (gfc_unit *, int);
internal_proto(fbuf_flush);
extern int fbuf_seek (gfc_unit *, gfc_offset);
internal_proto(fbuf_seek);
/* lock.c */ /* lock.c */
extern void free_ionml (st_parameter_dt *); extern void free_ionml (st_parameter_dt *);
internal_proto(free_ionml); internal_proto(free_ionml);
......
...@@ -140,9 +140,9 @@ free_line (st_parameter_dt *dtp) ...@@ -140,9 +140,9 @@ free_line (st_parameter_dt *dtp)
static char static char
next_char (st_parameter_dt *dtp) next_char (st_parameter_dt *dtp)
{ {
int length; size_t length;
gfc_offset record; gfc_offset record;
char c, *p; char c;
if (dtp->u.p.last_char != '\0') if (dtp->u.p.last_char != '\0')
{ {
...@@ -206,43 +206,40 @@ next_char (st_parameter_dt *dtp) ...@@ -206,43 +206,40 @@ next_char (st_parameter_dt *dtp)
length = 1; length = 1;
p = salloc_r (dtp->u.p.current_unit->s, &length); if (sread (dtp->u.p.current_unit->s, &c, &length) != 0)
{
generate_error (&dtp->common, LIBERROR_OS, NULL);
return '\0';
}
if (is_stream_io (dtp)) if (is_stream_io (dtp) && length == 1)
dtp->u.p.current_unit->strm_pos++; dtp->u.p.current_unit->strm_pos++;
if (is_internal_unit (dtp)) if (is_internal_unit (dtp))
{ {
if (is_array_io (dtp)) if (is_array_io (dtp))
{ {
/* End of record is handled in the next pass through, above. The /* Check whether we hit EOF. */
check for NULL here is cautionary. */ if (length == 0)
if (p == NULL)
{ {
generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL); generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
return '\0'; return '\0';
} }
dtp->u.p.current_unit->bytes_left--; dtp->u.p.current_unit->bytes_left--;
c = *p;
} }
else else
{ {
if (p == NULL) if (dtp->u.p.at_eof)
longjmp (*dtp->u.p.eof_jump, 1); longjmp (*dtp->u.p.eof_jump, 1);
if (length == 0) if (length == 0)
c = '\n'; {
else c = '\n';
c = *p; dtp->u.p.at_eof = 1;
}
} }
} }
else else
{ {
if (p == NULL)
{
generate_error (&dtp->common, LIBERROR_OS, NULL);
return '\0';
}
if (length == 0) if (length == 0)
{ {
if (dtp->u.p.advance_status == ADVANCE_NO) if (dtp->u.p.advance_status == ADVANCE_NO)
...@@ -255,8 +252,6 @@ next_char (st_parameter_dt *dtp) ...@@ -255,8 +252,6 @@ next_char (st_parameter_dt *dtp)
else else
longjmp (*dtp->u.p.eof_jump, 1); longjmp (*dtp->u.p.eof_jump, 1);
} }
else
c = *p;
} }
done: done:
dtp->u.p.at_eol = (c == '\n' || c == '\r'); dtp->u.p.at_eol = (c == '\n' || c == '\r');
...@@ -2226,6 +2221,15 @@ nml_query (st_parameter_dt *dtp, char c) ...@@ -2226,6 +2221,15 @@ nml_query (st_parameter_dt *dtp, char c)
namelist_info * nl; namelist_info * nl;
index_type len; index_type len;
char * p; char * p;
#ifdef HAVE_CRLF
static const index_type endlen = 3;
static const char endl[] = "\r\n";
static const char nmlend[] = "&end\r\n";
#else
static const index_type endlen = 2;
static const char endl[] = "\n";
static const char nmlend[] = "&end\n";
#endif
if (dtp->u.p.current_unit->unit_number != options.stdin_unit) if (dtp->u.p.current_unit->unit_number != options.stdin_unit)
return; return;
...@@ -2252,59 +2256,35 @@ nml_query (st_parameter_dt *dtp, char c) ...@@ -2252,59 +2256,35 @@ nml_query (st_parameter_dt *dtp, char c)
/* "&namelist_name\n" */ /* "&namelist_name\n" */
len = dtp->namelist_name_len; len = dtp->namelist_name_len;
#ifdef HAVE_CRLF p = write_block (dtp, len + endlen);
p = write_block (dtp, len + 3); if (!p)
#else goto query_return;
p = write_block (dtp, len + 2);
#endif
if (!p)
goto query_return;
memcpy (p, "&", 1); memcpy (p, "&", 1);
memcpy ((char*)(p + 1), dtp->namelist_name, len); memcpy ((char*)(p + 1), dtp->namelist_name, len);
#ifdef HAVE_CRLF memcpy ((char*)(p + len + 1), &endl, endlen - 1);
memcpy ((char*)(p + len + 1), "\r\n", 2);
#else
memcpy ((char*)(p + len + 1), "\n", 1);
#endif
for (nl = dtp->u.p.ionml; nl; nl = nl->next) for (nl = dtp->u.p.ionml; nl; nl = nl->next)
{ {
/* " var_name\n" */ /* " var_name\n" */
len = strlen (nl->var_name); len = strlen (nl->var_name);
#ifdef HAVE_CRLF p = write_block (dtp, len + endlen);
p = write_block (dtp, len + 3);
#else
p = write_block (dtp, len + 2);
#endif
if (!p) if (!p)
goto query_return; goto query_return;
memcpy (p, " ", 1); memcpy (p, " ", 1);
memcpy ((char*)(p + 1), nl->var_name, len); memcpy ((char*)(p + 1), nl->var_name, len);
#ifdef HAVE_CRLF memcpy ((char*)(p + len + 1), &endl, endlen - 1);
memcpy ((char*)(p + len + 1), "\r\n", 2);
#else
memcpy ((char*)(p + len + 1), "\n", 1);
#endif
} }
/* "&end\n" */ /* "&end\n" */
#ifdef HAVE_CRLF p = write_block (dtp, endlen + 3);
p = write_block (dtp, 6);
#else
p = write_block (dtp, 5);
#endif
if (!p)
goto query_return; goto query_return;
#ifdef HAVE_CRLF memcpy (p, &nmlend, endlen + 3);
memcpy (p, "&end\r\n", 6);
#else
memcpy (p, "&end\n", 5);
#endif
} }
/* Flush the stream to force immediate output. */ /* Flush the stream to force immediate output. */
fbuf_flush (dtp->u.p.current_unit, 1);
flush (dtp->u.p.current_unit->s); flush (dtp->u.p.current_unit->s);
unlock_unit (dtp->u.p.current_unit); unlock_unit (dtp->u.p.current_unit);
} }
......
...@@ -626,6 +626,13 @@ new_unit (st_parameter_open *opp, gfc_unit *u, unit_flags * flags) ...@@ -626,6 +626,13 @@ new_unit (st_parameter_open *opp, gfc_unit *u, unit_flags * flags)
if (flags->status == STATUS_SCRATCH && opp->file != NULL) if (flags->status == STATUS_SCRATCH && opp->file != NULL)
free_mem (opp->file); free_mem (opp->file);
if (flags->form == FORM_FORMATTED && (flags->action != ACTION_READ))
fbuf_init (u, 0);
else
u->fbuf = NULL;
return u; return u;
cleanup: cleanup:
......
...@@ -36,6 +36,7 @@ Boston, MA 02110-1301, USA. */ ...@@ -36,6 +36,7 @@ Boston, MA 02110-1301, USA. */
/* read.c -- Deal with formatted reads */ /* read.c -- Deal with formatted reads */
/* set_integer()-- All of the integer assignments come here to /* set_integer()-- All of the integer assignments come here to
* actually place the value into memory. */ * actually place the value into memory. */
...@@ -192,11 +193,13 @@ void ...@@ -192,11 +193,13 @@ void
read_l (st_parameter_dt *dtp, const fnode *f, char *dest, int length) read_l (st_parameter_dt *dtp, const fnode *f, char *dest, int length)
{ {
char *p; char *p;
int w; size_t w;
w = f->u.w; w = f->u.w;
p = read_block (dtp, &w);
if (p == NULL) p = gfc_alloca (w);
if (read_block_form (dtp, p, &w) == FAILURE)
return; return;
while (*p == ' ') while (*p == ' ')
...@@ -238,24 +241,29 @@ read_l (st_parameter_dt *dtp, const fnode *f, char *dest, int length) ...@@ -238,24 +241,29 @@ read_l (st_parameter_dt *dtp, const fnode *f, char *dest, int length)
void void
read_a (st_parameter_dt *dtp, const fnode *f, char *p, int length) read_a (st_parameter_dt *dtp, const fnode *f, char *p, int length)
{ {
char *source; char *s;
int w, m, n; int m, n, wi, status;
size_t w;
w = f->u.w; wi = f->u.w;
if (w == -1) /* '(A)' edit descriptor */ if (wi == -1) /* '(A)' edit descriptor */
w = length; wi = length;
w = wi;
s = gfc_alloca (w);
dtp->u.p.sf_read_comma = 0; dtp->u.p.sf_read_comma = 0;
source = read_block (dtp, &w); status = read_block_form (dtp, s, &w);
dtp->u.p.sf_read_comma = dtp->u.p.sf_read_comma =
dtp->u.p.decimal_status == DECIMAL_COMMA ? 0 : 1; dtp->u.p.decimal_status == DECIMAL_COMMA ? 0 : 1;
if (source == NULL) if (status == FAILURE)
return; return;
if (w > length) if (w > (size_t) length)
source += (w - length); s += (w - length);
m = (w > length) ? length : w; m = ((int) w > length) ? length : (int) w;
memcpy (p, source, m); memcpy (p, s, m);
n = length - w; n = length - w;
if (n > 0) if (n > 0)
...@@ -323,14 +331,19 @@ read_decimal (st_parameter_dt *dtp, const fnode *f, char *dest, int length) ...@@ -323,14 +331,19 @@ read_decimal (st_parameter_dt *dtp, const fnode *f, char *dest, int length)
{ {
GFC_UINTEGER_LARGEST value, maxv, maxv_10; GFC_UINTEGER_LARGEST value, maxv, maxv_10;
GFC_INTEGER_LARGEST v; GFC_INTEGER_LARGEST v;
int w, negative; int w, negative;
size_t wu;
char c, *p; char c, *p;
w = f->u.w; wu = f->u.w;
p = read_block (dtp, &w);
if (p == NULL) p = gfc_alloca (wu);
if (read_block_form (dtp, p, &wu) == FAILURE)
return; return;
w = wu;
p = eat_leading_spaces (&w, p); p = eat_leading_spaces (&w, p);
if (w == 0) if (w == 0)
{ {
...@@ -406,7 +419,7 @@ read_decimal (st_parameter_dt *dtp, const fnode *f, char *dest, int length) ...@@ -406,7 +419,7 @@ read_decimal (st_parameter_dt *dtp, const fnode *f, char *dest, int length)
generate_error (&dtp->common, LIBERROR_READ_OVERFLOW, generate_error (&dtp->common, LIBERROR_READ_OVERFLOW,
"Value overflowed during integer read"); "Value overflowed during integer read");
next_record (dtp, 1); next_record (dtp, 1);
return;
} }
...@@ -423,12 +436,17 @@ read_radix (st_parameter_dt *dtp, const fnode *f, char *dest, int length, ...@@ -423,12 +436,17 @@ read_radix (st_parameter_dt *dtp, const fnode *f, char *dest, int length,
GFC_INTEGER_LARGEST v; GFC_INTEGER_LARGEST v;
int w, negative; int w, negative;
char c, *p; char c, *p;
size_t wu;
w = f->u.w; wu = f->u.w;
p = read_block (dtp, &w);
if (p == NULL) p = gfc_alloca (wu);
if (read_block_form (dtp, p, &wu) == FAILURE)
return; return;
w = wu;
p = eat_leading_spaces (&w, p); p = eat_leading_spaces (&w, p);
if (w == 0) if (w == 0)
{ {
...@@ -552,7 +570,7 @@ read_radix (st_parameter_dt *dtp, const fnode *f, char *dest, int length, ...@@ -552,7 +570,7 @@ read_radix (st_parameter_dt *dtp, const fnode *f, char *dest, int length,
generate_error (&dtp->common, LIBERROR_READ_OVERFLOW, generate_error (&dtp->common, LIBERROR_READ_OVERFLOW,
"Value overflowed during integer read"); "Value overflowed during integer read");
next_record (dtp, 1); next_record (dtp, 1);
return;
} }
...@@ -565,6 +583,7 @@ read_radix (st_parameter_dt *dtp, const fnode *f, char *dest, int length, ...@@ -565,6 +583,7 @@ read_radix (st_parameter_dt *dtp, const fnode *f, char *dest, int length,
void void
read_f (st_parameter_dt *dtp, const fnode *f, char *dest, int length) read_f (st_parameter_dt *dtp, const fnode *f, char *dest, int length)
{ {
size_t wu;
int w, seen_dp, exponent; int w, seen_dp, exponent;
int exponent_sign, val_sign; int exponent_sign, val_sign;
int ndigits; int ndigits;
...@@ -576,11 +595,15 @@ read_f (st_parameter_dt *dtp, const fnode *f, char *dest, int length) ...@@ -576,11 +595,15 @@ read_f (st_parameter_dt *dtp, const fnode *f, char *dest, int length)
val_sign = 1; val_sign = 1;
seen_dp = 0; seen_dp = 0;
w = f->u.w; wu = f->u.w;
p = read_block (dtp, &w);
if (p == NULL) p = gfc_alloca (wu);
if (read_block_form (dtp, p, &wu) == FAILURE)
return; return;
w = wu;
p = eat_leading_spaces (&w, p); p = eat_leading_spaces (&w, p);
if (w == 0) if (w == 0)
goto zero; goto zero;
...@@ -842,7 +865,6 @@ read_f (st_parameter_dt *dtp, const fnode *f, char *dest, int length) ...@@ -842,7 +865,6 @@ read_f (st_parameter_dt *dtp, const fnode *f, char *dest, int length)
if (buffer != scratch) if (buffer != scratch)
free_mem (buffer); free_mem (buffer);
return;
} }
...@@ -850,19 +872,16 @@ read_f (st_parameter_dt *dtp, const fnode *f, char *dest, int length) ...@@ -850,19 +872,16 @@ read_f (st_parameter_dt *dtp, const fnode *f, char *dest, int length)
* and never look at it. */ * and never look at it. */
void void
read_x (st_parameter_dt *dtp, int n) read_x (st_parameter_dt * dtp, int n)
{ {
if (!is_stream_io (dtp)) if ((dtp->u.p.pad_status == PAD_NO || is_internal_unit (dtp))
{ && dtp->u.p.current_unit->bytes_left < n)
if ((dtp->u.p.pad_status == PAD_NO || is_internal_unit (dtp)) n = dtp->u.p.current_unit->bytes_left;
&& dtp->u.p.current_unit->bytes_left < n)
n = dtp->u.p.current_unit->bytes_left; dtp->u.p.sf_read_comma = 0;
if (n > 0)
dtp->u.p.sf_read_comma = 0; read_sf (dtp, &n, 1);
if (n > 0) dtp->u.p.sf_read_comma = 1;
read_sf (dtp, &n, 1); dtp->u.p.current_unit->strm_pos += (gfc_offset) n;
dtp->u.p.sf_read_comma = 1;
}
else
dtp->u.p.current_unit->strm_pos += (gfc_offset) n;
} }
...@@ -36,6 +36,7 @@ Boston, MA 02110-1301, USA. */ ...@@ -36,6 +36,7 @@ Boston, MA 02110-1301, USA. */
#include "io.h" #include "io.h"
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <stdlib.h>
/* Calling conventions: Data transfer statements are unlike other /* Calling conventions: Data transfer statements are unlike other
...@@ -180,9 +181,10 @@ current_mode (st_parameter_dt *dtp) ...@@ -180,9 +181,10 @@ current_mode (st_parameter_dt *dtp)
char * char *
read_sf (st_parameter_dt *dtp, int *length, int no_error) read_sf (st_parameter_dt *dtp, int *length, int no_error)
{ {
char *base, *p, *q; char *base, *p, q;
int n, readlen, crlf; int n, crlf;
gfc_offset pos; gfc_offset pos;
size_t readlen;
if (*length > SCRATCH_SIZE) if (*length > SCRATCH_SIZE)
dtp->u.p.line_buffer = get_mem (*length); dtp->u.p.line_buffer = get_mem (*length);
...@@ -199,15 +201,12 @@ read_sf (st_parameter_dt *dtp, int *length, int no_error) ...@@ -199,15 +201,12 @@ read_sf (st_parameter_dt *dtp, int *length, int no_error)
if (is_internal_unit (dtp)) if (is_internal_unit (dtp))
{ {
readlen = *length; readlen = *length;
q = salloc_r (dtp->u.p.current_unit->s, &readlen); if (sread (dtp->u.p.current_unit->s, p, &readlen) != 0 || readlen < (size_t) *length)
if (readlen < *length)
{ {
generate_error (&dtp->common, LIBERROR_END, NULL); generate_error (&dtp->common, LIBERROR_END, NULL);
return NULL; return NULL;
} }
if (q != NULL)
memcpy (p, q, readlen);
goto done; goto done;
} }
...@@ -216,9 +215,11 @@ read_sf (st_parameter_dt *dtp, int *length, int no_error) ...@@ -216,9 +215,11 @@ read_sf (st_parameter_dt *dtp, int *length, int no_error)
do do
{ {
q = salloc_r (dtp->u.p.current_unit->s, &readlen); if (sread (dtp->u.p.current_unit->s, &q, &readlen) != 0)
if (q == NULL) {
break; generate_error (&dtp->common, LIBERROR_END, NULL);
return NULL;
}
/* If we have a line without a terminating \n, drop through to /* If we have a line without a terminating \n, drop through to
EOR below. */ EOR below. */
...@@ -230,7 +231,7 @@ read_sf (st_parameter_dt *dtp, int *length, int no_error) ...@@ -230,7 +231,7 @@ read_sf (st_parameter_dt *dtp, int *length, int no_error)
return NULL; return NULL;
} }
if (readlen < 1 || *q == '\n' || *q == '\r') if (readlen < 1 || q == '\n' || q == '\r')
{ {
/* Unexpected end of line. */ /* Unexpected end of line. */
...@@ -241,12 +242,16 @@ read_sf (st_parameter_dt *dtp, int *length, int no_error) ...@@ -241,12 +242,16 @@ read_sf (st_parameter_dt *dtp, int *length, int no_error)
crlf = 0; crlf = 0;
/* If we encounter a CR, it might be a CRLF. */ /* If we encounter a CR, it might be a CRLF. */
if (*q == '\r') /* Probably a CRLF */ if (q == '\r') /* Probably a CRLF */
{ {
readlen = 1; readlen = 1;
pos = stream_offset (dtp->u.p.current_unit->s); pos = stream_offset (dtp->u.p.current_unit->s);
q = salloc_r (dtp->u.p.current_unit->s, &readlen); if (sread (dtp->u.p.current_unit->s, &q, &readlen) != 0)
if (*q != '\n' && readlen == 1) /* Not a CRLF after all. */ {
generate_error (&dtp->common, LIBERROR_END, NULL);
return NULL;
}
if (q != '\n' && readlen == 1) /* Not a CRLF after all. */
sseek (dtp->u.p.current_unit->s, pos); sseek (dtp->u.p.current_unit->s, pos);
else else
crlf = 1; crlf = 1;
...@@ -270,7 +275,7 @@ read_sf (st_parameter_dt *dtp, int *length, int no_error) ...@@ -270,7 +275,7 @@ read_sf (st_parameter_dt *dtp, int *length, int no_error)
/* Short circuit the read if a comma is found during numeric input. /* Short circuit the read if a comma is found during numeric input.
The flag is set to zero during character reads so that commas in The flag is set to zero during character reads so that commas in
strings are not ignored */ strings are not ignored */
if (*q == ',') if (q == ',')
if (dtp->u.p.sf_read_comma == 1) if (dtp->u.p.sf_read_comma == 1)
{ {
notify_std (&dtp->common, GFC_STD_GNU, notify_std (&dtp->common, GFC_STD_GNU,
...@@ -280,7 +285,7 @@ read_sf (st_parameter_dt *dtp, int *length, int no_error) ...@@ -280,7 +285,7 @@ read_sf (st_parameter_dt *dtp, int *length, int no_error)
} }
n++; n++;
*p++ = *q; *p++ = q;
dtp->u.p.sf_seen_eor = 0; dtp->u.p.sf_seen_eor = 0;
} }
while (n < *length); while (n < *length);
...@@ -296,35 +301,25 @@ read_sf (st_parameter_dt *dtp, int *length, int no_error) ...@@ -296,35 +301,25 @@ read_sf (st_parameter_dt *dtp, int *length, int no_error)
/* Function for reading the next couple of bytes from the current /* Function for reading the next couple of bytes from the current
file, advancing the current position. We return a pointer to a file, advancing the current position. We return FAILURE on end of record or
buffer containing the bytes. We return NULL on end of record or end of file. This function is only for formatted I/O, unformatted uses
end of file. read_block_direct.
If the read is short, then it is because the current record does not If the read is short, then it is because the current record does not
have enough data to satisfy the read request and the file was have enough data to satisfy the read request and the file was
opened with PAD=YES. The caller must assume tailing spaces for opened with PAD=YES. The caller must assume tailing spaces for
short reads. */ short reads. */
void * try
read_block (st_parameter_dt *dtp, int *length) read_block_form (st_parameter_dt *dtp, void *buf, size_t *nbytes)
{ {
char *source; char *source;
int nread; size_t nread;
int nb;
if (is_stream_io (dtp)) if (!is_stream_io (dtp))
{
if (dtp->u.p.current_unit->strm_pos - 1
!= file_position (dtp->u.p.current_unit->s)
&& sseek (dtp->u.p.current_unit->s,
dtp->u.p.current_unit->strm_pos - 1) == FAILURE)
{
generate_error (&dtp->common, LIBERROR_END, NULL);
return NULL;
}
}
else
{ {
if (dtp->u.p.current_unit->bytes_left < (gfc_offset) *length) if (dtp->u.p.current_unit->bytes_left < (gfc_offset) *nbytes)
{ {
/* For preconnected units with default record length, set bytes left /* For preconnected units with default record length, set bytes left
to unit record length and proceed, otherwise error. */ to unit record length and proceed, otherwise error. */
...@@ -337,7 +332,7 @@ read_block (st_parameter_dt *dtp, int *length) ...@@ -337,7 +332,7 @@ read_block (st_parameter_dt *dtp, int *length)
{ {
/* Not enough data left. */ /* Not enough data left. */
generate_error (&dtp->common, LIBERROR_EOR, NULL); generate_error (&dtp->common, LIBERROR_EOR, NULL);
return NULL; return FAILURE;
} }
} }
...@@ -345,10 +340,10 @@ read_block (st_parameter_dt *dtp, int *length) ...@@ -345,10 +340,10 @@ read_block (st_parameter_dt *dtp, int *length)
{ {
dtp->u.p.current_unit->endfile = AT_ENDFILE; dtp->u.p.current_unit->endfile = AT_ENDFILE;
generate_error (&dtp->common, LIBERROR_END, NULL); generate_error (&dtp->common, LIBERROR_END, NULL);
return NULL; return FAILURE;
} }
*length = dtp->u.p.current_unit->bytes_left; *nbytes = dtp->u.p.current_unit->bytes_left;
} }
} }
...@@ -356,23 +351,32 @@ read_block (st_parameter_dt *dtp, int *length) ...@@ -356,23 +351,32 @@ read_block (st_parameter_dt *dtp, int *length)
(dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL || (dtp->u.p.current_unit->flags.access == ACCESS_SEQUENTIAL ||
dtp->u.p.current_unit->flags.access == ACCESS_STREAM)) dtp->u.p.current_unit->flags.access == ACCESS_STREAM))
{ {
source = read_sf (dtp, length, 0); nb = *nbytes;
source = read_sf (dtp, &nb, 0);
*nbytes = nb;
dtp->u.p.current_unit->strm_pos += dtp->u.p.current_unit->strm_pos +=
(gfc_offset) (*length + dtp->u.p.sf_seen_eor); (gfc_offset) (*nbytes + dtp->u.p.sf_seen_eor);
return source; if (source == NULL)
return FAILURE;
memcpy (buf, source, *nbytes);
return SUCCESS;
} }
dtp->u.p.current_unit->bytes_left -= (gfc_offset) *length; dtp->u.p.current_unit->bytes_left -= (gfc_offset) *nbytes;
nread = *length; nread = *nbytes;
source = salloc_r (dtp->u.p.current_unit->s, &nread); if (sread (dtp->u.p.current_unit->s, buf, &nread) != 0)
{
generate_error (&dtp->common, LIBERROR_OS, NULL);
return FAILURE;
}
if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0) if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
dtp->u.p.size_used += (gfc_offset) nread; dtp->u.p.size_used += (gfc_offset) nread;
if (nread != *length) if (nread != *nbytes)
{ /* Short read, this shouldn't happen. */ { /* Short read, this shouldn't happen. */
if (dtp->u.p.pad_status == PAD_YES) if (dtp->u.p.pad_status == PAD_YES)
*length = nread; *nbytes = nread;
else else
{ {
generate_error (&dtp->common, LIBERROR_EOR, NULL); generate_error (&dtp->common, LIBERROR_EOR, NULL);
...@@ -382,7 +386,7 @@ read_block (st_parameter_dt *dtp, int *length) ...@@ -382,7 +386,7 @@ read_block (st_parameter_dt *dtp, int *length)
dtp->u.p.current_unit->strm_pos += (gfc_offset) nread; dtp->u.p.current_unit->strm_pos += (gfc_offset) nread;
return source; return SUCCESS;
} }
...@@ -400,15 +404,6 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes) ...@@ -400,15 +404,6 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
if (is_stream_io (dtp)) if (is_stream_io (dtp))
{ {
if (dtp->u.p.current_unit->strm_pos - 1
!= file_position (dtp->u.p.current_unit->s)
&& sseek (dtp->u.p.current_unit->s,
dtp->u.p.current_unit->strm_pos - 1) == FAILURE)
{
generate_error (&dtp->common, LIBERROR_END, NULL);
return;
}
to_read_record = *nbytes; to_read_record = *nbytes;
have_read_record = to_read_record; have_read_record = to_read_record;
if (sread (dtp->u.p.current_unit->s, buf, &have_read_record) != 0) if (sread (dtp->u.p.current_unit->s, buf, &have_read_record) != 0)
...@@ -576,18 +571,7 @@ write_block (st_parameter_dt *dtp, int length) ...@@ -576,18 +571,7 @@ write_block (st_parameter_dt *dtp, int length)
{ {
char *dest; char *dest;
if (is_stream_io (dtp)) if (!is_stream_io (dtp))
{
if (dtp->u.p.current_unit->strm_pos - 1
!= file_position (dtp->u.p.current_unit->s)
&& sseek (dtp->u.p.current_unit->s,
dtp->u.p.current_unit->strm_pos - 1) == FAILURE)
{
generate_error (&dtp->common, LIBERROR_OS, NULL);
return NULL;
}
}
else
{ {
if (dtp->u.p.current_unit->bytes_left < (gfc_offset) length) if (dtp->u.p.current_unit->bytes_left < (gfc_offset) length)
{ {
...@@ -607,17 +591,29 @@ write_block (st_parameter_dt *dtp, int length) ...@@ -607,17 +591,29 @@ write_block (st_parameter_dt *dtp, int length)
dtp->u.p.current_unit->bytes_left -= (gfc_offset) length; dtp->u.p.current_unit->bytes_left -= (gfc_offset) length;
} }
dest = salloc_w (dtp->u.p.current_unit->s, &length); if (is_internal_unit (dtp))
if (dest == NULL)
{ {
generate_error (&dtp->common, LIBERROR_END, NULL); dest = salloc_w (dtp->u.p.current_unit->s, &length);
return NULL;
}
if (is_internal_unit (dtp) && dtp->u.p.current_unit->endfile == AT_ENDFILE) if (dest == NULL)
generate_error (&dtp->common, LIBERROR_END, NULL); {
generate_error (&dtp->common, LIBERROR_END, NULL);
return NULL;
}
if (dtp->u.p.current_unit->endfile == AT_ENDFILE)
generate_error (&dtp->common, LIBERROR_END, NULL);
}
else
{
dest = fbuf_alloc (dtp->u.p.current_unit, length);
if (dest == NULL)
{
generate_error (&dtp->common, LIBERROR_OS, NULL);
return NULL;
}
}
if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0) if ((dtp->common.flags & IOPARM_DT_HAS_SIZE) != 0)
dtp->u.p.size_used += (gfc_offset) length; dtp->u.p.size_used += (gfc_offset) length;
...@@ -642,15 +638,6 @@ write_buf (st_parameter_dt *dtp, void *buf, size_t nbytes) ...@@ -642,15 +638,6 @@ write_buf (st_parameter_dt *dtp, void *buf, size_t nbytes)
if (is_stream_io (dtp)) if (is_stream_io (dtp))
{ {
if (dtp->u.p.current_unit->strm_pos - 1
!= file_position (dtp->u.p.current_unit->s)
&& sseek (dtp->u.p.current_unit->s,
dtp->u.p.current_unit->strm_pos - 1) == FAILURE)
{
generate_error (&dtp->common, LIBERROR_OS, NULL);
return FAILURE;
}
if (swrite (dtp->u.p.current_unit->s, buf, &nbytes) != 0) if (swrite (dtp->u.p.current_unit->s, buf, &nbytes) != 0)
{ {
generate_error (&dtp->common, LIBERROR_OS, NULL); generate_error (&dtp->common, LIBERROR_OS, NULL);
...@@ -866,7 +853,7 @@ static void ...@@ -866,7 +853,7 @@ static void
write_constant_string (st_parameter_dt *dtp, const fnode *f) write_constant_string (st_parameter_dt *dtp, const fnode *f)
{ {
char c, delimiter, *p, *q; char c, delimiter, *p, *q;
int length; int length;
length = f->u.string.length; length = f->u.string.length;
if (length == 0) if (length == 0)
...@@ -875,7 +862,7 @@ write_constant_string (st_parameter_dt *dtp, const fnode *f) ...@@ -875,7 +862,7 @@ write_constant_string (st_parameter_dt *dtp, const fnode *f)
p = write_block (dtp, length); p = write_block (dtp, length);
if (p == NULL) if (p == NULL)
return; return;
q = f->u.string.p; q = f->u.string.p;
delimiter = q[-1]; delimiter = q[-1];
...@@ -993,7 +980,10 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int len, ...@@ -993,7 +980,10 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int len,
} }
if (dtp->u.p.skips < 0) if (dtp->u.p.skips < 0)
{ {
move_pos_offset (dtp->u.p.current_unit->s, dtp->u.p.skips); if (is_internal_unit (dtp))
move_pos_offset (dtp->u.p.current_unit->s, dtp->u.p.skips);
else
fbuf_seek (dtp->u.p.current_unit, dtp->u.p.skips);
dtp->u.p.current_unit->bytes_left -= (gfc_offset) dtp->u.p.skips; dtp->u.p.current_unit->bytes_left -= (gfc_offset) dtp->u.p.skips;
} }
dtp->u.p.skips = dtp->u.p.pending_spaces = 0; dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
...@@ -1606,9 +1596,7 @@ transfer_array (st_parameter_dt *dtp, gfc_array_char *desc, int kind, ...@@ -1606,9 +1596,7 @@ transfer_array (st_parameter_dt *dtp, gfc_array_char *desc, int kind,
static void static void
us_read (st_parameter_dt *dtp, int continued) us_read (st_parameter_dt *dtp, int continued)
{ {
char *p; size_t n, nr;
int n;
int nr;
GFC_INTEGER_4 i4; GFC_INTEGER_4 i4;
GFC_INTEGER_8 i8; GFC_INTEGER_8 i8;
gfc_offset i; gfc_offset i;
...@@ -1623,7 +1611,11 @@ us_read (st_parameter_dt *dtp, int continued) ...@@ -1623,7 +1611,11 @@ us_read (st_parameter_dt *dtp, int continued)
nr = n; nr = n;
p = salloc_r (dtp->u.p.current_unit->s, &n); if (sread (dtp->u.p.current_unit->s, &i, &n) != 0)
{
generate_error (&dtp->common, LIBERROR_BAD_US, NULL);
return;
}
if (n == 0) if (n == 0)
{ {
...@@ -1631,7 +1623,7 @@ us_read (st_parameter_dt *dtp, int continued) ...@@ -1631,7 +1623,7 @@ us_read (st_parameter_dt *dtp, int continued)
return; /* end of file */ return; /* end of file */
} }
if (p == NULL || n != nr) if (n != nr)
{ {
generate_error (&dtp->common, LIBERROR_BAD_US, NULL); generate_error (&dtp->common, LIBERROR_BAD_US, NULL);
return; return;
...@@ -1643,12 +1635,12 @@ us_read (st_parameter_dt *dtp, int continued) ...@@ -1643,12 +1635,12 @@ us_read (st_parameter_dt *dtp, int continued)
switch (nr) switch (nr)
{ {
case sizeof(GFC_INTEGER_4): case sizeof(GFC_INTEGER_4):
memcpy (&i4, p, sizeof (i4)); memcpy (&i4, &i, sizeof (i4));
i = i4; i = i4;
break; break;
case sizeof(GFC_INTEGER_8): case sizeof(GFC_INTEGER_8):
memcpy (&i8, p, sizeof (i8)); memcpy (&i8, &i, sizeof (i8));
i = i8; i = i8;
break; break;
...@@ -1661,12 +1653,12 @@ us_read (st_parameter_dt *dtp, int continued) ...@@ -1661,12 +1653,12 @@ us_read (st_parameter_dt *dtp, int continued)
switch (nr) switch (nr)
{ {
case sizeof(GFC_INTEGER_4): case sizeof(GFC_INTEGER_4):
reverse_memcpy (&i4, p, sizeof (i4)); reverse_memcpy (&i4, &i, sizeof (i4));
i = i4; i = i4;
break; break;
case sizeof(GFC_INTEGER_8): case sizeof(GFC_INTEGER_8):
reverse_memcpy (&i8, p, sizeof (i8)); reverse_memcpy (&i8, &i, sizeof (i8));
i = i8; i = i8;
break; break;
...@@ -1734,10 +1726,10 @@ pre_position (st_parameter_dt *dtp) ...@@ -1734,10 +1726,10 @@ pre_position (st_parameter_dt *dtp)
{ {
case FORMATTED_STREAM: case FORMATTED_STREAM:
case UNFORMATTED_STREAM: case UNFORMATTED_STREAM:
/* There are no records with stream I/O. Set the default position /* There are no records with stream I/O. If the position was specified
to the beginning of the file if no position was specified. */ data_transfer_init has already positioned the file. If no position
if ((dtp->common.flags & IOPARM_DT_HAS_REC) == 0) was specified, we continue from where we last left off. I.e.
dtp->u.p.current_unit->strm_pos = 1; there is nothing to do here. */
break; break;
case UNFORMATTED_SEQUENTIAL: case UNFORMATTED_SEQUENTIAL:
...@@ -2070,7 +2062,10 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag) ...@@ -2070,7 +2062,10 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag)
if (dtp->u.p.mode == READING if (dtp->u.p.mode == READING
&& dtp->u.p.current_unit->mode == WRITING && dtp->u.p.current_unit->mode == WRITING
&& !is_internal_unit (dtp)) && !is_internal_unit (dtp))
flush(dtp->u.p.current_unit->s); {
fbuf_flush (dtp->u.p.current_unit, 1);
flush(dtp->u.p.current_unit->s);
}
/* Check whether the record exists to be read. Only /* Check whether the record exists to be read. Only
a partial record needs to exist. */ a partial record needs to exist. */
...@@ -2094,11 +2089,21 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag) ...@@ -2094,11 +2089,21 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag)
} }
} }
else else
dtp->u.p.current_unit->strm_pos = dtp->rec; {
if (dtp->u.p.current_unit->strm_pos != dtp->rec)
{
fbuf_flush (dtp->u.p.current_unit, 1);
flush (dtp->u.p.current_unit->s);
if (sseek (dtp->u.p.current_unit->s, dtp->rec - 1) == FAILURE)
{
generate_error (&dtp->common, LIBERROR_OS, NULL);
return;
}
dtp->u.p.current_unit->strm_pos = dtp->rec;
}
}
} }
else
dtp->rec = 0;
/* Overwriting an existing sequential file ? /* Overwriting an existing sequential file ?
it is always safe to truncate the file on the first write */ it is always safe to truncate the file on the first write */
...@@ -2118,6 +2123,7 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag) ...@@ -2118,6 +2123,7 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag)
dtp->u.p.max_pos = dtp->u.p.current_unit->saved_pos; dtp->u.p.max_pos = dtp->u.p.current_unit->saved_pos;
pre_position (dtp); pre_position (dtp);
/* Set up the subroutine that will handle the transfers. */ /* Set up the subroutine that will handle the transfers. */
...@@ -2256,14 +2262,13 @@ next_array_record (st_parameter_dt *dtp, array_loop_spec *ls, int *finished) ...@@ -2256,14 +2262,13 @@ next_array_record (st_parameter_dt *dtp, array_loop_spec *ls, int *finished)
read chunks of size MAX_READ until we get to the right read chunks of size MAX_READ until we get to the right
position. */ position. */
#define MAX_READ 4096
static void static void
skip_record (st_parameter_dt *dtp, size_t bytes) skip_record (st_parameter_dt *dtp, size_t bytes)
{ {
gfc_offset new; gfc_offset new;
int rlength, length; size_t rlength;
char *p; static const size_t MAX_READ = 4096;
char p[MAX_READ];
dtp->u.p.current_unit->bytes_left_subrecord += bytes; dtp->u.p.current_unit->bytes_left_subrecord += bytes;
if (dtp->u.p.current_unit->bytes_left_subrecord == 0) if (dtp->u.p.current_unit->bytes_left_subrecord == 0)
...@@ -2283,24 +2288,22 @@ skip_record (st_parameter_dt *dtp, size_t bytes) ...@@ -2283,24 +2288,22 @@ skip_record (st_parameter_dt *dtp, size_t bytes)
{ /* Seek by reading data. */ { /* Seek by reading data. */
while (dtp->u.p.current_unit->bytes_left_subrecord > 0) while (dtp->u.p.current_unit->bytes_left_subrecord > 0)
{ {
rlength = length = rlength =
(MAX_READ > dtp->u.p.current_unit->bytes_left_subrecord) ? (MAX_READ > (size_t) dtp->u.p.current_unit->bytes_left_subrecord) ?
MAX_READ : dtp->u.p.current_unit->bytes_left_subrecord; MAX_READ : dtp->u.p.current_unit->bytes_left_subrecord;
p = salloc_r (dtp->u.p.current_unit->s, &rlength); if (sread (dtp->u.p.current_unit->s, p, &rlength) != 0)
if (p == NULL)
{ {
generate_error (&dtp->common, LIBERROR_OS, NULL); generate_error (&dtp->common, LIBERROR_OS, NULL);
return; return;
} }
dtp->u.p.current_unit->bytes_left_subrecord -= length; dtp->u.p.current_unit->bytes_left_subrecord -= rlength;
} }
} }
} }
#undef MAX_READ
/* Advance to the next record reading unformatted files, taking /* Advance to the next record reading unformatted files, taking
care of subrecords. If complete_record is nonzero, we loop care of subrecords. If complete_record is nonzero, we loop
...@@ -2328,14 +2331,23 @@ next_record_r_unf (st_parameter_dt *dtp, int complete_record) ...@@ -2328,14 +2331,23 @@ next_record_r_unf (st_parameter_dt *dtp, int complete_record)
} }
} }
static inline gfc_offset
min_off (gfc_offset a, gfc_offset b)
{
return (a < b ? a : b);
}
/* Space to the next record for read mode. */ /* Space to the next record for read mode. */
static void static void
next_record_r (st_parameter_dt *dtp) next_record_r (st_parameter_dt *dtp)
{ {
gfc_offset record; gfc_offset record;
int length, bytes_left; int bytes_left;
char *p; size_t length;
char p;
switch (current_mode (dtp)) switch (current_mode (dtp))
{ {
...@@ -2384,18 +2396,24 @@ next_record_r (st_parameter_dt *dtp) ...@@ -2384,18 +2396,24 @@ next_record_r (st_parameter_dt *dtp)
else else
{ {
bytes_left = (int) dtp->u.p.current_unit->bytes_left; bytes_left = (int) dtp->u.p.current_unit->bytes_left;
p = salloc_r (dtp->u.p.current_unit->s, &bytes_left); bytes_left = min_off (bytes_left,
if (p != NULL) file_length (dtp->u.p.current_unit->s)
dtp->u.p.current_unit->bytes_left - file_position (dtp->u.p.current_unit->s));
= dtp->u.p.current_unit->recl; if (sseek (dtp->u.p.current_unit->s,
file_position (dtp->u.p.current_unit->s)
+ bytes_left) == FAILURE)
{
generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
break;
}
dtp->u.p.current_unit->bytes_left
= dtp->u.p.current_unit->recl;
} }
break; break;
} }
else do else do
{ {
p = salloc_r (dtp->u.p.current_unit->s, &length); if (sread (dtp->u.p.current_unit->s, &p, &length) != 0)
if (p == NULL)
{ {
generate_error (&dtp->common, LIBERROR_OS, NULL); generate_error (&dtp->common, LIBERROR_OS, NULL);
break; break;
...@@ -2410,7 +2428,7 @@ next_record_r (st_parameter_dt *dtp) ...@@ -2410,7 +2428,7 @@ next_record_r (st_parameter_dt *dtp)
if (is_stream_io (dtp)) if (is_stream_io (dtp))
dtp->u.p.current_unit->strm_pos++; dtp->u.p.current_unit->strm_pos++;
} }
while (*p != '\n'); while (p != '\n');
break; break;
} }
...@@ -2550,8 +2568,10 @@ next_record_w (st_parameter_dt *dtp, int done) ...@@ -2550,8 +2568,10 @@ next_record_w (st_parameter_dt *dtp, int done)
{ {
gfc_offset m, record, max_pos; gfc_offset m, record, max_pos;
int length; int length;
char *p;
/* Flush and reset the format buffer. */
fbuf_flush (dtp->u.p.current_unit, 1);
/* Zero counters for X- and T-editing. */ /* Zero counters for X- and T-editing. */
max_pos = dtp->u.p.max_pos; max_pos = dtp->u.p.max_pos;
dtp->u.p.max_pos = dtp->u.p.skips = dtp->u.p.pending_spaces = 0; dtp->u.p.max_pos = dtp->u.p.skips = dtp->u.p.pending_spaces = 0;
...@@ -2576,12 +2596,9 @@ next_record_w (st_parameter_dt *dtp, int done) ...@@ -2576,12 +2596,9 @@ next_record_w (st_parameter_dt *dtp, int done)
if (dtp->u.p.current_unit->bytes_left > 0) if (dtp->u.p.current_unit->bytes_left > 0)
{ {
length = (int) dtp->u.p.current_unit->bytes_left; length = (int) dtp->u.p.current_unit->bytes_left;
p = salloc_w (dtp->u.p.current_unit->s, &length); if (sset (dtp->u.p.current_unit->s, 0, length) == FAILURE)
memset (p, 0, length); goto io_error;
} }
if (sfree (dtp->u.p.current_unit->s) == FAILURE)
goto io_error;
break; break;
case UNFORMATTED_SEQUENTIAL: case UNFORMATTED_SEQUENTIAL:
...@@ -2609,7 +2626,13 @@ next_record_w (st_parameter_dt *dtp, int done) ...@@ -2609,7 +2626,13 @@ next_record_w (st_parameter_dt *dtp, int done)
if (max_pos > m) if (max_pos > m)
{ {
length = (int) (max_pos - m); length = (int) (max_pos - m);
p = salloc_w (dtp->u.p.current_unit->s, &length); if (sseek (dtp->u.p.current_unit->s,
file_position (dtp->u.p.current_unit->s)
+ length) == FAILURE)
{
generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
return;
}
length = (int) (dtp->u.p.current_unit->recl - max_pos); length = (int) (dtp->u.p.current_unit->recl - max_pos);
} }
...@@ -2651,7 +2674,13 @@ next_record_w (st_parameter_dt *dtp, int done) ...@@ -2651,7 +2674,13 @@ next_record_w (st_parameter_dt *dtp, int done)
if (max_pos > m) if (max_pos > m)
{ {
length = (int) (max_pos - m); length = (int) (max_pos - m);
p = salloc_w (dtp->u.p.current_unit->s, &length); if (sseek (dtp->u.p.current_unit->s,
file_position (dtp->u.p.current_unit->s)
+ length) == FAILURE)
{
generate_error (&dtp->common, LIBERROR_INTERNAL_UNIT, NULL);
return;
}
length = (int) (dtp->u.p.current_unit->recl - max_pos); length = (int) (dtp->u.p.current_unit->recl - max_pos);
} }
else else
...@@ -2670,15 +2699,6 @@ next_record_w (st_parameter_dt *dtp, int done) ...@@ -2670,15 +2699,6 @@ next_record_w (st_parameter_dt *dtp, int done)
size_t len; size_t len;
const char crlf[] = "\r\n"; const char crlf[] = "\r\n";
/* Move to the farthest position reached in preparation for
completing the record. (for file unit) */
m = dtp->u.p.current_unit->recl -
dtp->u.p.current_unit->bytes_left;
if (max_pos > m)
{
length = (int) (max_pos - m);
p = salloc_w (dtp->u.p.current_unit->s, &length);
}
#ifdef HAVE_CRLF #ifdef HAVE_CRLF
len = 2; len = 2;
#else #else
...@@ -2818,6 +2838,7 @@ finalize_transfer (st_parameter_dt *dtp) ...@@ -2818,6 +2838,7 @@ finalize_transfer (st_parameter_dt *dtp)
if (!is_internal_unit (dtp) && dtp->u.p.seen_dollar) if (!is_internal_unit (dtp) && dtp->u.p.seen_dollar)
{ {
dtp->u.p.seen_dollar = 0; dtp->u.p.seen_dollar = 0;
fbuf_flush (dtp->u.p.current_unit, 1);
sfree (dtp->u.p.current_unit->s); sfree (dtp->u.p.current_unit->s);
return; return;
} }
...@@ -2830,6 +2851,7 @@ finalize_transfer (st_parameter_dt *dtp) ...@@ -2830,6 +2851,7 @@ finalize_transfer (st_parameter_dt *dtp)
- dtp->u.p.current_unit->bytes_left); - dtp->u.p.current_unit->bytes_left);
dtp->u.p.current_unit->saved_pos = dtp->u.p.current_unit->saved_pos =
dtp->u.p.max_pos > 0 ? dtp->u.p.max_pos - bytes_written : 0; dtp->u.p.max_pos > 0 ? dtp->u.p.max_pos - bytes_written : 0;
fbuf_flush (dtp->u.p.current_unit, 0);
flush (dtp->u.p.current_unit->s); flush (dtp->u.p.current_unit->s);
return; return;
} }
......
...@@ -567,6 +567,8 @@ init_units (void) ...@@ -567,6 +567,8 @@ init_units (void)
u->file_len = strlen (stdout_name); u->file_len = strlen (stdout_name);
u->file = get_mem (u->file_len); u->file = get_mem (u->file_len);
memmove (u->file, stdout_name, u->file_len); memmove (u->file, stdout_name, u->file_len);
fbuf_init (u, 0);
__gthread_mutex_unlock (&u->lock); __gthread_mutex_unlock (&u->lock);
} }
...@@ -594,6 +596,9 @@ init_units (void) ...@@ -594,6 +596,9 @@ init_units (void)
u->file_len = strlen (stderr_name); u->file_len = strlen (stderr_name);
u->file = get_mem (u->file_len); u->file = get_mem (u->file_len);
memmove (u->file, stderr_name, u->file_len); memmove (u->file, stderr_name, u->file_len);
fbuf_init (u, 256); /* 256 bytes should be enough, probably not doing
any kind of exotic formatting to stderr. */
__gthread_mutex_unlock (&u->lock); __gthread_mutex_unlock (&u->lock);
} }
...@@ -613,7 +618,7 @@ static int ...@@ -613,7 +618,7 @@ static int
close_unit_1 (gfc_unit *u, int locked) close_unit_1 (gfc_unit *u, int locked)
{ {
int i, rc; int i, rc;
/* If there are previously written bytes from a write with ADVANCE="no" /* If there are previously written bytes from a write with ADVANCE="no"
Reposition the buffer before closing. */ Reposition the buffer before closing. */
if (u->previous_nonadvancing_write) if (u->previous_nonadvancing_write)
...@@ -635,6 +640,8 @@ close_unit_1 (gfc_unit *u, int locked) ...@@ -635,6 +640,8 @@ close_unit_1 (gfc_unit *u, int locked)
free_mem (u->file); free_mem (u->file);
u->file = NULL; u->file = NULL;
u->file_len = 0; u->file_len = 0;
fbuf_destroy (u);
if (!locked) if (!locked)
__gthread_mutex_unlock (&u->lock); __gthread_mutex_unlock (&u->lock);
...@@ -737,10 +744,11 @@ filename_from_unit (int n) ...@@ -737,10 +744,11 @@ filename_from_unit (int n)
void void
finish_last_advance_record (gfc_unit *u) finish_last_advance_record (gfc_unit *u)
{ {
char *p;
if (u->saved_pos > 0) if (u->saved_pos > 0)
p = salloc_w (u->s, &u->saved_pos); fbuf_seek (u, u->saved_pos);
fbuf_flush (u, 1);
if (!(u->unit_number == options.stdout_unit if (!(u->unit_number == options.stdout_unit
|| u->unit_number == options.stderr_unit)) || u->unit_number == options.stderr_unit))
......
...@@ -530,12 +530,10 @@ fd_alloc (unix_stream * s, gfc_offset where, ...@@ -530,12 +530,10 @@ fd_alloc (unix_stream * s, gfc_offset where,
* NULL on I/O error. */ * NULL on I/O error. */
static char * static char *
fd_alloc_r_at (unix_stream * s, int *len, gfc_offset where) fd_alloc_r_at (unix_stream * s, int *len)
{ {
gfc_offset m; gfc_offset m;
gfc_offset where = s->logical_offset;
if (where == -1)
where = s->logical_offset;
if (s->buffer != NULL && s->buffer_offset <= where && if (s->buffer != NULL && s->buffer_offset <= where &&
where + *len <= s->buffer_offset + s->active) where + *len <= s->buffer_offset + s->active)
...@@ -593,12 +591,10 @@ fd_alloc_r_at (unix_stream * s, int *len, gfc_offset where) ...@@ -593,12 +591,10 @@ fd_alloc_r_at (unix_stream * s, int *len, gfc_offset where)
* we've already buffered the data or we need to load it. */ * we've already buffered the data or we need to load it. */
static char * static char *
fd_alloc_w_at (unix_stream * s, int *len, gfc_offset where) fd_alloc_w_at (unix_stream * s, int *len)
{ {
gfc_offset n; gfc_offset n;
gfc_offset where = s->logical_offset;
if (where == -1)
where = s->logical_offset;
if (s->buffer == NULL || s->buffer_offset > where || if (s->buffer == NULL || s->buffer_offset > where ||
where + *len > s->buffer_offset + s->len) where + *len > s->buffer_offset + s->len)
...@@ -752,7 +748,7 @@ fd_sset (unix_stream * s, int c, size_t n) ...@@ -752,7 +748,7 @@ fd_sset (unix_stream * s, int c, size_t n)
/* memset() in chunks of BUFFER_SIZE. */ /* memset() in chunks of BUFFER_SIZE. */
trans = (bytes_left < BUFFER_SIZE) ? bytes_left : BUFFER_SIZE; trans = (bytes_left < BUFFER_SIZE) ? bytes_left : BUFFER_SIZE;
p = fd_alloc_w_at (s, &trans, -1); p = fd_alloc_w_at (s, &trans);
if (p) if (p)
memset (p, c, trans); memset (p, c, trans);
else else
...@@ -779,7 +775,7 @@ fd_read (unix_stream * s, void * buf, size_t * nbytes) ...@@ -779,7 +775,7 @@ fd_read (unix_stream * s, void * buf, size_t * nbytes)
if (*nbytes < BUFFER_SIZE && s->method == SYNC_BUFFERED) if (*nbytes < BUFFER_SIZE && s->method == SYNC_BUFFERED)
{ {
tmp = *nbytes; tmp = *nbytes;
p = fd_alloc_r_at (s, &tmp, -1); p = fd_alloc_r_at (s, &tmp);
if (p) if (p)
{ {
*nbytes = tmp; *nbytes = tmp;
...@@ -827,7 +823,7 @@ fd_write (unix_stream * s, const void * buf, size_t * nbytes) ...@@ -827,7 +823,7 @@ fd_write (unix_stream * s, const void * buf, size_t * nbytes)
if (*nbytes < BUFFER_SIZE && s->method == SYNC_BUFFERED) if (*nbytes < BUFFER_SIZE && s->method == SYNC_BUFFERED)
{ {
tmp = *nbytes; tmp = *nbytes;
p = fd_alloc_w_at (s, &tmp, -1); p = fd_alloc_w_at (s, &tmp);
if (p) if (p)
{ {
*nbytes = tmp; *nbytes = tmp;
...@@ -890,7 +886,6 @@ fd_open (unix_stream * s) ...@@ -890,7 +886,6 @@ fd_open (unix_stream * s)
else else
s->method = SYNC_BUFFERED; s->method = SYNC_BUFFERED;
s->st.alloc_r_at = (void *) fd_alloc_r_at;
s->st.alloc_w_at = (void *) fd_alloc_w_at; s->st.alloc_w_at = (void *) fd_alloc_w_at;
s->st.sfree = (void *) fd_sfree; s->st.sfree = (void *) fd_sfree;
s->st.close = (void *) fd_close; s->st.close = (void *) fd_close;
...@@ -918,12 +913,10 @@ fd_open (unix_stream * s) ...@@ -918,12 +913,10 @@ fd_open (unix_stream * s)
static char * static char *
mem_alloc_r_at (int_stream * s, int *len, gfc_offset where) mem_alloc_r_at (int_stream * s, int *len)
{ {
gfc_offset n; gfc_offset n;
gfc_offset where = s->logical_offset;
if (where == -1)
where = s->logical_offset;
if (where < s->buffer_offset || where > s->buffer_offset + s->active) if (where < s->buffer_offset || where > s->buffer_offset + s->active)
return NULL; return NULL;
...@@ -939,15 +932,13 @@ mem_alloc_r_at (int_stream * s, int *len, gfc_offset where) ...@@ -939,15 +932,13 @@ mem_alloc_r_at (int_stream * s, int *len, gfc_offset where)
static char * static char *
mem_alloc_w_at (int_stream * s, int *len, gfc_offset where) mem_alloc_w_at (int_stream * s, int *len)
{ {
gfc_offset m; gfc_offset m;
gfc_offset where = s->logical_offset;
assert (*len >= 0); /* Negative values not allowed. */ assert (*len >= 0); /* Negative values not allowed. */
if (where == -1)
where = s->logical_offset;
m = where + *len; m = where + *len;
if (where < s->buffer_offset) if (where < s->buffer_offset)
...@@ -962,9 +953,7 @@ mem_alloc_w_at (int_stream * s, int *len, gfc_offset where) ...@@ -962,9 +953,7 @@ mem_alloc_w_at (int_stream * s, int *len, gfc_offset where)
} }
/* Stream read function for internal units. This is not actually used /* Stream read function for internal units. */
at the moment, as all internal IO is formatted and the formatted IO
routines use mem_alloc_r_at. */
static int static int
mem_read (int_stream * s, void * buf, size_t * nbytes) mem_read (int_stream * s, void * buf, size_t * nbytes)
...@@ -973,7 +962,7 @@ mem_read (int_stream * s, void * buf, size_t * nbytes) ...@@ -973,7 +962,7 @@ mem_read (int_stream * s, void * buf, size_t * nbytes)
int tmp; int tmp;
tmp = *nbytes; tmp = *nbytes;
p = mem_alloc_r_at (s, &tmp, -1); p = mem_alloc_r_at (s, &tmp);
if (p) if (p)
{ {
*nbytes = tmp; *nbytes = tmp;
...@@ -983,7 +972,7 @@ mem_read (int_stream * s, void * buf, size_t * nbytes) ...@@ -983,7 +972,7 @@ mem_read (int_stream * s, void * buf, size_t * nbytes)
else else
{ {
*nbytes = 0; *nbytes = 0;
return errno; return 0;
} }
} }
...@@ -998,10 +987,8 @@ mem_write (int_stream * s, const void * buf, size_t * nbytes) ...@@ -998,10 +987,8 @@ mem_write (int_stream * s, const void * buf, size_t * nbytes)
void *p; void *p;
int tmp; int tmp;
errno = 0;
tmp = *nbytes; tmp = *nbytes;
p = mem_alloc_w_at (s, &tmp, -1); p = mem_alloc_w_at (s, &tmp);
if (p) if (p)
{ {
*nbytes = tmp; *nbytes = tmp;
...@@ -1011,7 +998,7 @@ mem_write (int_stream * s, const void * buf, size_t * nbytes) ...@@ -1011,7 +998,7 @@ mem_write (int_stream * s, const void * buf, size_t * nbytes)
else else
{ {
*nbytes = 0; *nbytes = 0;
return errno; return 0;
} }
} }
...@@ -1038,7 +1025,7 @@ mem_set (int_stream * s, int c, size_t n) ...@@ -1038,7 +1025,7 @@ mem_set (int_stream * s, int c, size_t n)
len = n; len = n;
p = mem_alloc_w_at (s, &len, -1); p = mem_alloc_w_at (s, &len);
if (p) if (p)
{ {
memset (p, c, len); memset (p, c, len);
...@@ -1104,7 +1091,6 @@ open_internal (char *base, int length, gfc_offset offset) ...@@ -1104,7 +1091,6 @@ open_internal (char *base, int length, gfc_offset offset)
s->logical_offset = 0; s->logical_offset = 0;
s->active = s->file_length = length; s->active = s->file_length = length;
s->st.alloc_r_at = (void *) mem_alloc_r_at;
s->st.alloc_w_at = (void *) mem_alloc_w_at; s->st.alloc_w_at = (void *) mem_alloc_w_at;
s->st.sfree = (void *) mem_sfree; s->st.sfree = (void *) mem_sfree;
s->st.close = (void *) mem_close; s->st.close = (void *) mem_close;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment