diff options
author | Jerry DeLisle <jvdelisle@gcc.gnu.org> | 2010-07-13 02:12:08 +0000 |
---|---|---|
committer | Jerry DeLisle <jvdelisle@gcc.gnu.org> | 2010-07-13 02:12:08 +0000 |
commit | c7421e06ca1de11fa125ed9d8619680d17bfb6f8 (patch) | |
tree | 708fe1e3e6e8349ec20c2bbbb436fa48ee645bd2 /libgfortran/io/unix.c | |
parent | c8dce2cfddf0baf62bf56c2d5a49e1dfcdda0231 (diff) | |
download | gcc-c7421e06ca1de11fa125ed9d8619680d17bfb6f8.zip gcc-c7421e06ca1de11fa125ed9d8619680d17bfb6f8.tar.gz gcc-c7421e06ca1de11fa125ed9d8619680d17bfb6f8.tar.bz2 |
re PR fortran/37077 (Implement Internal Unit I/O for character KIND=4)
2010-07-12 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libfortran/37077
* io/read.c: Fix comment.
* io/io.h (is_char4_unit): New macro.
* io/unit.c (get_internal_unit): Call new function open_internal4.
* io/unix.c (mem_alloc_r4): New function. (mem_alloc_w4): New function.
(mem_read4): New function, temporary stub. (mem_write4): New function.
(open_internal4): New function to set stream pointers to use the new
mem functions.
* io/transfer.c (write_block): Use new mem_alloc_w4 to access internal
units of kind=4.
* io/unix.h: Add prototypes for open_internal4, mem_alloc_w4, and
mem_alloc_r4.
* io/write.c (memset4): New helper function. (memcpy4): New helper
function. (write_default_char4): Use new helper functions.
(write_a): Likewise. (write_l): Likewise. (write_boz): Likewise.
(write_decimal): Likewise. (write_x): Likewise.
(write_integer): Likewise.
* io/write_float.def (output_float): Add code blocks to handle internal
unit kind=4 output utilizing gfc_char4_t pointers. (write_infnan): Use
new helper functions. (OUTPUT_FLOAT_FMT_G): Update this macro likewise.
From-SVN: r162123
Diffstat (limited to 'libgfortran/io/unix.c')
-rw-r--r-- | libgfortran/io/unix.c | 117 |
1 files changed, 111 insertions, 6 deletions
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c index afa5f45..65decce 100644 --- a/libgfortran/io/unix.c +++ b/libgfortran/io/unix.c @@ -598,7 +598,6 @@ buf_init (unix_stream * s) *********************************************************************/ - char * mem_alloc_r (stream * strm, int * len) { @@ -620,6 +619,26 @@ mem_alloc_r (stream * strm, int * len) char * +mem_alloc_r4 (stream * strm, int * len) +{ + unix_stream * s = (unix_stream *) strm; + gfc_offset n; + gfc_offset where = s->logical_offset; + + if (where < s->buffer_offset || where > s->buffer_offset + s->active) + return NULL; + + n = s->buffer_offset + s->active - where; + if (*len > n) + *len = n; + + s->logical_offset = where + *len; + + return s->buffer + (where - s->buffer_offset) * 4; +} + + +char * mem_alloc_w (stream * strm, int * len) { unix_stream * s = (unix_stream *) strm; @@ -640,7 +659,27 @@ mem_alloc_w (stream * strm, int * len) } -/* Stream read function for internal units. */ +char * +mem_alloc_w4 (stream * strm, int * len) +{ + unix_stream * s = (unix_stream *) strm; + gfc_offset m; + gfc_offset where = s->logical_offset; + + m = where + *len; + + if (where < s->buffer_offset) + return NULL; + + if (m > s->file_length) + return NULL; + + s->logical_offset = m; + return s->buffer + (where - s->buffer_offset) * 4; +} + + +/* Stream read function for character(kine=1) internal units. */ static ssize_t mem_read (stream * s, void * buf, ssize_t nbytes) @@ -659,9 +698,26 @@ mem_read (stream * s, void * buf, ssize_t nbytes) } -/* Stream write function for internal units. This is not actually used - at the moment, as all internal IO is formatted and the formatted IO - routines use mem_alloc_w_at. */ +/* Stream read function for chracter(kind=4) internal units. */ + +static ssize_t +mem_read4 (stream * s, void * buf, ssize_t nbytes) +{ + void *p; + int nb = nbytes; + + p = mem_alloc_r (s, &nb); + if (p) + { + memcpy (buf, p, nb); + return (ssize_t) nb; + } + else + return 0; +} + + +/* Stream write function for character(kind=1) internal units. */ static ssize_t mem_write (stream * s, const void * buf, ssize_t nbytes) @@ -680,6 +736,26 @@ mem_write (stream * s, const void * buf, ssize_t nbytes) } +/* Stream write function for character(kind=4) internal units. */ + +static ssize_t +mem_write4 (stream * s, const void * buf, ssize_t nwords) +{ + gfc_char4_t *p; + int nw = nwords; + + p = (gfc_char4_t *) mem_alloc_w4 (s, &nw); + if (p) + { + while (nw--) + *p++ = (gfc_char4_t) *((char *) buf); + return nwords; + } + else + return 0; +} + + static gfc_offset mem_seek (stream * strm, gfc_offset offset, int whence) { @@ -763,7 +839,8 @@ empty_internal_buffer(stream *strm) memset(s->buffer, ' ', s->file_length); } -/* open_internal()-- Returns a stream structure from an internal file */ +/* open_internal()-- Returns a stream structure from a character(kind=1) + internal file */ stream * open_internal (char *base, int length, gfc_offset offset) @@ -790,6 +867,34 @@ open_internal (char *base, int length, gfc_offset offset) return (stream *) s; } +/* open_internal4()-- Returns a stream structure from a character(kind=4) + internal file */ + +stream * +open_internal4 (char *base, int length, gfc_offset offset) +{ + unix_stream *s; + + s = get_mem (sizeof (unix_stream)); + memset (s, '\0', sizeof (unix_stream)); + + s->buffer = base; + s->buffer_offset = offset; + + s->logical_offset = 0; + s->active = s->file_length = length; + + s->st.close = (void *) mem_close; + s->st.seek = (void *) mem_seek; + s->st.tell = (void *) mem_tell; + s->st.trunc = (void *) mem_truncate; + s->st.read = (void *) mem_read4; + s->st.write = (void *) mem_write4; + s->st.flush = (void *) mem_flush; + + return (stream *) s; +} + /* fd_to_stream()-- Given an open file descriptor, build a stream * around it. */ |