Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
f3ed1d02
Commit
f3ed1d02
authored
Mar 22, 2009
by
Janne Blomqvist
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert part of patch accidentally committed to trunk rather than fortran-dev (I hate svn)
From-SVN: r144994
parent
9e544d73
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
440 additions
and
530 deletions
+440
-530
libgfortran/io/io.h
+45
-81
libgfortran/io/list_read.c
+31
-36
libgfortran/io/transfer.c
+353
-351
libgfortran/io/unit.c
+11
-62
No files found.
libgfortran/io/io.h
View file @
f3ed1d02
...
@@ -49,59 +49,34 @@ struct st_parameter_dt;
...
@@ -49,59 +49,34 @@ struct st_parameter_dt;
typedef
struct
stream
typedef
struct
stream
{
{
ssize_t
(
*
read
)
(
struct
stream
*
,
void
*
,
ssize_t
);
char
*
(
*
alloc_w_at
)
(
struct
stream
*
,
int
*
);
ssize_t
(
*
write
)
(
struct
stream
*
,
const
void
*
,
ssize_t
);
try
(
*
sfree
)
(
struct
stream
*
);
off_t
(
*
seek
)
(
struct
stream
*
,
off_t
,
int
);
try
(
*
close
)
(
struct
stream
*
);
off_t
(
*
tell
)
(
struct
stream
*
);
try
(
*
seek
)
(
struct
stream
*
,
gfc_offset
);
int
(
*
truncate
)
(
struct
stream
*
,
off_t
);
try
(
*
trunc
)
(
struct
stream
*
);
int
(
*
flush
)
(
struct
stream
*
);
int
(
*
read
)
(
struct
stream
*
,
void
*
,
size_t
*
);
int
(
*
close
)
(
struct
stream
*
);
int
(
*
write
)
(
struct
stream
*
,
const
void
*
,
size_t
*
);
try
(
*
set
)
(
struct
stream
*
,
int
,
size_t
);
}
}
stream
;
stream
;
/* Inline functions for doing file I/O given a stream. */
typedef
enum
static
inline
ssize_t
{
SYNC_BUFFERED
,
SYNC_UNBUFFERED
,
ASYNC
}
sread
(
stream
*
s
,
void
*
buf
,
ssize_t
nbyte
)
io_mode
;
{
return
s
->
read
(
s
,
buf
,
nbyte
);
}
static
inline
ssize_t
/* Macros for doing file I/O given a stream. */
swrite
(
stream
*
s
,
const
void
*
buf
,
ssize_t
nbyte
)
{
return
s
->
write
(
s
,
buf
,
nbyte
);
}
static
inline
off_t
#define sfree(s) ((s)->sfree)(s)
sseek
(
stream
*
s
,
off_t
offset
,
int
whence
)
#define sclose(s) ((s)->close)(s)
{
return
s
->
seek
(
s
,
offset
,
whence
);
}
static
inline
off_t
#define salloc_w(s, len) ((s)->alloc_w_at)(s, len)
stell
(
stream
*
s
)
{
return
s
->
tell
(
s
);
}
static
inline
int
#define sseek(s, pos) ((s)->seek)(s, pos)
struncate
(
stream
*
s
,
off_t
length
)
#define struncate(s) ((s)->trunc)(s)
{
#define sread(s, buf, nbytes) ((s)->read)(s, buf, nbytes)
return
s
->
truncate
(
s
,
length
);
#define swrite(s, buf, nbytes) ((s)->write)(s, buf, nbytes)
}
static
inline
int
sflush
(
stream
*
s
)
{
return
s
->
flush
(
s
);
}
static
inline
int
sclose
(
stream
*
s
)
{
return
s
->
close
(
s
);
}
#define sset(s, c, n) ((s)->set)(s, c, n)
/* Macros for testing what kinds of I/O we are doing. */
/* Macros for testing what kinds of I/O we are doing. */
...
@@ -563,9 +538,10 @@ unit_flags;
...
@@ -563,9 +538,10 @@ unit_flags;
typedef
struct
fbuf
typedef
struct
fbuf
{
{
char
*
buf
;
/* Start of buffer. */
char
*
buf
;
/* Start of buffer. */
int
len
;
/* Length of buffer. */
size_t
len
;
/* Length of buffer. */
int
act
;
/* Active bytes in buffer. */
size_t
act
;
/* Active bytes in buffer. */
int
pos
;
/* Current position in buffer. */
size_t
flushed
;
/* Flushed bytes from beginning of buffer. */
size_t
pos
;
/* Current position in buffer. */
}
}
fbuf
;
fbuf
;
...
@@ -707,12 +683,6 @@ internal_proto(open_external);
...
@@ -707,12 +683,6 @@ internal_proto(open_external);
extern
stream
*
open_internal
(
char
*
,
int
,
gfc_offset
);
extern
stream
*
open_internal
(
char
*
,
int
,
gfc_offset
);
internal_proto
(
open_internal
);
internal_proto
(
open_internal
);
extern
char
*
mem_alloc_w
(
stream
*
,
int
*
);
internal_proto
(
mem_alloc_w
);
extern
char
*
mem_alloc_r
(
stream
*
,
int
*
);
internal_proto
(
mem_alloc_w
);
extern
stream
*
input_stream
(
void
);
extern
stream
*
input_stream
(
void
);
internal_proto
(
input_stream
);
internal_proto
(
input_stream
);
...
@@ -728,6 +698,12 @@ internal_proto(compare_file_filename);
...
@@ -728,6 +698,12 @@ internal_proto(compare_file_filename);
extern
gfc_unit
*
find_file
(
const
char
*
file
,
gfc_charlen_type
file_len
);
extern
gfc_unit
*
find_file
(
const
char
*
file
,
gfc_charlen_type
file_len
);
internal_proto
(
find_file
);
internal_proto
(
find_file
);
extern
int
stream_at_bof
(
stream
*
);
internal_proto
(
stream_at_bof
);
extern
int
stream_at_eof
(
stream
*
);
internal_proto
(
stream_at_eof
);
extern
int
delete_file
(
gfc_unit
*
);
extern
int
delete_file
(
gfc_unit
*
);
internal_proto
(
delete_file
);
internal_proto
(
delete_file
);
...
@@ -758,6 +734,9 @@ internal_proto(inquire_readwrite);
...
@@ -758,6 +734,9 @@ internal_proto(inquire_readwrite);
extern
gfc_offset
file_length
(
stream
*
);
extern
gfc_offset
file_length
(
stream
*
);
internal_proto
(
file_length
);
internal_proto
(
file_length
);
extern
gfc_offset
file_position
(
stream
*
);
internal_proto
(
file_position
);
extern
int
is_seekable
(
stream
*
);
extern
int
is_seekable
(
stream
*
);
internal_proto
(
is_seekable
);
internal_proto
(
is_seekable
);
...
@@ -773,12 +752,18 @@ internal_proto(flush_if_preconnected);
...
@@ -773,12 +752,18 @@ internal_proto(flush_if_preconnected);
extern
void
empty_internal_buffer
(
stream
*
);
extern
void
empty_internal_buffer
(
stream
*
);
internal_proto
(
empty_internal_buffer
);
internal_proto
(
empty_internal_buffer
);
extern
try
flush
(
stream
*
);
internal_proto
(
flush
);
extern
int
stream_isatty
(
stream
*
);
extern
int
stream_isatty
(
stream
*
);
internal_proto
(
stream_isatty
);
internal_proto
(
stream_isatty
);
extern
char
*
stream_ttyname
(
stream
*
);
extern
char
*
stream_ttyname
(
stream
*
);
internal_proto
(
stream_ttyname
);
internal_proto
(
stream_ttyname
);
extern
gfc_offset
stream_offset
(
stream
*
s
);
internal_proto
(
stream_offset
);
extern
int
unpack_filename
(
char
*
,
const
char
*
,
int
);
extern
int
unpack_filename
(
char
*
,
const
char
*
,
int
);
internal_proto
(
unpack_filename
);
internal_proto
(
unpack_filename
);
...
@@ -822,9 +807,6 @@ internal_proto(update_position);
...
@@ -822,9 +807,6 @@ internal_proto(update_position);
extern
void
finish_last_advance_record
(
gfc_unit
*
u
);
extern
void
finish_last_advance_record
(
gfc_unit
*
u
);
internal_proto
(
finish_last_advance_record
);
internal_proto
(
finish_last_advance_record
);
extern
int
unit_truncate
(
gfc_unit
*
,
gfc_offset
,
st_parameter_common
*
);
internal_proto
(
unit_truncate
);
/* open.c */
/* open.c */
extern
gfc_unit
*
new_unit
(
st_parameter_open
*
,
gfc_unit
*
,
unit_flags
*
);
extern
gfc_unit
*
new_unit
(
st_parameter_open
*
,
gfc_unit
*
,
unit_flags
*
);
...
@@ -854,7 +836,7 @@ internal_proto(free_format_data);
...
@@ -854,7 +836,7 @@ 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_form
(
st_parameter_dt
*
,
in
t
*
);
extern
try
read_block_form
(
st_parameter_dt
*
,
void
*
,
size_
t
*
);
internal_proto
(
read_block_form
);
internal_proto
(
read_block_form
);
extern
char
*
read_sf
(
st_parameter_dt
*
,
int
*
,
int
);
extern
char
*
read_sf
(
st_parameter_dt
*
,
int
*
,
int
);
...
@@ -880,9 +862,6 @@ internal_proto (reverse_memcpy);
...
@@ -880,9 +862,6 @@ internal_proto (reverse_memcpy);
extern
void
st_wait
(
st_parameter_wait
*
);
extern
void
st_wait
(
st_parameter_wait
*
);
export_proto
(
st_wait
);
export_proto
(
st_wait
);
extern
void
hit_eof
(
st_parameter_dt
*
);
internal_proto
(
hit_eof
);
/* read.c */
/* read.c */
extern
void
set_integer
(
void
*
,
GFC_INTEGER_LARGEST
,
int
);
extern
void
set_integer
(
void
*
,
GFC_INTEGER_LARGEST
,
int
);
...
@@ -989,39 +968,24 @@ extern size_t size_from_complex_kind (int);
...
@@ -989,39 +968,24 @@ extern size_t size_from_complex_kind (int);
internal_proto
(
size_from_complex_kind
);
internal_proto
(
size_from_complex_kind
);
/* fbuf.c */
/* fbuf.c */
extern
void
fbuf_init
(
gfc_unit
*
,
in
t
);
extern
void
fbuf_init
(
gfc_unit
*
,
size_
t
);
internal_proto
(
fbuf_init
);
internal_proto
(
fbuf_init
);
extern
void
fbuf_destroy
(
gfc_unit
*
);
extern
void
fbuf_destroy
(
gfc_unit
*
);
internal_proto
(
fbuf_destroy
);
internal_proto
(
fbuf_destroy
);
extern
int
fbuf_reset
(
gfc_unit
*
);
extern
void
fbuf_reset
(
gfc_unit
*
);
internal_proto
(
fbuf_reset
);
internal_proto
(
fbuf_reset
);
extern
char
*
fbuf_alloc
(
gfc_unit
*
,
in
t
);
extern
char
*
fbuf_alloc
(
gfc_unit
*
,
size_
t
);
internal_proto
(
fbuf_alloc
);
internal_proto
(
fbuf_alloc
);
extern
int
fbuf_flush
(
gfc_unit
*
,
unit_mode
);
extern
int
fbuf_flush
(
gfc_unit
*
,
int
);
internal_proto
(
fbuf_flush
);
internal_proto
(
fbuf_flush
);
extern
int
fbuf_seek
(
gfc_unit
*
,
int
,
in
t
);
extern
int
fbuf_seek
(
gfc_unit
*
,
gfc_offse
t
);
internal_proto
(
fbuf_seek
);
internal_proto
(
fbuf_seek
);
extern
char
*
fbuf_read
(
gfc_unit
*
,
int
*
);
internal_proto
(
fbuf_read
);
/* Never call this function, only use fbuf_getc(). */
extern
int
fbuf_getc_refill
(
gfc_unit
*
);
internal_proto
(
fbuf_getc_refill
);
static
inline
int
fbuf_getc
(
gfc_unit
*
u
)
{
if
(
u
->
fbuf
->
pos
<
u
->
fbuf
->
act
)
return
(
unsigned
char
)
u
->
fbuf
->
buf
[
u
->
fbuf
->
pos
++
];
return
fbuf_getc_refill
(
u
);
}
/* 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
);
...
...
libgfortran/io/list_read.c
View file @
f3ed1d02
...
@@ -33,7 +33,6 @@ Boston, MA 02110-1301, USA. */
...
@@ -33,7 +33,6 @@ Boston, MA 02110-1301, USA. */
#include "io.h"
#include "io.h"
#include <string.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <ctype.h>
...
@@ -80,8 +79,9 @@ push_char (st_parameter_dt *dtp, char c)
...
@@ -80,8 +79,9 @@ push_char (st_parameter_dt *dtp, char c)
if
(
dtp
->
u
.
p
.
saved_string
==
NULL
)
if
(
dtp
->
u
.
p
.
saved_string
==
NULL
)
{
{
dtp
->
u
.
p
.
saved_string
=
get_mem
(
SCRATCH_SIZE
);
if
(
dtp
->
u
.
p
.
scratch
==
NULL
)
// memset below should be commented out.
dtp
->
u
.
p
.
scratch
=
get_mem
(
SCRATCH_SIZE
);
dtp
->
u
.
p
.
saved_string
=
dtp
->
u
.
p
.
scratch
;
memset
(
dtp
->
u
.
p
.
saved_string
,
0
,
SCRATCH_SIZE
);
memset
(
dtp
->
u
.
p
.
saved_string
,
0
,
SCRATCH_SIZE
);
dtp
->
u
.
p
.
saved_length
=
SCRATCH_SIZE
;
dtp
->
u
.
p
.
saved_length
=
SCRATCH_SIZE
;
dtp
->
u
.
p
.
saved_used
=
0
;
dtp
->
u
.
p
.
saved_used
=
0
;
...
@@ -90,15 +90,15 @@ push_char (st_parameter_dt *dtp, char c)
...
@@ -90,15 +90,15 @@ push_char (st_parameter_dt *dtp, char c)
if
(
dtp
->
u
.
p
.
saved_used
>=
dtp
->
u
.
p
.
saved_length
)
if
(
dtp
->
u
.
p
.
saved_used
>=
dtp
->
u
.
p
.
saved_length
)
{
{
dtp
->
u
.
p
.
saved_length
=
2
*
dtp
->
u
.
p
.
saved_length
;
dtp
->
u
.
p
.
saved_length
=
2
*
dtp
->
u
.
p
.
saved_length
;
new
=
realloc
(
dtp
->
u
.
p
.
saved_string
,
dtp
->
u
.
p
.
saved_length
);
new
=
get_mem
(
2
*
dtp
->
u
.
p
.
saved_length
);
if
(
new
==
NULL
)
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
dtp
->
u
.
p
.
saved_string
=
new
;
// Also this should not be necessary.
memset
(
new
+
dtp
->
u
.
p
.
saved_used
,
0
,
dtp
->
u
.
p
.
saved_length
-
dtp
->
u
.
p
.
saved_used
);
memset
(
new
,
0
,
2
*
dtp
->
u
.
p
.
saved_length
);
memcpy
(
new
,
dtp
->
u
.
p
.
saved_string
,
dtp
->
u
.
p
.
saved_used
);
if
(
dtp
->
u
.
p
.
saved_string
!=
dtp
->
u
.
p
.
scratch
)
free_mem
(
dtp
->
u
.
p
.
saved_string
);
dtp
->
u
.
p
.
saved_string
=
new
;
}
}
dtp
->
u
.
p
.
saved_string
[
dtp
->
u
.
p
.
saved_used
++
]
=
c
;
dtp
->
u
.
p
.
saved_string
[
dtp
->
u
.
p
.
saved_used
++
]
=
c
;
...
@@ -113,7 +113,8 @@ free_saved (st_parameter_dt *dtp)
...
@@ -113,7 +113,8 @@ free_saved (st_parameter_dt *dtp)
if
(
dtp
->
u
.
p
.
saved_string
==
NULL
)
if
(
dtp
->
u
.
p
.
saved_string
==
NULL
)
return
;
return
;
free_mem
(
dtp
->
u
.
p
.
saved_string
);
if
(
dtp
->
u
.
p
.
saved_string
!=
dtp
->
u
.
p
.
scratch
)
free_mem
(
dtp
->
u
.
p
.
saved_string
);
dtp
->
u
.
p
.
saved_string
=
NULL
;
dtp
->
u
.
p
.
saved_string
=
NULL
;
dtp
->
u
.
p
.
saved_used
=
0
;
dtp
->
u
.
p
.
saved_used
=
0
;
...
@@ -139,10 +140,9 @@ free_line (st_parameter_dt *dtp)
...
@@ -139,10 +140,9 @@ free_line (st_parameter_dt *dtp)
static
char
static
char
next_char
(
st_parameter_dt
*
dtp
)
next_char
(
st_parameter_dt
*
dtp
)
{
{
s
s
ize_t
length
;
size_t
length
;
gfc_offset
record
;
gfc_offset
record
;
char
c
;
char
c
;
int
cc
;
if
(
dtp
->
u
.
p
.
last_char
!=
'\0'
)
if
(
dtp
->
u
.
p
.
last_char
!=
'\0'
)
{
{
...
@@ -194,7 +194,7 @@ next_char (st_parameter_dt *dtp)
...
@@ -194,7 +194,7 @@ next_char (st_parameter_dt *dtp)
}
}
record
*=
dtp
->
u
.
p
.
current_unit
->
recl
;
record
*=
dtp
->
u
.
p
.
current_unit
->
recl
;
if
(
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
record
,
SEEK_SET
)
<
0
)
if
(
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
record
)
==
FAILURE
)
longjmp
(
*
dtp
->
u
.
p
.
eof_jump
,
1
);
longjmp
(
*
dtp
->
u
.
p
.
eof_jump
,
1
);
dtp
->
u
.
p
.
current_unit
->
bytes_left
=
dtp
->
u
.
p
.
current_unit
->
recl
;
dtp
->
u
.
p
.
current_unit
->
bytes_left
=
dtp
->
u
.
p
.
current_unit
->
recl
;
...
@@ -204,15 +204,19 @@ next_char (st_parameter_dt *dtp)
...
@@ -204,15 +204,19 @@ next_char (st_parameter_dt *dtp)
/* Get the next character and handle end-of-record conditions. */
/* Get the next character and handle end-of-record conditions. */
if
(
is_internal_unit
(
dtp
))
length
=
1
;
if
(
sread
(
dtp
->
u
.
p
.
current_unit
->
s
,
&
c
,
&
length
)
!=
0
)
{
{
length
=
sread
(
dtp
->
u
.
p
.
current_unit
->
s
,
&
c
,
1
);
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
if
(
length
<
0
)
return
'\0'
;
{
}
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
return
'\0'
;
}
if
(
is_stream_io
(
dtp
)
&&
length
==
1
)
dtp
->
u
.
p
.
current_unit
->
strm_pos
++
;
if
(
is_internal_unit
(
dtp
))
{
if
(
is_array_io
(
dtp
))
if
(
is_array_io
(
dtp
))
{
{
/* Check whether we hit EOF. */
/* Check whether we hit EOF. */
...
@@ -236,20 +240,13 @@ next_char (st_parameter_dt *dtp)
...
@@ -236,20 +240,13 @@ next_char (st_parameter_dt *dtp)
}
}
else
else
{
{
cc
=
fbuf_getc
(
dtp
->
u
.
p
.
current_unit
);
if
(
length
==
0
)
if
(
cc
==
EOF
)
{
{
if
(
dtp
->
u
.
p
.
current_unit
->
endfile
==
AT_ENDFILE
)
if
(
dtp
->
u
.
p
.
current_unit
->
endfile
==
AT_ENDFILE
)
longjmp
(
*
dtp
->
u
.
p
.
eof_jump
,
1
);
longjmp
(
*
dtp
->
u
.
p
.
eof_jump
,
1
);
dtp
->
u
.
p
.
current_unit
->
endfile
=
AT_ENDFILE
;
dtp
->
u
.
p
.
current_unit
->
endfile
=
AT_ENDFILE
;
c
=
'\n'
;
c
=
'\n'
;
}
}
else
c
=
(
char
)
cc
;
if
(
is_stream_io
(
dtp
)
&&
cc
!=
EOF
)
dtp
->
u
.
p
.
current_unit
->
strm_pos
++
;
}
}
done:
done:
dtp
->
u
.
p
.
at_eol
=
(
c
==
'\n'
||
c
==
'\r'
);
dtp
->
u
.
p
.
at_eol
=
(
c
==
'\n'
||
c
==
'\r'
);
...
@@ -1701,7 +1698,7 @@ list_formatted_read_scalar (st_parameter_dt *dtp, volatile bt type, void *p,
...
@@ -1701,7 +1698,7 @@ list_formatted_read_scalar (st_parameter_dt *dtp, volatile bt type, void *p,
dtp
->
u
.
p
.
input_complete
=
0
;
dtp
->
u
.
p
.
input_complete
=
0
;
dtp
->
u
.
p
.
repeat_count
=
1
;
dtp
->
u
.
p
.
repeat_count
=
1
;
dtp
->
u
.
p
.
at_eol
=
0
;
dtp
->
u
.
p
.
at_eol
=
0
;
c
=
eat_spaces
(
dtp
);
c
=
eat_spaces
(
dtp
);
if
(
is_separator
(
c
))
if
(
is_separator
(
c
))
{
{
...
@@ -1856,8 +1853,6 @@ finish_list_read (st_parameter_dt *dtp)
...
@@ -1856,8 +1853,6 @@ finish_list_read (st_parameter_dt *dtp)
free_saved
(
dtp
);
free_saved
(
dtp
);
fbuf_flush
(
dtp
->
u
.
p
.
current_unit
,
dtp
->
u
.
p
.
mode
);
if
(
dtp
->
u
.
p
.
at_eol
)
if
(
dtp
->
u
.
p
.
at_eol
)
{
{
dtp
->
u
.
p
.
at_eol
=
0
;
dtp
->
u
.
p
.
at_eol
=
0
;
...
@@ -2266,8 +2261,8 @@ nml_query (st_parameter_dt *dtp, char c)
...
@@ -2266,8 +2261,8 @@ nml_query (st_parameter_dt *dtp, char c)
/* Flush the stream to force immediate output. */
/* Flush the stream to force immediate output. */
fbuf_flush
(
dtp
->
u
.
p
.
current_unit
,
WRITING
);
fbuf_flush
(
dtp
->
u
.
p
.
current_unit
,
1
);
s
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
);
}
}
...
@@ -2908,7 +2903,7 @@ find_nml_name:
...
@@ -2908,7 +2903,7 @@ find_nml_name:
st_printf
(
"%s
\n
"
,
nml_err_msg
);
st_printf
(
"%s
\n
"
,
nml_err_msg
);
if
(
u
!=
NULL
)
if
(
u
!=
NULL
)
{
{
s
flush
(
u
->
s
);
flush
(
u
->
s
);
unlock_unit
(
u
);
unlock_unit
(
u
);
}
}
}
}
...
...
libgfortran/io/transfer.c
View file @
f3ed1d02
...
@@ -37,7 +37,6 @@ Boston, MA 02110-1301, USA. */
...
@@ -37,7 +37,6 @@ Boston, MA 02110-1301, USA. */
#include <string.h>
#include <string.h>
#include <assert.h>
#include <assert.h>
#include <stdlib.h>
#include <stdlib.h>
#include <errno.h>
/* Calling conventions: Data transfer statements are unlike other
/* Calling conventions: Data transfer statements are unlike other
...
@@ -184,58 +183,60 @@ current_mode (st_parameter_dt *dtp)
...
@@ -184,58 +183,60 @@ current_mode (st_parameter_dt *dtp)
heap. Hopefully this won't happen very often. */
heap. Hopefully this won't happen very often. */
char
*
char
*
read_sf
(
st_parameter_dt
*
dtp
,
int
*
length
,
int
no_error
)
read_sf
(
st_parameter_dt
*
dtp
,
int
*
length
,
int
no_error
)
{
{
static
char
*
empty_string
[
0
];
char
*
base
,
*
p
,
q
;
char
*
base
,
*
p
,
q
;
int
n
,
lorig
,
memread
,
seen_comma
;
int
n
,
crlf
;
gfc_offset
pos
;
size_t
readlen
;
/* If we hit EOF previously with the no_error flag set (i.e. X, T,
if
(
*
length
>
SCRATCH_SIZE
)
TR edit descriptors), and we now try to read again, this time
dtp
->
u
.
p
.
line_buffer
=
get_mem
(
*
length
);
without setting no_error. */
p
=
base
=
dtp
->
u
.
p
.
line_buffer
;
if
(
!
no_error
&&
dtp
->
u
.
p
.
at_eof
)
{
*
length
=
0
;
hit_eof
(
dtp
);
return
NULL
;
}
/* If we have seen an eor previously, return a length of 0. The
/* If we have seen an eor previously, return a length of 0. The
caller is responsible for correctly padding the input field. */
caller is responsible for correctly padding the input field. */
if
(
dtp
->
u
.
p
.
sf_seen_eor
)
if
(
dtp
->
u
.
p
.
sf_seen_eor
)
{
{
*
length
=
0
;
*
length
=
0
;
/* Just return something that isn't a NULL pointer, otherwise the
return
base
;
caller thinks an error occured. */
return
(
char
*
)
empty_string
;
}
}
if
(
is_internal_unit
(
dtp
))
if
(
is_internal_unit
(
dtp
))
{
{
memread
=
*
length
;
readlen
=
*
length
;
base
=
mem_alloc_r
(
dtp
->
u
.
p
.
current_unit
->
s
,
length
);
if
(
unlikely
(
sread
(
dtp
->
u
.
p
.
current_unit
->
s
,
p
,
&
readlen
)
!=
0
if
(
unlikely
(
memread
>
*
length
))
||
readlen
<
(
size_t
)
*
length
))
{
{
hit_eof
(
dtp
);
generate_error
(
&
dtp
->
common
,
LIBERROR_END
,
NULL
);
return
NULL
;
return
NULL
;
}
}
n
=
*
length
;
goto
done
;
goto
done
;
}
}
n
=
seen_comma
=
0
;
readlen
=
1
;
n
=
0
;
/* Read data into format buffer and scan through it. */
do
lorig
=
*
length
;
base
=
p
=
fbuf_read
(
dtp
->
u
.
p
.
current_unit
,
length
);
if
(
base
==
NULL
)
return
NULL
;
while
(
n
<
*
length
)
{
{
q
=
*
p
;
if
(
unlikely
(
sread
(
dtp
->
u
.
p
.
current_unit
->
s
,
&
q
,
&
readlen
)
!=
0
))
{
generate_error
(
&
dtp
->
common
,
LIBERROR_END
,
NULL
);
return
NULL
;
}
if
(
q
==
'\n'
||
q
==
'\r'
)
/* If we have a line without a terminating \n, drop through to
EOR below. */
if
(
readlen
<
1
&&
n
==
0
)
{
if
(
likely
(
no_error
))
break
;
generate_error
(
&
dtp
->
common
,
LIBERROR_END
,
NULL
);
return
NULL
;
}
if
(
readlen
<
1
||
q
==
'\n'
||
q
==
'\r'
)
{
{
/* Unexpected end of line. */
/* Unexpected end of line. */
...
@@ -244,14 +245,23 @@ read_sf (st_parameter_dt *dtp, int * length, int no_error)
...
@@ -244,14 +245,23 @@ read_sf (st_parameter_dt *dtp, int * length, int no_error)
if
(
dtp
->
u
.
p
.
advance_status
==
ADVANCE_NO
||
dtp
->
u
.
p
.
seen_dollar
)
if
(
dtp
->
u
.
p
.
advance_status
==
ADVANCE_NO
||
dtp
->
u
.
p
.
seen_dollar
)
dtp
->
u
.
p
.
eor_condition
=
1
;
dtp
->
u
.
p
.
eor_condition
=
1
;
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 */
{
{
if
(
n
<
*
length
&&
*
(
p
+
1
)
==
'\n'
)
readlen
=
1
;
dtp
->
u
.
p
.
sf_seen_eor
=
2
;
pos
=
stream_offset
(
dtp
->
u
.
p
.
current_unit
->
s
);
if
(
unlikely
(
sread
(
dtp
->
u
.
p
.
current_unit
->
s
,
&
q
,
&
readlen
)
!=
0
))
{
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
);
else
crlf
=
1
;
}
}
else
dtp
->
u
.
p
.
sf_seen_eor
=
1
;
/* Without padding, terminate the I/O statement without assigning
/* Without padding, terminate the I/O statement without assigning
the value. With padding, the value still needs to be assigned,
the value. With padding, the value still needs to be assigned,
...
@@ -265,6 +275,7 @@ read_sf (st_parameter_dt *dtp, int * length, int no_error)
...
@@ -265,6 +275,7 @@ read_sf (st_parameter_dt *dtp, int * length, int no_error)
}
}
*
length
=
n
;
*
length
=
n
;
dtp
->
u
.
p
.
sf_seen_eor
=
(
crlf
?
2
:
1
);
break
;
break
;
}
}
/* Short circuit the read if a comma is found during numeric input.
/* Short circuit the read if a comma is found during numeric input.
...
@@ -273,7 +284,6 @@ read_sf (st_parameter_dt *dtp, int * length, int no_error)
...
@@ -273,7 +284,6 @@ read_sf (st_parameter_dt *dtp, int * length, int no_error)
if
(
q
==
','
)
if
(
q
==
','
)
if
(
dtp
->
u
.
p
.
sf_read_comma
==
1
)
if
(
dtp
->
u
.
p
.
sf_read_comma
==
1
)
{
{
seen_comma
=
1
;
notify_std
(
&
dtp
->
common
,
GFC_STD_GNU
,
notify_std
(
&
dtp
->
common
,
GFC_STD_GNU
,
"Comma in formatted numeric read."
);
"Comma in formatted numeric read."
);
*
length
=
n
;
*
length
=
n
;
...
@@ -281,31 +291,16 @@ read_sf (st_parameter_dt *dtp, int * length, int no_error)
...
@@ -281,31 +291,16 @@ read_sf (st_parameter_dt *dtp, int * length, int no_error)
}
}
n
++
;
n
++
;
p
++
;
*
p
++
=
q
;
}
dtp
->
u
.
p
.
sf_seen_eor
=
0
;
fbuf_seek
(
dtp
->
u
.
p
.
current_unit
,
n
+
dtp
->
u
.
p
.
sf_seen_eor
+
seen_comma
,
SEEK_CUR
);
/* A short read implies we hit EOF, unless we hit EOR, a comma, or
some other stuff. Set the relevant flags. */
if
(
lorig
>
*
length
&&
!
dtp
->
u
.
p
.
sf_seen_eor
&&
!
seen_comma
)
{
if
(
no_error
)
dtp
->
u
.
p
.
at_eof
=
1
;
else
{
hit_eof
(
dtp
);
return
NULL
;
}
}
}
while
(
n
<
*
length
);
done:
done:
dtp
->
u
.
p
.
current_unit
->
bytes_left
-=
*
length
;
dtp
->
u
.
p
.
current_unit
->
bytes_left
-=
n
;
if
((
dtp
->
common
.
flags
&
IOPARM_DT_HAS_SIZE
)
!=
0
)
if
((
dtp
->
common
.
flags
&
IOPARM_DT_HAS_SIZE
)
!=
0
)
dtp
->
u
.
p
.
size_used
+=
(
GFC_IO_INT
)
n
;
dtp
->
u
.
p
.
size_used
+=
(
GFC_IO_INT
)
*
length
;
return
base
;
return
base
;
}
}
...
@@ -321,11 +316,12 @@ read_sf (st_parameter_dt *dtp, int * length, int no_error)
...
@@ -321,11 +316,12 @@ read_sf (st_parameter_dt *dtp, int * length, int no_error)
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_form
(
st_parameter_dt
*
dtp
,
int
*
nbytes
)
read_block_form
(
st_parameter_dt
*
dtp
,
void
*
buf
,
size_t
*
nbytes
)
{
{
char
*
source
;
char
*
source
;
int
norig
;
size_t
nread
;
int
nb
;
if
(
!
is_stream_io
(
dtp
))
if
(
!
is_stream_io
(
dtp
))
{
{
...
@@ -342,14 +338,15 @@ read_block_form (st_parameter_dt *dtp, int * nbytes)
...
@@ -342,14 +338,15 @@ read_block_form (st_parameter_dt *dtp, int * nbytes)
{
{
/* 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
;
}
}
}
}
if
(
unlikely
(
dtp
->
u
.
p
.
current_unit
->
bytes_left
==
0
))
if
(
unlikely
(
dtp
->
u
.
p
.
current_unit
->
bytes_left
==
0
))
{
{
hit_eof
(
dtp
);
dtp
->
u
.
p
.
current_unit
->
endfile
=
AT_ENDFILE
;
return
NULL
;
generate_error
(
&
dtp
->
common
,
LIBERROR_END
,
NULL
);
return
FAILURE
;
}
}
*
nbytes
=
dtp
->
u
.
p
.
current_unit
->
bytes_left
;
*
nbytes
=
dtp
->
u
.
p
.
current_unit
->
bytes_left
;
...
@@ -360,36 +357,42 @@ read_block_form (st_parameter_dt *dtp, int * nbytes)
...
@@ -360,36 +357,42 @@ read_block_form (st_parameter_dt *dtp, int * nbytes)
(
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
,
nbytes
,
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
)
(
*
nbytes
+
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
;
}
}
/* If we reach here, we can assume it's direct access. */
dtp
->
u
.
p
.
current_unit
->
bytes_left
-=
(
gfc_offset
)
*
nbytes
;
dtp
->
u
.
p
.
current_unit
->
bytes_left
-=
(
gfc_offset
)
*
nbytes
;
norig
=
*
nbytes
;
nread
=
*
nbytes
;
source
=
fbuf_read
(
dtp
->
u
.
p
.
current_unit
,
nbytes
);
if
(
unlikely
(
sread
(
dtp
->
u
.
p
.
current_unit
->
s
,
buf
,
&
nread
)
!=
0
))
fbuf_seek
(
dtp
->
u
.
p
.
current_unit
,
*
nbytes
,
SEEK_CUR
);
{
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_IO_INT
)
*
nbytes
;
dtp
->
u
.
p
.
size_used
+=
(
GFC_IO_INT
)
nread
;
if
(
norig
!=
*
nbytes
)
if
(
nread
!=
*
nbytes
)
{
{
/* Short read, this shouldn't happen. */
/* Short read, this shouldn't happen. */
if
(
likely
(
dtp
->
u
.
p
.
current_unit
->
pad_status
==
PAD_YES
))
if
(
!
dtp
->
u
.
p
.
current_unit
->
pad_status
==
PAD_YES
)
*
nbytes
=
nread
;
else
{
{
generate_error
(
&
dtp
->
common
,
LIBERROR_EOR
,
NULL
);
generate_error
(
&
dtp
->
common
,
LIBERROR_EOR
,
NULL
);
source
=
NULL
;
source
=
NULL
;
}
}
}
}
dtp
->
u
.
p
.
current_unit
->
strm_pos
+=
(
gfc_offset
)
*
nbytes
;
dtp
->
u
.
p
.
current_unit
->
strm_pos
+=
(
gfc_offset
)
nread
;
return
source
;
return
SUCCESS
;
}
}
...
@@ -399,18 +402,18 @@ read_block_form (st_parameter_dt *dtp, int * nbytes)
...
@@ -399,18 +402,18 @@ read_block_form (st_parameter_dt *dtp, int * nbytes)
static
void
static
void
read_block_direct
(
st_parameter_dt
*
dtp
,
void
*
buf
,
size_t
*
nbytes
)
read_block_direct
(
st_parameter_dt
*
dtp
,
void
*
buf
,
size_t
*
nbytes
)
{
{
s
s
ize_t
to_read_record
;
size_t
to_read_record
;
s
s
ize_t
have_read_record
;
size_t
have_read_record
;
s
s
ize_t
to_read_subrecord
;
size_t
to_read_subrecord
;
s
s
ize_t
have_read_subrecord
;
size_t
have_read_subrecord
;
int
short_record
;
int
short_record
;
if
(
is_stream_io
(
dtp
))
if
(
is_stream_io
(
dtp
))
{
{
to_read_record
=
*
nbytes
;
to_read_record
=
*
nbytes
;
have_read_record
=
sread
(
dtp
->
u
.
p
.
current_unit
->
s
,
buf
,
have_read_record
=
to_read_record
;
to_read_record
);
if
(
unlikely
(
sread
(
dtp
->
u
.
p
.
current_unit
->
s
,
buf
,
&
have_read_record
)
if
(
unlikely
(
have_read_record
<
0
))
!=
0
))
{
{
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
return
;
return
;
...
@@ -422,7 +425,7 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
...
@@ -422,7 +425,7 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
{
{
/* Short read, e.g. if we hit EOF. For stream files,
/* Short read, e.g. if we hit EOF. For stream files,
we have to set the end-of-file condition. */
we have to set the end-of-file condition. */
hit_eof
(
dtp
);
generate_error
(
&
dtp
->
common
,
LIBERROR_END
,
NULL
);
return
;
return
;
}
}
return
;
return
;
...
@@ -445,14 +448,14 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
...
@@ -445,14 +448,14 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
dtp
->
u
.
p
.
current_unit
->
bytes_left
-=
to_read_record
;
dtp
->
u
.
p
.
current_unit
->
bytes_left
-=
to_read_record
;
to_read_record
=
sread
(
dtp
->
u
.
p
.
current_unit
->
s
,
buf
,
to_read_record
);
if
(
unlikely
(
sread
(
dtp
->
u
.
p
.
current_unit
->
s
,
buf
,
&
to_read_record
)
if
(
unlikely
(
to_read_record
<
0
))
!=
0
))
{
{
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
return
;
return
;
}
}
if
(
to_read_record
!=
(
ssize_t
)
*
nbytes
)
if
(
to_read_record
!=
*
nbytes
)
{
{
/* Short read, e.g. if we hit EOF. Apparently, we read
/* Short read, e.g. if we hit EOF. Apparently, we read
more than was written to the last record. */
more than was written to the last record. */
...
@@ -472,12 +475,18 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
...
@@ -472,12 +475,18 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
until the request has been fulfilled or the record has run out
until the request has been fulfilled or the record has run out
of continuation subrecords. */
of continuation subrecords. */
if
(
unlikely
(
dtp
->
u
.
p
.
current_unit
->
endfile
==
AT_ENDFILE
))
{
generate_error
(
&
dtp
->
common
,
LIBERROR_END
,
NULL
);
return
;
}
/* Check whether we exceed the total record length. */
/* Check whether we exceed the total record length. */
if
(
dtp
->
u
.
p
.
current_unit
->
flags
.
has_recl
if
(
dtp
->
u
.
p
.
current_unit
->
flags
.
has_recl
&&
(
*
nbytes
>
(
size_t
)
dtp
->
u
.
p
.
current_unit
->
bytes_left
))
&&
(
*
nbytes
>
(
size_t
)
dtp
->
u
.
p
.
current_unit
->
bytes_left
))
{
{
to_read_record
=
(
s
s
ize_t
)
dtp
->
u
.
p
.
current_unit
->
bytes_left
;
to_read_record
=
(
size_t
)
dtp
->
u
.
p
.
current_unit
->
bytes_left
;
short_record
=
1
;
short_record
=
1
;
}
}
else
else
...
@@ -492,7 +501,7 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
...
@@ -492,7 +501,7 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
if
(
dtp
->
u
.
p
.
current_unit
->
bytes_left_subrecord
if
(
dtp
->
u
.
p
.
current_unit
->
bytes_left_subrecord
<
(
gfc_offset
)
to_read_record
)
<
(
gfc_offset
)
to_read_record
)
{
{
to_read_subrecord
=
(
s
s
ize_t
)
dtp
->
u
.
p
.
current_unit
->
bytes_left_subrecord
;
to_read_subrecord
=
(
size_t
)
dtp
->
u
.
p
.
current_unit
->
bytes_left_subrecord
;
to_read_record
-=
to_read_subrecord
;
to_read_record
-=
to_read_subrecord
;
}
}
else
else
...
@@ -503,9 +512,9 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
...
@@ -503,9 +512,9 @@ read_block_direct (st_parameter_dt *dtp, void *buf, size_t *nbytes)
dtp
->
u
.
p
.
current_unit
->
bytes_left_subrecord
-=
to_read_subrecord
;
dtp
->
u
.
p
.
current_unit
->
bytes_left_subrecord
-=
to_read_subrecord
;
have_read_subrecord
=
sread
(
dtp
->
u
.
p
.
current_unit
->
s
,
have_read_subrecord
=
to_read_subrecord
;
buf
+
have_read_record
,
to_read_subrecord
);
if
(
unlikely
(
sread
(
dtp
->
u
.
p
.
current_unit
->
s
,
buf
+
have_read_record
,
if
(
unlikely
(
have_read_subrecord
)
<
0
)
&
have_read_subrecord
)
!=
0
)
)
{
{
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
return
;
return
;
...
@@ -594,7 +603,7 @@ write_block (st_parameter_dt *dtp, int length)
...
@@ -594,7 +603,7 @@ write_block (st_parameter_dt *dtp, int length)
if
(
is_internal_unit
(
dtp
))
if
(
is_internal_unit
(
dtp
))
{
{
dest
=
mem_
alloc_w
(
dtp
->
u
.
p
.
current_unit
->
s
,
&
length
);
dest
=
s
alloc_w
(
dtp
->
u
.
p
.
current_unit
->
s
,
&
length
);
if
(
dest
==
NULL
)
if
(
dest
==
NULL
)
{
{
...
@@ -632,22 +641,20 @@ static try
...
@@ -632,22 +641,20 @@ static try
write_buf
(
st_parameter_dt
*
dtp
,
void
*
buf
,
size_t
nbytes
)
write_buf
(
st_parameter_dt
*
dtp
,
void
*
buf
,
size_t
nbytes
)
{
{
ssize_t
have_written
;
size_t
have_written
,
to_write_subrecord
;
ssize_t
to_write_subrecord
;
int
short_record
;
int
short_record
;
/* Stream I/O. */
/* Stream I/O. */
if
(
is_stream_io
(
dtp
))
if
(
is_stream_io
(
dtp
))
{
{
have_written
=
swrite
(
dtp
->
u
.
p
.
current_unit
->
s
,
buf
,
nbytes
);
if
(
unlikely
(
swrite
(
dtp
->
u
.
p
.
current_unit
->
s
,
buf
,
&
nbytes
)
!=
0
))
if
(
unlikely
(
have_written
<
0
))
{
{
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
return
FAILURE
;
return
FAILURE
;
}
}
dtp
->
u
.
p
.
current_unit
->
strm_pos
+=
(
gfc_offset
)
have_written
;
dtp
->
u
.
p
.
current_unit
->
strm_pos
+=
(
gfc_offset
)
nbytes
;
return
SUCCESS
;
return
SUCCESS
;
}
}
...
@@ -665,15 +672,14 @@ write_buf (st_parameter_dt *dtp, void *buf, size_t nbytes)
...
@@ -665,15 +672,14 @@ write_buf (st_parameter_dt *dtp, void *buf, size_t nbytes)
if
(
buf
==
NULL
&&
nbytes
==
0
)
if
(
buf
==
NULL
&&
nbytes
==
0
)
return
SUCCESS
;
return
SUCCESS
;
have_written
=
swrite
(
dtp
->
u
.
p
.
current_unit
->
s
,
buf
,
nbytes
);
if
(
unlikely
(
swrite
(
dtp
->
u
.
p
.
current_unit
->
s
,
buf
,
&
nbytes
)
!=
0
))
if
(
unlikely
(
have_written
<
0
))
{
{
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
return
FAILURE
;
return
FAILURE
;
}
}
dtp
->
u
.
p
.
current_unit
->
strm_pos
+=
(
gfc_offset
)
have_written
;
dtp
->
u
.
p
.
current_unit
->
strm_pos
+=
(
gfc_offset
)
nbytes
;
dtp
->
u
.
p
.
current_unit
->
bytes_left
-=
(
gfc_offset
)
have_written
;
dtp
->
u
.
p
.
current_unit
->
bytes_left
-=
(
gfc_offset
)
nbytes
;
return
SUCCESS
;
return
SUCCESS
;
}
}
...
@@ -703,9 +709,8 @@ write_buf (st_parameter_dt *dtp, void *buf, size_t nbytes)
...
@@ -703,9 +709,8 @@ write_buf (st_parameter_dt *dtp, void *buf, size_t nbytes)
dtp
->
u
.
p
.
current_unit
->
bytes_left_subrecord
-=
dtp
->
u
.
p
.
current_unit
->
bytes_left_subrecord
-=
(
gfc_offset
)
to_write_subrecord
;
(
gfc_offset
)
to_write_subrecord
;
to_write_subrecord
=
swrite
(
dtp
->
u
.
p
.
current_unit
->
s
,
if
(
unlikely
(
swrite
(
dtp
->
u
.
p
.
current_unit
->
s
,
buf
+
have_written
,
buf
+
have_written
,
to_write_subrecord
);
&
to_write_subrecord
)
!=
0
))
if
(
unlikely
(
to_write_subrecord
<
0
))
{
{
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
return
FAILURE
;
return
FAILURE
;
...
@@ -927,6 +932,7 @@ static void
...
@@ -927,6 +932,7 @@ static void
formatted_transfer_scalar
(
st_parameter_dt
*
dtp
,
bt
type
,
void
*
p
,
int
kind
,
formatted_transfer_scalar
(
st_parameter_dt
*
dtp
,
bt
type
,
void
*
p
,
int
kind
,
size_t
size
)
size_t
size
)
{
{
char
scratch
[
SCRATCH_SIZE
];
int
pos
,
bytes_used
;
int
pos
,
bytes_used
;
const
fnode
*
f
;
const
fnode
*
f
;
format_token
t
;
format_token
t
;
...
@@ -953,6 +959,8 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
...
@@ -953,6 +959,8 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
dtp
->
u
.
p
.
sf_read_comma
=
dtp
->
u
.
p
.
sf_read_comma
=
dtp
->
u
.
p
.
current_unit
->
decimal_status
==
DECIMAL_COMMA
?
0
:
1
;
dtp
->
u
.
p
.
current_unit
->
decimal_status
==
DECIMAL_COMMA
?
0
:
1
;
dtp
->
u
.
p
.
line_buffer
=
scratch
;
for
(;;)
for
(;;)
{
{
/* If reversion has occurred and there is another real data item,
/* If reversion has occurred and there is another real data item,
...
@@ -1002,7 +1010,7 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
...
@@ -1002,7 +1010,7 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
if
(
is_internal_unit
(
dtp
))
if
(
is_internal_unit
(
dtp
))
move_pos_offset
(
dtp
->
u
.
p
.
current_unit
->
s
,
dtp
->
u
.
p
.
skips
);
move_pos_offset
(
dtp
->
u
.
p
.
current_unit
->
s
,
dtp
->
u
.
p
.
skips
);
else
else
fbuf_seek
(
dtp
->
u
.
p
.
current_unit
,
dtp
->
u
.
p
.
skips
,
SEEK_CUR
);
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
;
...
@@ -1213,7 +1221,7 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
...
@@ -1213,7 +1221,7 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
break
;
break
;
case
BT_REAL
:
case
BT_REAL
:
if
(
f
->
u
.
real
.
w
==
0
)
if
(
f
->
u
.
real
.
w
==
0
)
write_real_g0
(
dtp
,
p
,
kind
,
f
->
u
.
real
.
d
);
write_real_g0
(
dtp
,
p
,
kind
,
f
->
u
.
real
.
d
);
else
else
write_d
(
dtp
,
f
,
p
,
kind
);
write_d
(
dtp
,
f
,
p
,
kind
);
break
;
break
;
...
@@ -1243,6 +1251,7 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
...
@@ -1243,6 +1251,7 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
dtp
->
u
.
p
.
skips
+=
f
->
u
.
n
;
dtp
->
u
.
p
.
skips
+=
f
->
u
.
n
;
pos
=
bytes_used
+
dtp
->
u
.
p
.
skips
-
1
;
pos
=
bytes_used
+
dtp
->
u
.
p
.
skips
-
1
;
dtp
->
u
.
p
.
pending_spaces
=
pos
-
dtp
->
u
.
p
.
max_pos
+
1
;
dtp
->
u
.
p
.
pending_spaces
=
pos
-
dtp
->
u
.
p
.
max_pos
+
1
;
/* Writes occur just before the switch on f->format, above, so
/* Writes occur just before the switch on f->format, above, so
that trailing blanks are suppressed, unless we are doing a
that trailing blanks are suppressed, unless we are doing a
non-advancing write in which case we want to output the blanks
non-advancing write in which case we want to output the blanks
...
@@ -1307,17 +1316,24 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
...
@@ -1307,17 +1316,24 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
/* Adjust everything for end-of-record condition */
/* Adjust everything for end-of-record condition */
if
(
dtp
->
u
.
p
.
sf_seen_eor
&&
!
is_internal_unit
(
dtp
))
if
(
dtp
->
u
.
p
.
sf_seen_eor
&&
!
is_internal_unit
(
dtp
))
{
{
dtp
->
u
.
p
.
current_unit
->
bytes_left
-=
dtp
->
u
.
p
.
sf_seen_eor
;
if
(
dtp
->
u
.
p
.
sf_seen_eor
==
2
)
dtp
->
u
.
p
.
skips
-=
dtp
->
u
.
p
.
sf_seen_eor
;
{
/* The EOR was a CRLF (two bytes wide). */
dtp
->
u
.
p
.
current_unit
->
bytes_left
-=
2
;
dtp
->
u
.
p
.
skips
-=
2
;
}
else
{
/* The EOR marker was only one byte wide. */
dtp
->
u
.
p
.
current_unit
->
bytes_left
--
;
dtp
->
u
.
p
.
skips
--
;
}
bytes_used
=
pos
;
bytes_used
=
pos
;
dtp
->
u
.
p
.
sf_seen_eor
=
0
;
dtp
->
u
.
p
.
sf_seen_eor
=
0
;
}
}
if
(
dtp
->
u
.
p
.
skips
<
0
)
if
(
dtp
->
u
.
p
.
skips
<
0
)
{
{
if
(
is_internal_unit
(
dtp
))
move_pos_offset
(
dtp
->
u
.
p
.
current_unit
->
s
,
dtp
->
u
.
p
.
skips
);
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
,
SEEK_CUR
);
dtp
->
u
.
p
.
current_unit
->
bytes_left
dtp
->
u
.
p
.
current_unit
->
bytes_left
-=
(
gfc_offset
)
dtp
->
u
.
p
.
skips
;
-=
(
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
;
...
@@ -1393,6 +1409,16 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
...
@@ -1393,6 +1409,16 @@ formatted_transfer_scalar (st_parameter_dt *dtp, bt type, void *p, int kind,
internal_error
(
&
dtp
->
common
,
"Bad format node"
);
internal_error
(
&
dtp
->
common
,
"Bad format node"
);
}
}
/* Free a buffer that we had to allocate during a sequential
formatted read of a block that was larger than the static
buffer. */
if
(
dtp
->
u
.
p
.
line_buffer
!=
scratch
)
{
free_mem
(
dtp
->
u
.
p
.
line_buffer
);
dtp
->
u
.
p
.
line_buffer
=
scratch
;
}
/* Adjust the item count and data pointer. */
/* Adjust the item count and data pointer. */
if
((
consume_data_flag
>
0
)
&&
(
n
>
0
))
if
((
consume_data_flag
>
0
)
&&
(
n
>
0
))
...
@@ -1631,28 +1657,34 @@ transfer_array (st_parameter_dt *dtp, gfc_array_char *desc, int kind,
...
@@ -1631,28 +1657,34 @@ 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
)
{
{
s
s
ize_t
n
,
nr
;
size_t
n
,
nr
;
GFC_INTEGER_4
i4
;
GFC_INTEGER_4
i4
;
GFC_INTEGER_8
i8
;
GFC_INTEGER_8
i8
;
gfc_offset
i
;
gfc_offset
i
;
if
(
dtp
->
u
.
p
.
current_unit
->
endfile
==
AT_ENDFILE
)
return
;
if
(
compile_options
.
record_marker
==
0
)
if
(
compile_options
.
record_marker
==
0
)
n
=
sizeof
(
GFC_INTEGER_4
);
n
=
sizeof
(
GFC_INTEGER_4
);
else
else
n
=
compile_options
.
record_marker
;
n
=
compile_options
.
record_marker
;
nr
=
sread
(
dtp
->
u
.
p
.
current_unit
->
s
,
&
i
,
n
);
nr
=
n
;
if
(
unlikely
(
nr
<
0
))
if
(
unlikely
(
sread
(
dtp
->
u
.
p
.
current_unit
->
s
,
&
i
,
&
n
)
!=
0
))
{
{
generate_error
(
&
dtp
->
common
,
LIBERROR_BAD_US
,
NULL
);
generate_error
(
&
dtp
->
common
,
LIBERROR_BAD_US
,
NULL
);
return
;
return
;
}
}
else
if
(
nr
==
0
)
if
(
n
==
0
)
{
{
hit_eof
(
dtp
)
;
dtp
->
u
.
p
.
current_unit
->
endfile
=
AT_ENDFILE
;
return
;
/* end of file */
return
;
/* end of file */
}
}
else
if
(
unlikely
(
n
!=
nr
))
if
(
unlikely
(
n
!=
nr
))
{
{
generate_error
(
&
dtp
->
common
,
LIBERROR_BAD_US
,
NULL
);
generate_error
(
&
dtp
->
common
,
LIBERROR_BAD_US
,
NULL
);
return
;
return
;
...
@@ -1718,7 +1750,7 @@ us_read (st_parameter_dt *dtp, int continued)
...
@@ -1718,7 +1750,7 @@ us_read (st_parameter_dt *dtp, int continued)
static
void
static
void
us_write
(
st_parameter_dt
*
dtp
,
int
continued
)
us_write
(
st_parameter_dt
*
dtp
,
int
continued
)
{
{
s
s
ize_t
nbytes
;
size_t
nbytes
;
gfc_offset
dummy
;
gfc_offset
dummy
;
dummy
=
0
;
dummy
=
0
;
...
@@ -1728,7 +1760,7 @@ us_write (st_parameter_dt *dtp, int continued)
...
@@ -1728,7 +1760,7 @@ us_write (st_parameter_dt *dtp, int continued)
else
else
nbytes
=
compile_options
.
record_marker
;
nbytes
=
compile_options
.
record_marker
;
if
(
swrite
(
dtp
->
u
.
p
.
current_unit
->
s
,
&
dummy
,
nbytes
)
!=
nbytes
)
if
(
swrite
(
dtp
->
u
.
p
.
current_unit
->
s
,
&
dummy
,
&
nbytes
)
!=
0
)
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
/* For sequential unformatted, if RECL= was not specified in the OPEN
/* For sequential unformatted, if RECL= was not specified in the OPEN
...
@@ -1930,7 +1962,7 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag)
...
@@ -1930,7 +1962,7 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag)
return
;
return
;
}
}
/* Check the record
or position
number. */
/* Check the record number. */
if
(
dtp
->
u
.
p
.
current_unit
->
flags
.
access
==
ACCESS_DIRECT
if
(
dtp
->
u
.
p
.
current_unit
->
flags
.
access
==
ACCESS_DIRECT
&&
(
cf
&
IOPARM_DT_HAS_REC
)
==
0
)
&&
(
cf
&
IOPARM_DT_HAS_REC
)
==
0
)
...
@@ -2079,71 +2111,65 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag)
...
@@ -2079,71 +2111,65 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag)
if
(
dtp
->
u
.
p
.
current_unit
->
pad_status
==
PAD_UNSPECIFIED
)
if
(
dtp
->
u
.
p
.
current_unit
->
pad_status
==
PAD_UNSPECIFIED
)
dtp
->
u
.
p
.
current_unit
->
pad_status
=
dtp
->
u
.
p
.
current_unit
->
flags
.
pad
;
dtp
->
u
.
p
.
current_unit
->
pad_status
=
dtp
->
u
.
p
.
current_unit
->
flags
.
pad
;
/* Check to see if we might be reading what we wrote before */
if
(
dtp
->
u
.
p
.
mode
!=
dtp
->
u
.
p
.
current_unit
->
mode
&&
!
is_internal_unit
(
dtp
))
{
int
pos
=
fbuf_reset
(
dtp
->
u
.
p
.
current_unit
);
if
(
pos
!=
0
)
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
pos
,
SEEK_CUR
);
sflush
(
dtp
->
u
.
p
.
current_unit
->
s
);
}
/* Check the POS= specifier: that it is in range and that it is used with a
/* Check the POS= specifier: that it is in range and that it is used with a
unit that has been connected for STREAM access. F2003 9.5.1.10. */
unit that has been connected for STREAM access. F2003 9.5.1.10. */
if
(((
cf
&
IOPARM_DT_HAS_POS
)
!=
0
))
if
(((
cf
&
IOPARM_DT_HAS_POS
)
!=
0
))
{
{
if
(
is_stream_io
(
dtp
))
if
(
is_stream_io
(
dtp
))
{
{
if
(
dtp
->
pos
<=
0
)
if
(
dtp
->
pos
<=
0
)
{
{
generate_error
(
&
dtp
->
common
,
LIBERROR_BAD_OPTION
,
generate_error
(
&
dtp
->
common
,
LIBERROR_BAD_OPTION
,
"POS=specifier must be positive"
);
"POS=specifier must be positive"
);
return
;
return
;
}
}
if
(
dtp
->
pos
>=
dtp
->
u
.
p
.
current_unit
->
maxrec
)
if
(
dtp
->
pos
>=
dtp
->
u
.
p
.
current_unit
->
maxrec
)
{
{
generate_error
(
&
dtp
->
common
,
LIBERROR_BAD_OPTION
,
generate_error
(
&
dtp
->
common
,
LIBERROR_BAD_OPTION
,
"POS=specifier too large"
);
"POS=specifier too large"
);
return
;
return
;
}
}
dtp
->
rec
=
dtp
->
pos
;
dtp
->
rec
=
dtp
->
pos
;
if
(
dtp
->
u
.
p
.
mode
==
READING
)
if
(
dtp
->
u
.
p
.
mode
==
READING
)
{
{
/* Reset the endfile flag; if we hit EOF during reading
/* Required for compatibility between 4.3 and 4.4 runtime. Check
we'll set the flag and generate an error at that point
to see if we might be reading what we wrote before */
rather than worrying about it here. */
if
(
dtp
->
u
.
p
.
current_unit
->
mode
==
WRITING
)
dtp
->
u
.
p
.
current_unit
->
endfile
=
NO_ENDFILE
;
{
}
fbuf_flush
(
dtp
->
u
.
p
.
current_unit
,
1
);
flush
(
dtp
->
u
.
p
.
current_unit
->
s
);
if
(
dtp
->
pos
!=
dtp
->
u
.
p
.
current_unit
->
strm_pos
)
}
{
fbuf_flush
(
dtp
->
u
.
p
.
current_unit
,
dtp
->
u
.
p
.
mode
);
if
(
dtp
->
pos
<
file_length
(
dtp
->
u
.
p
.
current_unit
->
s
))
sflush
(
dtp
->
u
.
p
.
current_unit
->
s
);
dtp
->
u
.
p
.
current_unit
->
endfile
=
NO_ENDFILE
;
if
(
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
dtp
->
pos
-
1
,
SEEK_SET
)
<
0
)
}
{
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
if
(
dtp
->
pos
!=
dtp
->
u
.
p
.
current_unit
->
strm_pos
)
return
;
{
}
fbuf_flush
(
dtp
->
u
.
p
.
current_unit
,
1
);
dtp
->
u
.
p
.
current_unit
->
strm_pos
=
dtp
->
pos
;
flush
(
dtp
->
u
.
p
.
current_unit
->
s
);
}
if
(
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
dtp
->
pos
-
1
)
==
FAILURE
)
}
{
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
return
;
}
dtp
->
u
.
p
.
current_unit
->
strm_pos
=
dtp
->
pos
;
}
}
else
else
{
{
generate_error
(
&
dtp
->
common
,
LIBERROR_BAD_OPTION
,
generate_error
(
&
dtp
->
common
,
LIBERROR_BAD_OPTION
,
"POS=specifier not allowed, "
"POS=specifier not allowed, "
"Try OPEN with ACCESS='stream'"
);
"Try OPEN with ACCESS='stream'"
);
return
;
return
;
}
}
}
}
/* Sanity checks on the record number. */
/* Sanity checks on the record number. */
if
((
cf
&
IOPARM_DT_HAS_REC
)
!=
0
)
if
((
cf
&
IOPARM_DT_HAS_REC
)
!=
0
)
...
@@ -2162,10 +2188,15 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag)
...
@@ -2162,10 +2188,15 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag)
return
;
return
;
}
}
/* Make sure format buffer is reset. */
/* Check to see if we might be reading what we wrote before */
if
(
dtp
->
u
.
p
.
current_unit
->
flags
.
form
==
FORM_FORMATTED
)
fbuf_reset
(
dtp
->
u
.
p
.
current_unit
);
if
(
dtp
->
u
.
p
.
mode
==
READING
&&
dtp
->
u
.
p
.
current_unit
->
mode
==
WRITING
&&
!
is_internal_unit
(
dtp
))
{
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. */
...
@@ -2180,28 +2211,37 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag)
...
@@ -2180,28 +2211,37 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag)
/* Position the file. */
/* Position the file. */
if
(
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
(
gfc_offset
)
(
dtp
->
rec
-
1
)
if
(
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
(
gfc_offset
)
(
dtp
->
rec
-
1
)
*
dtp
->
u
.
p
.
current_unit
->
recl
,
SEEK_SET
)
<
0
)
*
dtp
->
u
.
p
.
current_unit
->
recl
)
==
FAILURE
)
{
{
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
return
;
return
;
}
}
/* TODO: This is required to maintain compatibility between
/* TODO: This is required to maintain compatibility between
4.3 and 4.4 runtime. Remove when ABI changes from 4.3 */
4.3 and 4.4 runtime. Remove when ABI changes from 4.3 */
if
(
is_stream_io
(
dtp
))
if
(
is_stream_io
(
dtp
))
dtp
->
u
.
p
.
current_unit
->
strm_pos
=
dtp
->
rec
;
dtp
->
u
.
p
.
current_unit
->
strm_pos
=
dtp
->
rec
;
/* TODO: Un-comment this code when ABI changes from 4.3.
/* TODO: Un-comment this code when ABI changes from 4.3.
if (dtp->u.p.current_unit->flags.access == ACCESS_STREAM)
if (dtp->u.p.current_unit->flags.access == ACCESS_STREAM)
{
{
generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
generate_error (&dtp->common, LIBERROR_OPTION_CONFLICT,
"Record number not allowed for stream access "
"Record number not allowed for stream access "
"data transfer");
"data transfer");
return;
return;
} */
} */
}
}
/* Overwriting an existing sequential file ?
it is always safe to truncate the file on the first write */
if
(
dtp
->
u
.
p
.
mode
==
WRITING
&&
dtp
->
u
.
p
.
current_unit
->
flags
.
access
==
ACCESS_SEQUENTIAL
&&
dtp
->
u
.
p
.
current_unit
->
last_record
==
0
&&
!
is_preconnected
(
dtp
->
u
.
p
.
current_unit
->
s
))
struncate
(
dtp
->
u
.
p
.
current_unit
->
s
);
/* Bugware for badly written mixed C-Fortran I/O. */
/* Bugware for badly written mixed C-Fortran I/O. */
flush_if_preconnected
(
dtp
->
u
.
p
.
current_unit
->
s
);
flush_if_preconnected
(
dtp
->
u
.
p
.
current_unit
->
s
);
...
@@ -2354,8 +2394,8 @@ next_array_record (st_parameter_dt *dtp, array_loop_spec *ls, int *finished)
...
@@ -2354,8 +2394,8 @@ next_array_record (st_parameter_dt *dtp, array_loop_spec *ls, int *finished)
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
;
size_t
rlength
;
size_t
rlength
;
ssize_t
readb
;
static
const
size_t
MAX_READ
=
4096
;
static
const
size_t
MAX_READ
=
4096
;
char
p
[
MAX_READ
];
char
p
[
MAX_READ
];
...
@@ -2365,10 +2405,12 @@ skip_record (st_parameter_dt *dtp, size_t bytes)
...
@@ -2365,10 +2405,12 @@ skip_record (st_parameter_dt *dtp, size_t bytes)
if
(
is_seekable
(
dtp
->
u
.
p
.
current_unit
->
s
))
if
(
is_seekable
(
dtp
->
u
.
p
.
current_unit
->
s
))
{
{
new
=
file_position
(
dtp
->
u
.
p
.
current_unit
->
s
)
+
dtp
->
u
.
p
.
current_unit
->
bytes_left_subrecord
;
/* Direct access files do not generate END conditions,
/* Direct access files do not generate END conditions,
only I/O errors. */
only I/O errors. */
if
(
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
if
(
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
new
)
==
FAILURE
)
dtp
->
u
.
p
.
current_unit
->
bytes_left_subrecord
,
SEEK_CUR
)
<
0
)
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
}
}
else
else
...
@@ -2376,17 +2418,16 @@ skip_record (st_parameter_dt *dtp, size_t bytes)
...
@@ -2376,17 +2418,16 @@ skip_record (st_parameter_dt *dtp, size_t bytes)
while
(
dtp
->
u
.
p
.
current_unit
->
bytes_left_subrecord
>
0
)
while
(
dtp
->
u
.
p
.
current_unit
->
bytes_left_subrecord
>
0
)
{
{
rlength
=
rlength
=
(
MAX_READ
<
(
size_t
)
dtp
->
u
.
p
.
current_unit
->
bytes_left_subrecord
)
?
(
MAX_READ
>
(
size_t
)
dtp
->
u
.
p
.
current_unit
->
bytes_left_subrecord
)
?
MAX_READ
:
(
size_t
)
dtp
->
u
.
p
.
current_unit
->
bytes_left_subrecord
;
MAX_READ
:
(
size_t
)
dtp
->
u
.
p
.
current_unit
->
bytes_left_subrecord
;
readb
=
sread
(
dtp
->
u
.
p
.
current_unit
->
s
,
p
,
rlength
);
if
(
sread
(
dtp
->
u
.
p
.
current_unit
->
s
,
p
,
&
rlength
)
!=
0
)
if
(
readb
<
0
)
{
{
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
return
;
return
;
}
}
dtp
->
u
.
p
.
current_unit
->
bytes_left_subrecord
-=
r
eadb
;
dtp
->
u
.
p
.
current_unit
->
bytes_left_subrecord
-=
r
length
;
}
}
}
}
...
@@ -2434,8 +2475,8 @@ next_record_r (st_parameter_dt *dtp)
...
@@ -2434,8 +2475,8 @@ next_record_r (st_parameter_dt *dtp)
{
{
gfc_offset
record
;
gfc_offset
record
;
int
bytes_left
;
int
bytes_left
;
size_t
length
;
char
p
;
char
p
;
int
cc
;
switch
(
current_mode
(
dtp
))
switch
(
current_mode
(
dtp
))
{
{
...
@@ -2455,12 +2496,11 @@ next_record_r (st_parameter_dt *dtp)
...
@@ -2455,12 +2496,11 @@ next_record_r (st_parameter_dt *dtp)
case
FORMATTED_STREAM
:
case
FORMATTED_STREAM
:
case
FORMATTED_SEQUENTIAL
:
case
FORMATTED_SEQUENTIAL
:
/* read_sf has already terminated input because of an '\n', or
length
=
1
;
we have hit EOF.
*/
/* sf_read has already terminated input because of an '\n'
*/
if
(
dtp
->
u
.
p
.
sf_seen_eor
||
dtp
->
u
.
p
.
at_eof
)
if
(
dtp
->
u
.
p
.
sf_seen_eor
)
{
{
dtp
->
u
.
p
.
sf_seen_eor
=
0
;
dtp
->
u
.
p
.
sf_seen_eor
=
0
;
dtp
->
u
.
p
.
at_eof
=
0
;
break
;
break
;
}
}
...
@@ -2475,7 +2515,7 @@ next_record_r (st_parameter_dt *dtp)
...
@@ -2475,7 +2515,7 @@ next_record_r (st_parameter_dt *dtp)
/* Now seek to this record. */
/* Now seek to this record. */
record
=
record
*
dtp
->
u
.
p
.
current_unit
->
recl
;
record
=
record
*
dtp
->
u
.
p
.
current_unit
->
recl
;
if
(
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
record
,
SEEK_SET
)
<
0
)
if
(
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
record
)
==
FAILURE
)
{
{
generate_error
(
&
dtp
->
common
,
LIBERROR_INTERNAL_UNIT
,
NULL
);
generate_error
(
&
dtp
->
common
,
LIBERROR_INTERNAL_UNIT
,
NULL
);
break
;
break
;
...
@@ -2487,9 +2527,10 @@ next_record_r (st_parameter_dt *dtp)
...
@@ -2487,9 +2527,10 @@ next_record_r (st_parameter_dt *dtp)
bytes_left
=
(
int
)
dtp
->
u
.
p
.
current_unit
->
bytes_left
;
bytes_left
=
(
int
)
dtp
->
u
.
p
.
current_unit
->
bytes_left
;
bytes_left
=
min_off
(
bytes_left
,
bytes_left
=
min_off
(
bytes_left
,
file_length
(
dtp
->
u
.
p
.
current_unit
->
s
)
file_length
(
dtp
->
u
.
p
.
current_unit
->
s
)
-
stell
(
dtp
->
u
.
p
.
current_unit
->
s
));
-
file_position
(
dtp
->
u
.
p
.
current_unit
->
s
));
if
(
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
if
(
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
bytes_left
,
SEEK_CUR
)
<
0
)
file_position
(
dtp
->
u
.
p
.
current_unit
->
s
)
+
bytes_left
)
==
FAILURE
)
{
{
generate_error
(
&
dtp
->
common
,
LIBERROR_INTERNAL_UNIT
,
NULL
);
generate_error
(
&
dtp
->
common
,
LIBERROR_INTERNAL_UNIT
,
NULL
);
break
;
break
;
...
@@ -2499,37 +2540,42 @@ next_record_r (st_parameter_dt *dtp)
...
@@ -2499,37 +2540,42 @@ next_record_r (st_parameter_dt *dtp)
}
}
break
;
break
;
}
}
else
else
do
{
{
do
if
(
sread
(
dtp
->
u
.
p
.
current_unit
->
s
,
&
p
,
&
length
)
!=
0
)
{
{
errno
=
0
;
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
cc
=
fbuf_getc
(
dtp
->
u
.
p
.
current_unit
);
break
;
if
(
cc
==
EOF
)
{
if
(
errno
!=
0
)
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
else
hit_eof
(
dtp
);
break
;
}
if
(
is_stream_io
(
dtp
))
dtp
->
u
.
p
.
current_unit
->
strm_pos
++
;
p
=
(
char
)
cc
;
}
}
while
(
p
!=
'\n'
);
if
(
length
==
0
)
{
dtp
->
u
.
p
.
current_unit
->
endfile
=
AT_ENDFILE
;
break
;
}
if
(
is_stream_io
(
dtp
))
dtp
->
u
.
p
.
current_unit
->
strm_pos
++
;
}
}
while
(
p
!=
'\n'
);
break
;
break
;
}
}
if
(
dtp
->
u
.
p
.
current_unit
->
flags
.
access
==
ACCESS_SEQUENTIAL
&&
!
dtp
->
u
.
p
.
namelist_mode
&&
dtp
->
u
.
p
.
current_unit
->
endfile
==
NO_ENDFILE
&&
(
file_length
(
dtp
->
u
.
p
.
current_unit
->
s
)
==
file_position
(
dtp
->
u
.
p
.
current_unit
->
s
)))
dtp
->
u
.
p
.
current_unit
->
endfile
=
AT_ENDFILE
;
}
}
/* Small utility function to write a record marker, taking care of
/* Small utility function to write a record marker, taking care of
byte swapping and of choosing the correct size. */
byte swapping and of choosing the correct size. */
static
int
inline
static
int
write_us_marker
(
st_parameter_dt
*
dtp
,
const
gfc_offset
buf
)
write_us_marker
(
st_parameter_dt
*
dtp
,
const
gfc_offset
buf
)
{
{
size_t
len
;
size_t
len
;
...
@@ -2549,12 +2595,12 @@ write_us_marker (st_parameter_dt *dtp, const gfc_offset buf)
...
@@ -2549,12 +2595,12 @@ write_us_marker (st_parameter_dt *dtp, const gfc_offset buf)
{
{
case
sizeof
(
GFC_INTEGER_4
):
case
sizeof
(
GFC_INTEGER_4
):
buf4
=
buf
;
buf4
=
buf
;
return
swrite
(
dtp
->
u
.
p
.
current_unit
->
s
,
&
buf4
,
len
);
return
swrite
(
dtp
->
u
.
p
.
current_unit
->
s
,
&
buf4
,
&
len
);
break
;
break
;
case
sizeof
(
GFC_INTEGER_8
):
case
sizeof
(
GFC_INTEGER_8
):
buf8
=
buf
;
buf8
=
buf
;
return
swrite
(
dtp
->
u
.
p
.
current_unit
->
s
,
&
buf8
,
len
);
return
swrite
(
dtp
->
u
.
p
.
current_unit
->
s
,
&
buf8
,
&
len
);
break
;
break
;
default:
default:
...
@@ -2569,13 +2615,13 @@ write_us_marker (st_parameter_dt *dtp, const gfc_offset buf)
...
@@ -2569,13 +2615,13 @@ write_us_marker (st_parameter_dt *dtp, const gfc_offset buf)
case
sizeof
(
GFC_INTEGER_4
):
case
sizeof
(
GFC_INTEGER_4
):
buf4
=
buf
;
buf4
=
buf
;
reverse_memcpy
(
p
,
&
buf4
,
sizeof
(
GFC_INTEGER_4
));
reverse_memcpy
(
p
,
&
buf4
,
sizeof
(
GFC_INTEGER_4
));
return
swrite
(
dtp
->
u
.
p
.
current_unit
->
s
,
p
,
len
);
return
swrite
(
dtp
->
u
.
p
.
current_unit
->
s
,
p
,
&
len
);
break
;
break
;
case
sizeof
(
GFC_INTEGER_8
):
case
sizeof
(
GFC_INTEGER_8
):
buf8
=
buf
;
buf8
=
buf
;
reverse_memcpy
(
p
,
&
buf8
,
sizeof
(
GFC_INTEGER_8
));
reverse_memcpy
(
p
,
&
buf8
,
sizeof
(
GFC_INTEGER_8
));
return
swrite
(
dtp
->
u
.
p
.
current_unit
->
s
,
p
,
len
);
return
swrite
(
dtp
->
u
.
p
.
current_unit
->
s
,
p
,
&
len
);
break
;
break
;
default:
default:
...
@@ -2598,7 +2644,7 @@ next_record_w_unf (st_parameter_dt *dtp, int next_subrecord)
...
@@ -2598,7 +2644,7 @@ next_record_w_unf (st_parameter_dt *dtp, int next_subrecord)
/* Bytes written. */
/* Bytes written. */
m
=
dtp
->
u
.
p
.
current_unit
->
recl_subrecord
m
=
dtp
->
u
.
p
.
current_unit
->
recl_subrecord
-
dtp
->
u
.
p
.
current_unit
->
bytes_left_subrecord
;
-
dtp
->
u
.
p
.
current_unit
->
bytes_left_subrecord
;
c
=
stell
(
dtp
->
u
.
p
.
current_unit
->
s
);
c
=
file_position
(
dtp
->
u
.
p
.
current_unit
->
s
);
/* Write the length tail. If we finish a record containing
/* Write the length tail. If we finish a record containing
subrecords, we write out the negative length. */
subrecords, we write out the negative length. */
...
@@ -2608,7 +2654,7 @@ next_record_w_unf (st_parameter_dt *dtp, int next_subrecord)
...
@@ -2608,7 +2654,7 @@ next_record_w_unf (st_parameter_dt *dtp, int next_subrecord)
else
else
m_write
=
m
;
m_write
=
m
;
if
(
unlikely
(
write_us_marker
(
dtp
,
m_write
)
<
0
))
if
(
unlikely
(
write_us_marker
(
dtp
,
m_write
)
!=
0
))
goto
io_error
;
goto
io_error
;
if
(
compile_options
.
record_marker
==
0
)
if
(
compile_options
.
record_marker
==
0
)
...
@@ -2619,8 +2665,8 @@ next_record_w_unf (st_parameter_dt *dtp, int next_subrecord)
...
@@ -2619,8 +2665,8 @@ next_record_w_unf (st_parameter_dt *dtp, int next_subrecord)
/* Seek to the head and overwrite the bogus length with the real
/* Seek to the head and overwrite the bogus length with the real
length. */
length. */
if
(
unlikely
(
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
c
-
m
-
record_marker
,
if
(
unlikely
(
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
c
-
m
-
record_marker
)
SEEK_SET
)
<
0
))
==
FAILURE
))
goto
io_error
;
goto
io_error
;
if
(
next_subrecord
)
if
(
next_subrecord
)
...
@@ -2628,13 +2674,13 @@ next_record_w_unf (st_parameter_dt *dtp, int next_subrecord)
...
@@ -2628,13 +2674,13 @@ next_record_w_unf (st_parameter_dt *dtp, int next_subrecord)
else
else
m_write
=
m
;
m_write
=
m
;
if
(
unlikely
(
write_us_marker
(
dtp
,
m_write
)
<
0
))
if
(
unlikely
(
write_us_marker
(
dtp
,
m_write
)
!=
0
))
goto
io_error
;
goto
io_error
;
/* Seek past the end of the current record. */
/* Seek past the end of the current record. */
if
(
unlikely
(
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
c
+
record_marker
,
if
(
unlikely
(
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
c
+
record_marker
)
SEEK_SET
)
<
0
))
==
FAILURE
))
goto
io_error
;
goto
io_error
;
return
;
return
;
...
@@ -2645,35 +2691,6 @@ next_record_w_unf (st_parameter_dt *dtp, int next_subrecord)
...
@@ -2645,35 +2691,6 @@ next_record_w_unf (st_parameter_dt *dtp, int next_subrecord)
}
}
/* Utility function like memset() but operating on streams. Return
value is same as for POSIX write(). */
static
ssize_t
sset
(
stream
*
s
,
int
c
,
ssize_t
nbyte
)
{
static
const
int
WRITE_CHUNK
=
256
;
char
p
[
WRITE_CHUNK
];
ssize_t
bytes_left
,
trans
;
if
(
nbyte
<
WRITE_CHUNK
)
memset
(
p
,
c
,
nbyte
);
else
memset
(
p
,
c
,
WRITE_CHUNK
);
bytes_left
=
nbyte
;
while
(
bytes_left
>
0
)
{
trans
=
(
bytes_left
<
WRITE_CHUNK
)
?
bytes_left
:
WRITE_CHUNK
;
trans
=
swrite
(
s
,
p
,
trans
);
if
(
trans
<
0
)
return
trans
;
bytes_left
-=
trans
;
}
return
nbyte
-
bytes_left
;
}
/* Position to the next record in write mode. */
/* Position to the next record in write mode. */
static
void
static
void
...
@@ -2682,6 +2699,9 @@ next_record_w (st_parameter_dt *dtp, int done)
...
@@ -2682,6 +2699,9 @@ 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
;
/* 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
;
...
@@ -2696,11 +2716,8 @@ next_record_w (st_parameter_dt *dtp, int done)
...
@@ -2696,11 +2716,8 @@ 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
)
break
;
break
;
fbuf_seek
(
dtp
->
u
.
p
.
current_unit
,
0
,
SEEK_END
);
fbuf_flush
(
dtp
->
u
.
p
.
current_unit
,
WRITING
);
if
(
sset
(
dtp
->
u
.
p
.
current_unit
->
s
,
' '
,
if
(
sset
(
dtp
->
u
.
p
.
current_unit
->
s
,
' '
,
dtp
->
u
.
p
.
current_unit
->
bytes_left
)
dtp
->
u
.
p
.
current_unit
->
bytes_left
)
==
FAILURE
)
!=
dtp
->
u
.
p
.
current_unit
->
bytes_left
)
goto
io_error
;
goto
io_error
;
break
;
break
;
...
@@ -2709,7 +2726,7 @@ next_record_w (st_parameter_dt *dtp, int done)
...
@@ -2709,7 +2726,7 @@ 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
;
if
(
sset
(
dtp
->
u
.
p
.
current_unit
->
s
,
0
,
length
)
!=
length
)
if
(
sset
(
dtp
->
u
.
p
.
current_unit
->
s
,
0
,
length
)
==
FAILURE
)
goto
io_error
;
goto
io_error
;
}
}
break
;
break
;
...
@@ -2740,7 +2757,8 @@ next_record_w (st_parameter_dt *dtp, int done)
...
@@ -2740,7 +2757,8 @@ next_record_w (st_parameter_dt *dtp, int done)
{
{
length
=
(
int
)
(
max_pos
-
m
);
length
=
(
int
)
(
max_pos
-
m
);
if
(
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
if
(
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
length
,
SEEK_CUR
)
<
0
)
file_position
(
dtp
->
u
.
p
.
current_unit
->
s
)
+
length
)
==
FAILURE
)
{
{
generate_error
(
&
dtp
->
common
,
LIBERROR_INTERNAL_UNIT
,
NULL
);
generate_error
(
&
dtp
->
common
,
LIBERROR_INTERNAL_UNIT
,
NULL
);
return
;
return
;
...
@@ -2748,7 +2766,7 @@ next_record_w (st_parameter_dt *dtp, int done)
...
@@ -2748,7 +2766,7 @@ next_record_w (st_parameter_dt *dtp, int done)
length
=
(
int
)
(
dtp
->
u
.
p
.
current_unit
->
recl
-
max_pos
);
length
=
(
int
)
(
dtp
->
u
.
p
.
current_unit
->
recl
-
max_pos
);
}
}
if
(
sset
(
dtp
->
u
.
p
.
current_unit
->
s
,
' '
,
length
)
!=
length
)
if
(
sset
(
dtp
->
u
.
p
.
current_unit
->
s
,
' '
,
length
)
==
FAILURE
)
{
{
generate_error
(
&
dtp
->
common
,
LIBERROR_END
,
NULL
);
generate_error
(
&
dtp
->
common
,
LIBERROR_END
,
NULL
);
return
;
return
;
...
@@ -2764,7 +2782,7 @@ next_record_w (st_parameter_dt *dtp, int done)
...
@@ -2764,7 +2782,7 @@ next_record_w (st_parameter_dt *dtp, int done)
/* Now seek to this record */
/* Now seek to this record */
record
=
record
*
dtp
->
u
.
p
.
current_unit
->
recl
;
record
=
record
*
dtp
->
u
.
p
.
current_unit
->
recl
;
if
(
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
record
,
SEEK_SET
)
<
0
)
if
(
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
record
)
==
FAILURE
)
{
{
generate_error
(
&
dtp
->
common
,
LIBERROR_INTERNAL_UNIT
,
NULL
);
generate_error
(
&
dtp
->
common
,
LIBERROR_INTERNAL_UNIT
,
NULL
);
return
;
return
;
...
@@ -2787,7 +2805,8 @@ next_record_w (st_parameter_dt *dtp, int done)
...
@@ -2787,7 +2805,8 @@ next_record_w (st_parameter_dt *dtp, int done)
{
{
length
=
(
int
)
(
max_pos
-
m
);
length
=
(
int
)
(
max_pos
-
m
);
if
(
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
if
(
sseek
(
dtp
->
u
.
p
.
current_unit
->
s
,
length
,
SEEK_CUR
)
<
0
)
file_position
(
dtp
->
u
.
p
.
current_unit
->
s
)
+
length
)
==
FAILURE
)
{
{
generate_error
(
&
dtp
->
common
,
LIBERROR_INTERNAL_UNIT
,
NULL
);
generate_error
(
&
dtp
->
common
,
LIBERROR_INTERNAL_UNIT
,
NULL
);
return
;
return
;
...
@@ -2798,7 +2817,7 @@ next_record_w (st_parameter_dt *dtp, int done)
...
@@ -2798,7 +2817,7 @@ next_record_w (st_parameter_dt *dtp, int done)
length
=
(
int
)
dtp
->
u
.
p
.
current_unit
->
bytes_left
;
length
=
(
int
)
dtp
->
u
.
p
.
current_unit
->
bytes_left
;
}
}
if
(
sset
(
dtp
->
u
.
p
.
current_unit
->
s
,
' '
,
length
)
!=
length
)
if
(
sset
(
dtp
->
u
.
p
.
current_unit
->
s
,
' '
,
length
)
==
FAILURE
)
{
{
generate_error
(
&
dtp
->
common
,
LIBERROR_END
,
NULL
);
generate_error
(
&
dtp
->
common
,
LIBERROR_END
,
NULL
);
return
;
return
;
...
@@ -2807,27 +2826,23 @@ next_record_w (st_parameter_dt *dtp, int done)
...
@@ -2807,27 +2826,23 @@ next_record_w (st_parameter_dt *dtp, int done)
}
}
else
else
{
{
size_t
len
;
const
char
crlf
[]
=
"
\r\n
"
;
#ifdef HAVE_CRLF
#ifdef HAVE_CRLF
const
int
len
=
2
;
len
=
2
;
#else
#else
const
int
len
=
1
;
len
=
1
;
#endif
fbuf_seek
(
dtp
->
u
.
p
.
current_unit
,
0
,
SEEK_END
);
char
*
p
=
fbuf_alloc
(
dtp
->
u
.
p
.
current_unit
,
len
);
if
(
!
p
)
goto
io_error
;
#ifdef HAVE_CRLF
*
(
p
++
)
=
'\r'
;
#endif
#endif
*
p
=
'\n'
;
if
(
swrite
(
dtp
->
u
.
p
.
current_unit
->
s
,
&
crlf
[
2
-
len
],
&
len
)
!=
0
)
goto
io_error
;
if
(
is_stream_io
(
dtp
))
if
(
is_stream_io
(
dtp
))
{
{
dtp
->
u
.
p
.
current_unit
->
strm_pos
+=
len
;
dtp
->
u
.
p
.
current_unit
->
strm_pos
+=
len
;
if
(
dtp
->
u
.
p
.
current_unit
->
strm_pos
if
(
dtp
->
u
.
p
.
current_unit
->
strm_pos
<
file_length
(
dtp
->
u
.
p
.
current_unit
->
s
))
<
file_length
(
dtp
->
u
.
p
.
current_unit
->
s
))
unit_truncate
(
dtp
->
u
.
p
.
current_unit
,
struncate
(
dtp
->
u
.
p
.
current_unit
->
s
);
dtp
->
u
.
p
.
current_unit
->
strm_pos
-
1
,
&
dtp
->
common
);
}
}
}
}
...
@@ -2865,7 +2880,7 @@ next_record (st_parameter_dt *dtp, int done)
...
@@ -2865,7 +2880,7 @@ next_record (st_parameter_dt *dtp, int done)
dtp
->
u
.
p
.
current_unit
->
current_record
=
0
;
dtp
->
u
.
p
.
current_unit
->
current_record
=
0
;
if
(
dtp
->
u
.
p
.
current_unit
->
flags
.
access
==
ACCESS_DIRECT
)
if
(
dtp
->
u
.
p
.
current_unit
->
flags
.
access
==
ACCESS_DIRECT
)
{
{
fp
=
stell
(
dtp
->
u
.
p
.
current_unit
->
s
);
fp
=
file_position
(
dtp
->
u
.
p
.
current_unit
->
s
);
/* Calculate next record, rounding up partial records. */
/* Calculate next record, rounding up partial records. */
dtp
->
u
.
p
.
current_unit
->
last_record
=
dtp
->
u
.
p
.
current_unit
->
last_record
=
(
fp
+
dtp
->
u
.
p
.
current_unit
->
recl
-
1
)
/
(
fp
+
dtp
->
u
.
p
.
current_unit
->
recl
-
1
)
/
...
@@ -2877,8 +2892,6 @@ next_record (st_parameter_dt *dtp, int done)
...
@@ -2877,8 +2892,6 @@ next_record (st_parameter_dt *dtp, int done)
if
(
!
done
)
if
(
!
done
)
pre_position
(
dtp
);
pre_position
(
dtp
);
fbuf_flush
(
dtp
->
u
.
p
.
current_unit
,
dtp
->
u
.
p
.
mode
);
}
}
...
@@ -2927,6 +2940,7 @@ finalize_transfer (st_parameter_dt *dtp)
...
@@ -2927,6 +2940,7 @@ finalize_transfer (st_parameter_dt *dtp)
if
((
cf
&
IOPARM_DT_LIST_FORMAT
)
!=
0
&&
dtp
->
u
.
p
.
mode
==
READING
)
if
((
cf
&
IOPARM_DT_LIST_FORMAT
)
!=
0
&&
dtp
->
u
.
p
.
mode
==
READING
)
{
{
finish_list_read
(
dtp
);
finish_list_read
(
dtp
);
sfree
(
dtp
->
u
.
p
.
current_unit
->
s
);
return
;
return
;
}
}
...
@@ -2941,9 +2955,10 @@ finalize_transfer (st_parameter_dt *dtp)
...
@@ -2941,9 +2955,10 @@ finalize_transfer (st_parameter_dt *dtp)
next_record
(
dtp
,
1
);
next_record
(
dtp
,
1
);
if
(
dtp
->
u
.
p
.
current_unit
->
flags
.
form
==
FORM_UNFORMATTED
if
(
dtp
->
u
.
p
.
current_unit
->
flags
.
form
==
FORM_UNFORMATTED
&&
stell
(
dtp
->
u
.
p
.
current_unit
->
s
)
>=
dtp
->
rec
)
&&
file_position
(
dtp
->
u
.
p
.
current_unit
->
s
)
>=
dtp
->
rec
)
{
{
sflush
(
dtp
->
u
.
p
.
current_unit
->
s
);
flush
(
dtp
->
u
.
p
.
current_unit
->
s
);
sfree
(
dtp
->
u
.
p
.
current_unit
->
s
);
}
}
return
;
return
;
}
}
...
@@ -2952,8 +2967,9 @@ finalize_transfer (st_parameter_dt *dtp)
...
@@ -2952,8 +2967,9 @@ 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
)
{
{
fbuf_flush
(
dtp
->
u
.
p
.
current_unit
,
dtp
->
u
.
p
.
mode
);
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
);
return
;
return
;
}
}
...
@@ -2965,17 +2981,15 @@ finalize_transfer (st_parameter_dt *dtp)
...
@@ -2965,17 +2981,15 @@ 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
,
dtp
->
u
.
p
.
mode
);
fbuf_flush
(
dtp
->
u
.
p
.
current_unit
,
0
);
s
flush
(
dtp
->
u
.
p
.
current_unit
->
s
);
flush
(
dtp
->
u
.
p
.
current_unit
->
s
);
return
;
return
;
}
}
else
if
(
dtp
->
u
.
p
.
current_unit
->
flags
.
form
==
FORM_FORMATTED
&&
dtp
->
u
.
p
.
mode
==
WRITING
&&
!
is_internal_unit
(
dtp
))
fbuf_seek
(
dtp
->
u
.
p
.
current_unit
,
0
,
SEEK_END
);
dtp
->
u
.
p
.
current_unit
->
saved_pos
=
0
;
dtp
->
u
.
p
.
current_unit
->
saved_pos
=
0
;
next_record
(
dtp
,
1
);
next_record
(
dtp
,
1
);
sfree
(
dtp
->
u
.
p
.
current_unit
->
s
);
}
}
/* Transfer function for IOLENGTH. It doesn't actually do any
/* Transfer function for IOLENGTH. It doesn't actually do any
...
@@ -3032,6 +3046,8 @@ void
...
@@ -3032,6 +3046,8 @@ void
st_iolength_done
(
st_parameter_dt
*
dtp
__attribute__
((
unused
)))
st_iolength_done
(
st_parameter_dt
*
dtp
__attribute__
((
unused
)))
{
{
free_ionml
(
dtp
);
free_ionml
(
dtp
);
if
(
dtp
->
u
.
p
.
scratch
!=
NULL
)
free_mem
(
dtp
->
u
.
p
.
scratch
);
library_end
();
library_end
();
}
}
...
@@ -3047,6 +3063,29 @@ st_read (st_parameter_dt *dtp)
...
@@ -3047,6 +3063,29 @@ st_read (st_parameter_dt *dtp)
library_start
(
&
dtp
->
common
);
library_start
(
&
dtp
->
common
);
data_transfer_init
(
dtp
,
1
);
data_transfer_init
(
dtp
,
1
);
/* Handle complications dealing with the endfile record. */
if
(
dtp
->
u
.
p
.
current_unit
->
flags
.
access
==
ACCESS_SEQUENTIAL
)
switch
(
dtp
->
u
.
p
.
current_unit
->
endfile
)
{
case
NO_ENDFILE
:
break
;
case
AT_ENDFILE
:
if
(
!
is_internal_unit
(
dtp
))
{
generate_error
(
&
dtp
->
common
,
LIBERROR_END
,
NULL
);
dtp
->
u
.
p
.
current_unit
->
endfile
=
AFTER_ENDFILE
;
dtp
->
u
.
p
.
current_unit
->
current_record
=
0
;
}
break
;
case
AFTER_ENDFILE
:
generate_error
(
&
dtp
->
common
,
LIBERROR_ENDFILE
,
NULL
);
dtp
->
u
.
p
.
current_unit
->
current_record
=
0
;
break
;
}
}
}
extern
void
st_read_done
(
st_parameter_dt
*
);
extern
void
st_read_done
(
st_parameter_dt
*
);
...
@@ -3058,6 +3097,8 @@ st_read_done (st_parameter_dt *dtp)
...
@@ -3058,6 +3097,8 @@ st_read_done (st_parameter_dt *dtp)
finalize_transfer
(
dtp
);
finalize_transfer
(
dtp
);
free_format_data
(
dtp
);
free_format_data
(
dtp
);
free_ionml
(
dtp
);
free_ionml
(
dtp
);
if
(
dtp
->
u
.
p
.
scratch
!=
NULL
)
free_mem
(
dtp
->
u
.
p
.
scratch
);
if
(
dtp
->
u
.
p
.
current_unit
!=
NULL
)
if
(
dtp
->
u
.
p
.
current_unit
!=
NULL
)
unlock_unit
(
dtp
->
u
.
p
.
current_unit
);
unlock_unit
(
dtp
->
u
.
p
.
current_unit
);
...
@@ -3100,15 +3141,19 @@ st_write_done (st_parameter_dt *dtp)
...
@@ -3100,15 +3141,19 @@ st_write_done (st_parameter_dt *dtp)
case
NO_ENDFILE
:
case
NO_ENDFILE
:
/* Get rid of whatever is after this record. */
/* Get rid of whatever is after this record. */
if
(
!
is_internal_unit
(
dtp
))
if
(
!
is_internal_unit
(
dtp
))
unit_truncate
(
dtp
->
u
.
p
.
current_unit
,
{
stell
(
dtp
->
u
.
p
.
current_unit
->
s
),
flush
(
dtp
->
u
.
p
.
current_unit
->
s
);
&
dtp
->
common
);
if
(
struncate
(
dtp
->
u
.
p
.
current_unit
->
s
)
==
FAILURE
)
generate_error
(
&
dtp
->
common
,
LIBERROR_OS
,
NULL
);
}
dtp
->
u
.
p
.
current_unit
->
endfile
=
AT_ENDFILE
;
dtp
->
u
.
p
.
current_unit
->
endfile
=
AT_ENDFILE
;
break
;
break
;
}
}
free_format_data
(
dtp
);
free_format_data
(
dtp
);
free_ionml
(
dtp
);
free_ionml
(
dtp
);
if
(
dtp
->
u
.
p
.
scratch
!=
NULL
)
free_mem
(
dtp
->
u
.
p
.
scratch
);
if
(
dtp
->
u
.
p
.
current_unit
!=
NULL
)
if
(
dtp
->
u
.
p
.
current_unit
!=
NULL
)
unlock_unit
(
dtp
->
u
.
p
.
current_unit
);
unlock_unit
(
dtp
->
u
.
p
.
current_unit
);
...
@@ -3222,46 +3267,3 @@ void reverse_memcpy (void *dest, const void *src, size_t n)
...
@@ -3222,46 +3267,3 @@ void reverse_memcpy (void *dest, const void *src, size_t n)
for
(
i
=
0
;
i
<
n
;
i
++
)
for
(
i
=
0
;
i
<
n
;
i
++
)
*
(
d
++
)
=
*
(
s
--
);
*
(
d
++
)
=
*
(
s
--
);
}
}
/* Once upon a time, a poor innocent Fortran program was reading a
file, when suddenly it hit the end-of-file (EOF). Unfortunately
the OS doesn't tell whether we're at the EOF or whether we already
went past it. Luckily our hero, libgfortran, keeps track of this.
Call this function when you detect an EOF condition. See Section
9.10.2 in F2003. */
void
hit_eof
(
st_parameter_dt
*
dtp
)
{
dtp
->
u
.
p
.
current_unit
->
flags
.
position
=
POSITION_APPEND
;
if
(
dtp
->
u
.
p
.
current_unit
->
flags
.
access
==
ACCESS_SEQUENTIAL
)
switch
(
dtp
->
u
.
p
.
current_unit
->
endfile
)
{
case
NO_ENDFILE
:
case
AT_ENDFILE
:
generate_error
(
&
dtp
->
common
,
LIBERROR_END
,
NULL
);
if
(
!
is_internal_unit
(
dtp
))
{
dtp
->
u
.
p
.
current_unit
->
endfile
=
AFTER_ENDFILE
;
dtp
->
u
.
p
.
current_unit
->
current_record
=
0
;
}
else
dtp
->
u
.
p
.
current_unit
->
endfile
=
AT_ENDFILE
;
break
;
case
AFTER_ENDFILE
:
generate_error
(
&
dtp
->
common
,
LIBERROR_ENDFILE
,
NULL
);
dtp
->
u
.
p
.
current_unit
->
current_record
=
0
;
break
;
}
else
{
/* Non-sequential files don't have an ENDFILE record, so we
can't be at AFTER_ENDFILE. */
dtp
->
u
.
p
.
current_unit
->
endfile
=
AT_ENDFILE
;
generate_error
(
&
dtp
->
common
,
LIBERROR_END
,
NULL
);
dtp
->
u
.
p
.
current_unit
->
current_record
=
0
;
}
}
libgfortran/io/unit.c
View file @
f3ed1d02
...
@@ -540,8 +540,6 @@ init_units (void)
...
@@ -540,8 +540,6 @@ init_units (void)
u
->
file_len
=
strlen
(
stdin_name
);
u
->
file_len
=
strlen
(
stdin_name
);
u
->
file
=
get_mem
(
u
->
file_len
);
u
->
file
=
get_mem
(
u
->
file_len
);
memmove
(
u
->
file
,
stdin_name
,
u
->
file_len
);
memmove
(
u
->
file
,
stdin_name
,
u
->
file_len
);
fbuf_init
(
u
,
0
);
__gthread_mutex_unlock
(
&
u
->
lock
);
__gthread_mutex_unlock
(
&
u
->
lock
);
}
}
...
@@ -699,62 +697,15 @@ close_units (void)
...
@@ -699,62 +697,15 @@ close_units (void)
void
void
update_position
(
gfc_unit
*
u
)
update_position
(
gfc_unit
*
u
)
{
{
if
(
stell
(
u
->
s
)
==
0
)
if
(
file_position
(
u
->
s
)
==
0
)
u
->
flags
.
position
=
POSITION_REWIND
;
u
->
flags
.
position
=
POSITION_REWIND
;
else
if
(
file_length
(
u
->
s
)
==
stell
(
u
->
s
))
else
if
(
file_length
(
u
->
s
)
==
file_position
(
u
->
s
))
u
->
flags
.
position
=
POSITION_APPEND
;
u
->
flags
.
position
=
POSITION_APPEND
;
else
else
u
->
flags
.
position
=
POSITION_ASIS
;
u
->
flags
.
position
=
POSITION_ASIS
;
}
}
/* High level interface to truncate a file safely, i.e. flush format
buffers, check that it's a regular file, and generate error if that
occurs. Just like POSIX ftruncate, returns 0 on success, -1 on
failure. */
int
unit_truncate
(
gfc_unit
*
u
,
gfc_offset
pos
,
st_parameter_common
*
common
)
{
int
ret
;
/* Make sure format buffer is flushed. */
if
(
u
->
flags
.
form
==
FORM_FORMATTED
)
{
if
(
u
->
mode
==
READING
)
pos
+=
fbuf_reset
(
u
);
else
fbuf_flush
(
u
,
u
->
mode
);
}
/* Don't try to truncate a special file, just pretend that it
succeeds. */
if
(
is_special
(
u
->
s
)
||
!
is_seekable
(
u
->
s
))
{
sflush
(
u
->
s
);
return
0
;
}
/* struncate() should flush the stream buffer if necessary, so don't
bother calling sflush() here. */
ret
=
struncate
(
u
->
s
,
pos
);
if
(
ret
!=
0
)
{
generate_error
(
common
,
LIBERROR_OS
,
NULL
);
u
->
endfile
=
NO_ENDFILE
;
u
->
flags
.
position
=
POSITION_ASIS
;
}
else
{
u
->
endfile
=
AT_ENDFILE
;
u
->
flags
.
position
=
POSITION_APPEND
;
}
return
ret
;
}
/* filename_from_unit()-- If the unit_number exists, return a pointer to the
/* filename_from_unit()-- If the unit_number exists, return a pointer to the
name of the associated file, otherwise return the empty string. The caller
name of the associated file, otherwise return the empty string. The caller
must free memory allocated for the filename string. */
must free memory allocated for the filename string. */
...
@@ -795,25 +746,23 @@ finish_last_advance_record (gfc_unit *u)
...
@@ -795,25 +746,23 @@ finish_last_advance_record (gfc_unit *u)
{
{
if
(
u
->
saved_pos
>
0
)
if
(
u
->
saved_pos
>
0
)
fbuf_seek
(
u
,
u
->
saved_pos
,
SEEK_CUR
);
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
))
{
{
size_t
len
;
const
char
crlf
[]
=
"
\r\n
"
;
#ifdef HAVE_CRLF
#ifdef HAVE_CRLF
const
int
len
=
2
;
len
=
2
;
#else
#else
const
int
len
=
1
;
len
=
1
;
#endif
#endif
char
*
p
=
fbuf_alloc
(
u
,
len
);
if
(
swrite
(
u
->
s
,
&
crlf
[
2
-
len
],
&
len
)
!=
0
)
if
(
!
p
)
os_error
(
"Completing record after ADVANCE_NO failed"
);
os_error
(
"Completing record after ADVANCE_NO failed"
);
#ifdef HAVE_CRLF
*
(
p
++
)
=
'\r'
;
#endif
*
p
=
'\n'
;
}
}
fbuf_flush
(
u
,
u
->
mode
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment