diff options
author | Janne Blomqvist <jb@gcc.gnu.org> | 2018-01-07 12:17:52 +0200 |
---|---|---|
committer | Janne Blomqvist <jb@gcc.gnu.org> | 2018-01-07 12:17:52 +0200 |
commit | ea99ec5bd62c0d14023aac0316f4286193db9434 (patch) | |
tree | 36694f3e28c6ca161e719f0dc4e69779533ff1fa /libgfortran/io/read.c | |
parent | c7c9468a6c1e21bb140f62d97d427352d90556bc (diff) | |
download | gcc-ea99ec5bd62c0d14023aac0316f4286193db9434.zip gcc-ea99ec5bd62c0d14023aac0316f4286193db9434.tar.gz gcc-ea99ec5bd62c0d14023aac0316f4286193db9434.tar.bz2 |
PR 78534, 83704 Handle large formatted I/O
In order to handle large characters when doing formatted I/O, use
size_t and ptrdiff_t for lengths. Compared to the previous patch,
based on discussions on IRC use size_t for sizes that don't need to be
negative rather than ptrdiff_t everywhere.
Regtested on x86_64-pc-linux-gnu, approved as part of the PR 78534
approval, committed to trunk.
libgfortran/ChangeLog:
2018-01-07 Janne Blomqvist <jb@gcc.gnu.org>
PR fortran/78534
PR fortran/83704
* io/fbuf.c (fbuf_init): Use size_t instead of int for length.
(fbuf_debug): Convert debug output to unsigned long.
(fbuf_reset): Use ptrdiff_t for return value.
(fbuf_alloc): Use size_t for length argument.
(fbuf_flush): Handle large buffers.
(fbuf_flush_list): Likewise.
(fbuf_seek): Use ptrdiff_t for offset and return value.
(fbuf_read): Use size_t for length argument.
(fbuf_getc_refill): Use size_t to match fbuf_read.
* io/fbuf.h (struct fbuf): Use size_t for lengths.
(fbuf_init): Use size_t instead of int for length.
(fbuf_reset): Use ptrdiff_t for return value.
(fbuf_alloc): Use size_t for length argument.
(fbuf_seek): Use ptrdiff_t for offset and return value.
(fbuf_read): Use size_t for length argument.
* io/io.h (read_block_form): Likewise.
(read_block_form4): Likewise.
(write_block): Likewise.
(read_a): Likewise.
(read_a_char4): Likewise.
(read_x): Likewise.
(write_a): Likewise.
(write_a_char4): Likewise.
* io/list_read.c (list_formatted_read_scalar): Use size_t to
handle large buffers.
* io/read.c (read_l): Likewise.
(read_utf8): Likewise.
(read_utf8_char1): Likewise.
(read_default_char1): Likewise.
(read_utf8_char4): Likewise.
(read_default_char4): Likewise.
(read_a): Likewise.
(read_a_char4): Likewise.
(eat_leading_spaces): Likewise.
(next_char): Likewise.
(read_decimal): Likewise.
(read_radix): Likewise.
(read_f): Likewise.
(read_x): Likewise.
* io/transfer.c (read_sf_internal): Likewise.
(read_sf): Likewise.
(read_block_form): Likewise.
(read_block_form4): Likewise.
(write_block): Likewise.
(formatted_transfer_scalar_write): Likewise.
(next_record_w): Likewise.
* io/unix.c (mem_alloc_r): Likewise.
(mem_alloc_r4): Likewise.
(mem_alloc_w): Likewise.
(mem_alloc_w4): Likewise.
(mem_read): Likewise.
(mem_read4): Likewise.
(mem_write): Likewise.
(mem_write4): Likewise.
(open_internal): Likewise.
(open_internal4): Likewise.
* io/unix.h (open_internal): Likewise.
(open_internal4): Likewise.
(mem_alloc_w): Likewise.
(mem_alloc_r): Likewise.
(mem_alloc_w4): Likewise.
(mem_alloc_r4): Likewise.
* io/write.c (write_check_cc): Likewise.
(write_cc): Likewise.
(write_a): Likewise.
(write_a_char4): Likewise.
From-SVN: r256322
Diffstat (limited to 'libgfortran/io/read.c')
-rw-r--r-- | libgfortran/io/read.c | 95 |
1 files changed, 51 insertions, 44 deletions
diff --git a/libgfortran/io/read.c b/libgfortran/io/read.c index 167587f..87adfb8 100644 --- a/libgfortran/io/read.c +++ b/libgfortran/io/read.c @@ -272,7 +272,7 @@ void read_l (st_parameter_dt *dtp, const fnode *f, char *dest, int length) { char *p; - int w; + size_t w; w = f->u.w; @@ -316,11 +316,11 @@ read_l (st_parameter_dt *dtp, const fnode *f, char *dest, int length) static gfc_char4_t -read_utf8 (st_parameter_dt *dtp, int *nbytes) +read_utf8 (st_parameter_dt *dtp, size_t *nbytes) { static const uchar masks[6] = { 0x7F, 0x1F, 0x0F, 0x07, 0x02, 0x01 }; static const uchar patns[6] = { 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - int i, nb, nread; + size_t nb, nread; gfc_char4_t c; char *s; @@ -353,7 +353,7 @@ read_utf8 (st_parameter_dt *dtp, int *nbytes) if (s == NULL) return 0; /* Decode the bytes read. */ - for (i = 1; i < nb; i++) + for (size_t i = 1; i < nb; i++) { gfc_char4_t n = *s++; @@ -383,12 +383,11 @@ read_utf8 (st_parameter_dt *dtp, int *nbytes) static void -read_utf8_char1 (st_parameter_dt *dtp, char *p, int len, int width) +read_utf8_char1 (st_parameter_dt *dtp, char *p, size_t len, size_t width) { gfc_char4_t c; char *dest; - int nbytes; - int i, j; + size_t nbytes, j; len = (width < len) ? len : width; @@ -407,16 +406,16 @@ read_utf8_char1 (st_parameter_dt *dtp, char *p, int len, int width) } /* If there was a short read, pad the remaining characters. */ - for (i = j; i < len; i++) + for (size_t i = j; i < len; i++) *dest++ = ' '; return; } static void -read_default_char1 (st_parameter_dt *dtp, char *p, int len, int width) +read_default_char1 (st_parameter_dt *dtp, char *p, size_t len, size_t width) { char *s; - int m, n; + size_t m; s = read_block_form (dtp, &width); @@ -428,18 +427,16 @@ read_default_char1 (st_parameter_dt *dtp, char *p, int len, int width) m = (width > len) ? len : width; memcpy (p, s, m); - n = len - width; - if (n > 0) - memset (p + m, ' ', n); + if (len > width) + memset (p + m, ' ', len - width); } static void -read_utf8_char4 (st_parameter_dt *dtp, void *p, int len, int width) +read_utf8_char4 (st_parameter_dt *dtp, void *p, size_t len, size_t width) { gfc_char4_t *dest; - int nbytes; - int i, j; + size_t nbytes, j; len = (width < len) ? len : width; @@ -456,16 +453,16 @@ read_utf8_char4 (st_parameter_dt *dtp, void *p, int len, int width) } /* If there was a short read, pad the remaining characters. */ - for (i = j; i < len; i++) + for (size_t i = j; i < len; i++) *dest++ = (gfc_char4_t) ' '; return; } static void -read_default_char4 (st_parameter_dt *dtp, char *p, int len, int width) +read_default_char4 (st_parameter_dt *dtp, char *p, size_t len, size_t width) { - int m, n; + size_t m, n; gfc_char4_t *dest; if (is_char4_unit(dtp)) @@ -479,15 +476,18 @@ read_default_char4 (st_parameter_dt *dtp, char *p, int len, int width) if (width > len) s4 += (width - len); - m = ((int) width > len) ? len : (int) width; + m = (width > len) ? len : width; dest = (gfc_char4_t *) p; for (n = 0; n < m; n++) *dest++ = *s4++; - for (n = 0; n < len - (int) width; n++) - *dest++ = (gfc_char4_t) ' '; + if (len > width) + { + for (n = 0; n < len - width; n++) + *dest++ = (gfc_char4_t) ' '; + } } else { @@ -500,15 +500,18 @@ read_default_char4 (st_parameter_dt *dtp, char *p, int len, int width) if (width > len) s += (width - len); - m = ((int) width > len) ? len : (int) width; + m = (width > len) ? len : width; dest = (gfc_char4_t *) p; for (n = 0; n < m; n++, dest++, s++) *dest = (unsigned char ) *s; - for (n = 0; n < len - (int) width; n++, dest++) - *dest = (unsigned char) ' '; + if (len > width) + { + for (n = 0; n < len - width; n++, dest++) + *dest = (unsigned char) ' '; + } } } @@ -517,15 +520,14 @@ read_default_char4 (st_parameter_dt *dtp, char *p, int len, int width) processing UTF-8 encoding if necessary. */ 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, size_t length) { - int wi; - int w; + size_t w; - wi = f->u.w; - if (wi == -1) /* '(A)' edit descriptor */ - wi = length; - w = wi; + if (f->u.w == -1) /* '(A)' edit descriptor */ + w = length; + else + w = f->u.w; /* Read in w characters, treating comma as not a separator. */ dtp->u.p.sf_read_comma = 0; @@ -544,13 +546,14 @@ read_a (st_parameter_dt *dtp, const fnode *f, char *p, int length) processing UTF-8 encoding if necessary. */ void -read_a_char4 (st_parameter_dt *dtp, const fnode *f, char *p, int length) +read_a_char4 (st_parameter_dt *dtp, const fnode *f, char *p, size_t length) { - int w; + size_t w; - w = f->u.w; - if (w == -1) /* '(A)' edit descriptor */ + if (f->u.w == -1) /* '(A)' edit descriptor */ w = length; + else + w = f->u.w; /* Read in w characters, treating comma as not a separator. */ dtp->u.p.sf_read_comma = 0; @@ -568,7 +571,7 @@ read_a_char4 (st_parameter_dt *dtp, const fnode *f, char *p, int length) ignore the leading spaces. */ static char * -eat_leading_spaces (int *width, char *p) +eat_leading_spaces (size_t *width, char *p) { for (;;) { @@ -584,7 +587,7 @@ eat_leading_spaces (int *width, char *p) static char -next_char (st_parameter_dt *dtp, char **p, int *w) +next_char (st_parameter_dt *dtp, char **p, size_t *w) { char c, *q; @@ -624,7 +627,8 @@ read_decimal (st_parameter_dt *dtp, const fnode *f, char *dest, int length) { GFC_UINTEGER_LARGEST value, maxv, maxv_10; GFC_INTEGER_LARGEST v; - int w, negative; + size_t w; + int negative; char c, *p; w = f->u.w; @@ -732,7 +736,8 @@ read_radix (st_parameter_dt *dtp, const fnode *f, char *dest, int length, { GFC_UINTEGER_LARGEST value, maxv, maxv_r; GFC_INTEGER_LARGEST v; - int w, negative; + size_t w; + int negative; char c, *p; w = f->u.w; @@ -882,7 +887,8 @@ read_f (st_parameter_dt *dtp, const fnode *f, char *dest, int length) #define READF_TMP 50 char tmp[READF_TMP]; size_t buf_size = 0; - int w, seen_dp, exponent; + size_t w; + int seen_dp, exponent; int exponent_sign; const char *p; char *buffer; @@ -1230,12 +1236,13 @@ bad_float: and never look at it. */ void -read_x (st_parameter_dt *dtp, int n) +read_x (st_parameter_dt *dtp, size_t n) { - int length, q, q2; + size_t length; + int q, q2; if ((dtp->u.p.current_unit->pad_status == PAD_NO || is_internal_unit (dtp)) - && dtp->u.p.current_unit->bytes_left < n) + && dtp->u.p.current_unit->bytes_left < (gfc_offset) n) n = dtp->u.p.current_unit->bytes_left; if (n == 0) |