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,11 +114,9 @@ unformatted_backspace (st_parameter_filepos *fpp, gfc_unit *u) ...@@ -115,11 +114,9 @@ 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);
if (p == NULL || length_read != length)
goto io_error; 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. */
...@@ -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'; c = '\n';
else dtp->u.p.at_eof = 1;
c = *p; }
} }
} }
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);
#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), 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)
...@@ -324,13 +332,18 @@ read_decimal (st_parameter_dt *dtp, const fnode *f, char *dest, int length) ...@@ -324,13 +332,18 @@ 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,10 +872,8 @@ read_f (st_parameter_dt *dtp, const fnode *f, char *dest, int length) ...@@ -850,10 +872,8 @@ 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)) if ((dtp->u.p.pad_status == PAD_NO || is_internal_unit (dtp))
&& dtp->u.p.current_unit->bytes_left < n) && dtp->u.p.current_unit->bytes_left < n)
n = dtp->u.p.current_unit->bytes_left; n = dtp->u.p.current_unit->bytes_left;
...@@ -862,7 +882,6 @@ read_x (st_parameter_dt *dtp, int n) ...@@ -862,7 +882,6 @@ read_x (st_parameter_dt *dtp, int n)
if (n > 0) if (n > 0)
read_sf (dtp, &n, 1); read_sf (dtp, &n, 1);
dtp->u.p.sf_read_comma = 1; dtp->u.p.sf_read_comma = 1;
}
else
dtp->u.p.current_unit->strm_pos += (gfc_offset) n; dtp->u.p.current_unit->strm_pos += (gfc_offset) n;
} }
...@@ -568,6 +568,8 @@ init_units (void) ...@@ -568,6 +568,8 @@ init_units (void)
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);
} }
...@@ -595,6 +597,9 @@ init_units (void) ...@@ -595,6 +597,9 @@ init_units (void)
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);
} }
...@@ -636,6 +641,8 @@ close_unit_1 (gfc_unit *u, int locked) ...@@ -636,6 +641,8 @@ close_unit_1 (gfc_unit *u, int locked)
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