1 /* Copyright (C) 2002-2013 Free Software Foundation, Inc.
2 Contributed by Andy Vaught
3 F2003 I/O support contributed by Jerry DeLisle
5 This file is part of the GNU Fortran runtime library (libgfortran).
7 Libgfortran is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 Libgfortran is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
35 static const st_option access_opt
[] = {
36 {"sequential", ACCESS_SEQUENTIAL
},
37 {"direct", ACCESS_DIRECT
},
38 {"append", ACCESS_APPEND
},
39 {"stream", ACCESS_STREAM
},
43 static const st_option action_opt
[] =
45 { "read", ACTION_READ
},
46 { "write", ACTION_WRITE
},
47 { "readwrite", ACTION_READWRITE
},
51 static const st_option blank_opt
[] =
53 { "null", BLANK_NULL
},
54 { "zero", BLANK_ZERO
},
58 static const st_option delim_opt
[] =
60 { "none", DELIM_NONE
},
61 { "apostrophe", DELIM_APOSTROPHE
},
62 { "quote", DELIM_QUOTE
},
66 static const st_option form_opt
[] =
68 { "formatted", FORM_FORMATTED
},
69 { "unformatted", FORM_UNFORMATTED
},
73 static const st_option position_opt
[] =
75 { "asis", POSITION_ASIS
},
76 { "rewind", POSITION_REWIND
},
77 { "append", POSITION_APPEND
},
81 static const st_option status_opt
[] =
83 { "unknown", STATUS_UNKNOWN
},
86 { "replace", STATUS_REPLACE
},
87 { "scratch", STATUS_SCRATCH
},
91 static const st_option pad_opt
[] =
98 static const st_option decimal_opt
[] =
100 { "point", DECIMAL_POINT
},
101 { "comma", DECIMAL_COMMA
},
105 static const st_option encoding_opt
[] =
107 { "utf-8", ENCODING_UTF8
},
108 { "default", ENCODING_DEFAULT
},
112 static const st_option round_opt
[] =
115 { "down", ROUND_DOWN
},
116 { "zero", ROUND_ZERO
},
117 { "nearest", ROUND_NEAREST
},
118 { "compatible", ROUND_COMPATIBLE
},
119 { "processor_defined", ROUND_PROCDEFINED
},
123 static const st_option sign_opt
[] =
125 { "plus", SIGN_PLUS
},
126 { "suppress", SIGN_SUPPRESS
},
127 { "processor_defined", SIGN_PROCDEFINED
},
131 static const st_option convert_opt
[] =
133 { "native", GFC_CONVERT_NATIVE
},
134 { "swap", GFC_CONVERT_SWAP
},
135 { "big_endian", GFC_CONVERT_BIG
},
136 { "little_endian", GFC_CONVERT_LITTLE
},
140 static const st_option async_opt
[] =
147 /* Given a unit, test to see if the file is positioned at the terminal
148 point, and if so, change state from NO_ENDFILE flag to AT_ENDFILE.
149 This prevents us from changing the state from AFTER_ENDFILE to
153 test_endfile (gfc_unit
* u
)
155 if (u
->endfile
== NO_ENDFILE
&& ssize (u
->s
) == stell (u
->s
))
156 u
->endfile
= AT_ENDFILE
;
160 /* Change the modes of a file, those that are allowed * to be
164 edit_modes (st_parameter_open
*opp
, gfc_unit
* u
, unit_flags
* flags
)
166 /* Complain about attempts to change the unchangeable. */
168 if (flags
->status
!= STATUS_UNSPECIFIED
&& flags
->status
!= STATUS_OLD
&&
169 u
->flags
.status
!= flags
->status
)
170 generate_error (&opp
->common
, LIBERROR_BAD_OPTION
,
171 "Cannot change STATUS parameter in OPEN statement");
173 if (flags
->access
!= ACCESS_UNSPECIFIED
&& u
->flags
.access
!= flags
->access
)
174 generate_error (&opp
->common
, LIBERROR_BAD_OPTION
,
175 "Cannot change ACCESS parameter in OPEN statement");
177 if (flags
->form
!= FORM_UNSPECIFIED
&& u
->flags
.form
!= flags
->form
)
178 generate_error (&opp
->common
, LIBERROR_BAD_OPTION
,
179 "Cannot change FORM parameter in OPEN statement");
181 if ((opp
->common
.flags
& IOPARM_OPEN_HAS_RECL_IN
)
182 && opp
->recl_in
!= u
->recl
)
183 generate_error (&opp
->common
, LIBERROR_BAD_OPTION
,
184 "Cannot change RECL parameter in OPEN statement");
186 if (flags
->action
!= ACTION_UNSPECIFIED
&& u
->flags
.action
!= flags
->action
)
187 generate_error (&opp
->common
, LIBERROR_BAD_OPTION
,
188 "Cannot change ACTION parameter in OPEN statement");
190 /* Status must be OLD if present. */
192 if (flags
->status
!= STATUS_UNSPECIFIED
&& flags
->status
!= STATUS_OLD
&&
193 flags
->status
!= STATUS_UNKNOWN
)
195 if (flags
->status
== STATUS_SCRATCH
)
196 notify_std (&opp
->common
, GFC_STD_GNU
,
197 "OPEN statement must have a STATUS of OLD or UNKNOWN");
199 generate_error (&opp
->common
, LIBERROR_BAD_OPTION
,
200 "OPEN statement must have a STATUS of OLD or UNKNOWN");
203 if (u
->flags
.form
== FORM_UNFORMATTED
)
205 if (flags
->delim
!= DELIM_UNSPECIFIED
)
206 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
207 "DELIM parameter conflicts with UNFORMATTED form in "
210 if (flags
->blank
!= BLANK_UNSPECIFIED
)
211 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
212 "BLANK parameter conflicts with UNFORMATTED form in "
215 if (flags
->pad
!= PAD_UNSPECIFIED
)
216 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
217 "PAD parameter conflicts with UNFORMATTED form in "
220 if (flags
->decimal
!= DECIMAL_UNSPECIFIED
)
221 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
222 "DECIMAL parameter conflicts with UNFORMATTED form in "
225 if (flags
->encoding
!= ENCODING_UNSPECIFIED
)
226 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
227 "ENCODING parameter conflicts with UNFORMATTED form in "
230 if (flags
->round
!= ROUND_UNSPECIFIED
)
231 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
232 "ROUND parameter conflicts with UNFORMATTED form in "
235 if (flags
->sign
!= SIGN_UNSPECIFIED
)
236 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
237 "SIGN parameter conflicts with UNFORMATTED form in "
241 if ((opp
->common
.flags
& IOPARM_LIBRETURN_MASK
) == IOPARM_LIBRETURN_OK
)
243 /* Change the changeable: */
244 if (flags
->blank
!= BLANK_UNSPECIFIED
)
245 u
->flags
.blank
= flags
->blank
;
246 if (flags
->delim
!= DELIM_UNSPECIFIED
)
247 u
->flags
.delim
= flags
->delim
;
248 if (flags
->pad
!= PAD_UNSPECIFIED
)
249 u
->flags
.pad
= flags
->pad
;
250 if (flags
->decimal
!= DECIMAL_UNSPECIFIED
)
251 u
->flags
.decimal
= flags
->decimal
;
252 if (flags
->encoding
!= ENCODING_UNSPECIFIED
)
253 u
->flags
.encoding
= flags
->encoding
;
254 if (flags
->async
!= ASYNC_UNSPECIFIED
)
255 u
->flags
.async
= flags
->async
;
256 if (flags
->round
!= ROUND_UNSPECIFIED
)
257 u
->flags
.round
= flags
->round
;
258 if (flags
->sign
!= SIGN_UNSPECIFIED
)
259 u
->flags
.sign
= flags
->sign
;
262 /* Reposition the file if necessary. */
264 switch (flags
->position
)
266 case POSITION_UNSPECIFIED
:
270 case POSITION_REWIND
:
271 if (sseek (u
->s
, 0, SEEK_SET
) != 0)
274 u
->current_record
= 0;
280 case POSITION_APPEND
:
281 if (sseek (u
->s
, 0, SEEK_END
) < 0)
284 if (flags
->access
!= ACCESS_STREAM
)
285 u
->current_record
= 0;
287 u
->endfile
= AT_ENDFILE
; /* We are at the end. */
291 generate_error (&opp
->common
, LIBERROR_OS
, NULL
);
299 /* Open an unused unit. */
302 new_unit (st_parameter_open
*opp
, gfc_unit
*u
, unit_flags
* flags
)
306 char tmpname
[5 /* fort. */ + 10 /* digits of unit number */ + 1 /* 0 */];
308 /* Change unspecifieds to defaults. Leave (flags->action ==
309 ACTION_UNSPECIFIED) alone so open_external() can set it based on
310 what type of open actually works. */
312 if (flags
->access
== ACCESS_UNSPECIFIED
)
313 flags
->access
= ACCESS_SEQUENTIAL
;
315 if (flags
->form
== FORM_UNSPECIFIED
)
316 flags
->form
= (flags
->access
== ACCESS_SEQUENTIAL
)
317 ? FORM_FORMATTED
: FORM_UNFORMATTED
;
319 if (flags
->async
== ASYNC_UNSPECIFIED
)
320 flags
->async
= ASYNC_NO
;
322 if (flags
->status
== STATUS_UNSPECIFIED
)
323 flags
->status
= STATUS_UNKNOWN
;
327 if (flags
->delim
== DELIM_UNSPECIFIED
)
328 flags
->delim
= DELIM_NONE
;
331 if (flags
->form
== FORM_UNFORMATTED
)
333 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
334 "DELIM parameter conflicts with UNFORMATTED form in "
340 if (flags
->blank
== BLANK_UNSPECIFIED
)
341 flags
->blank
= BLANK_NULL
;
344 if (flags
->form
== FORM_UNFORMATTED
)
346 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
347 "BLANK parameter conflicts with UNFORMATTED form in "
353 if (flags
->pad
== PAD_UNSPECIFIED
)
354 flags
->pad
= PAD_YES
;
357 if (flags
->form
== FORM_UNFORMATTED
)
359 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
360 "PAD parameter conflicts with UNFORMATTED form in "
366 if (flags
->decimal
== DECIMAL_UNSPECIFIED
)
367 flags
->decimal
= DECIMAL_POINT
;
370 if (flags
->form
== FORM_UNFORMATTED
)
372 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
373 "DECIMAL parameter conflicts with UNFORMATTED form "
374 "in OPEN statement");
379 if (flags
->encoding
== ENCODING_UNSPECIFIED
)
380 flags
->encoding
= ENCODING_DEFAULT
;
383 if (flags
->form
== FORM_UNFORMATTED
)
385 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
386 "ENCODING parameter conflicts with UNFORMATTED form in "
392 /* NB: the value for ROUND when it's not specified by the user does not
393 have to be PROCESSOR_DEFINED; the standard says that it is
394 processor dependent, and requires that it is one of the
395 possible value (see F2003, 9.4.5.13). */
396 if (flags
->round
== ROUND_UNSPECIFIED
)
397 flags
->round
= ROUND_PROCDEFINED
;
400 if (flags
->form
== FORM_UNFORMATTED
)
402 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
403 "ROUND parameter conflicts with UNFORMATTED form in "
409 if (flags
->sign
== SIGN_UNSPECIFIED
)
410 flags
->sign
= SIGN_PROCDEFINED
;
413 if (flags
->form
== FORM_UNFORMATTED
)
415 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
416 "SIGN parameter conflicts with UNFORMATTED form in "
422 if (flags
->position
!= POSITION_ASIS
&& flags
->access
== ACCESS_DIRECT
)
424 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
425 "ACCESS parameter conflicts with SEQUENTIAL access in "
430 if (flags
->position
== POSITION_UNSPECIFIED
)
431 flags
->position
= POSITION_ASIS
;
433 if (flags
->access
== ACCESS_DIRECT
434 && (opp
->common
.flags
& IOPARM_OPEN_HAS_RECL_IN
) == 0)
436 generate_error (&opp
->common
, LIBERROR_MISSING_OPTION
,
437 "Missing RECL parameter in OPEN statement");
441 if ((opp
->common
.flags
& IOPARM_OPEN_HAS_RECL_IN
) && opp
->recl_in
<= 0)
443 generate_error (&opp
->common
, LIBERROR_BAD_OPTION
,
444 "RECL parameter is non-positive in OPEN statement");
448 switch (flags
->status
)
451 if ((opp
->common
.flags
& IOPARM_OPEN_HAS_FILE
) == 0)
457 generate_error (&opp
->common
, LIBERROR_BAD_OPTION
,
458 "FILE parameter must not be present in OPEN statement");
465 if ((opp
->common
.flags
& IOPARM_OPEN_HAS_FILE
))
469 opp
->file_len
= snprintf(opp
->file
, sizeof (tmpname
), "fort.%d",
470 (int) opp
->common
.unit
);
474 internal_error (&opp
->common
, "new_unit(): Bad status");
477 /* Make sure the file isn't already open someplace else.
478 Do not error if opening file preconnected to stdin, stdout, stderr. */
481 if ((opp
->common
.flags
& IOPARM_OPEN_HAS_FILE
) != 0)
482 u2
= find_file (opp
->file
, opp
->file_len
);
484 && (options
.stdin_unit
< 0 || u2
->unit_number
!= options
.stdin_unit
)
485 && (options
.stdout_unit
< 0 || u2
->unit_number
!= options
.stdout_unit
)
486 && (options
.stderr_unit
< 0 || u2
->unit_number
!= options
.stderr_unit
))
489 generate_error (&opp
->common
, LIBERROR_ALREADY_OPEN
, NULL
);
498 s
= open_external (opp
, flags
);
503 path
= (char *) gfc_alloca (opp
->file_len
+ 1);
504 msglen
= opp
->file_len
+ 51;
505 msg
= (char *) gfc_alloca (msglen
);
506 unpack_filename (path
, opp
->file
, opp
->file_len
);
511 snprintf (msg
, msglen
, "File '%s' does not exist", path
);
515 snprintf (msg
, msglen
, "File '%s' already exists", path
);
519 snprintf (msg
, msglen
,
520 "Permission denied trying to open file '%s'", path
);
524 snprintf (msg
, msglen
, "'%s' is a directory", path
);
531 generate_error (&opp
->common
, LIBERROR_OS
, msg
);
535 if (flags
->status
== STATUS_NEW
|| flags
->status
== STATUS_REPLACE
)
536 flags
->status
= STATUS_OLD
;
538 /* Create the unit structure. */
540 u
->file
= xmalloc (opp
->file_len
);
541 if (u
->unit_number
!= opp
->common
.unit
)
542 internal_error (&opp
->common
, "Unit number changed");
546 u
->endfile
= NO_ENDFILE
;
548 u
->current_record
= 0;
554 if (flags
->position
== POSITION_APPEND
)
556 if (sseek (u
->s
, 0, SEEK_END
) < 0)
557 generate_error (&opp
->common
, LIBERROR_OS
, NULL
);
558 u
->endfile
= AT_ENDFILE
;
561 /* Unspecified recl ends up with a processor dependent value. */
563 if ((opp
->common
.flags
& IOPARM_OPEN_HAS_RECL_IN
))
565 u
->flags
.has_recl
= 1;
566 u
->recl
= opp
->recl_in
;
567 u
->recl_subrecord
= u
->recl
;
568 u
->bytes_left
= u
->recl
;
572 u
->flags
.has_recl
= 0;
573 u
->recl
= max_offset
;
574 if (compile_options
.max_subrecord_length
)
576 u
->recl_subrecord
= compile_options
.max_subrecord_length
;
580 switch (compile_options
.record_marker
)
584 case sizeof (GFC_INTEGER_4
):
585 u
->recl_subrecord
= GFC_MAX_SUBRECORD_LENGTH
;
588 case sizeof (GFC_INTEGER_8
):
589 u
->recl_subrecord
= max_offset
- 16;
593 runtime_error ("Illegal value for record marker");
599 /* If the file is direct access, calculate the maximum record number
600 via a division now instead of letting the multiplication overflow
603 if (flags
->access
== ACCESS_DIRECT
)
604 u
->maxrec
= max_offset
/ u
->recl
;
606 if (flags
->access
== ACCESS_STREAM
)
608 u
->maxrec
= max_offset
;
611 u
->strm_pos
= stell (u
->s
) + 1;
614 memmove (u
->file
, opp
->file
, opp
->file_len
);
615 u
->file_len
= opp
->file_len
;
617 /* Curiously, the standard requires that the
618 position specifier be ignored for new files so a newly connected
619 file starts out at the initial point. We still need to figure
620 out if the file is at the end or not. */
624 if (flags
->status
== STATUS_SCRATCH
&& opp
->file
!= NULL
)
627 if (flags
->form
== FORM_FORMATTED
)
629 if ((opp
->common
.flags
& IOPARM_OPEN_HAS_RECL_IN
))
630 fbuf_init (u
, u
->recl
);
643 /* Free memory associated with a temporary filename. */
645 if (flags
->status
== STATUS_SCRATCH
&& opp
->file
!= NULL
)
655 /* Open a unit which is already open. This involves changing the
656 modes or closing what is there now and opening the new file. */
659 already_open (st_parameter_open
*opp
, gfc_unit
* u
, unit_flags
* flags
)
661 if ((opp
->common
.flags
& IOPARM_OPEN_HAS_FILE
) == 0)
663 edit_modes (opp
, u
, flags
);
667 /* If the file is connected to something else, close it and open a
670 if (!compare_file_filename (u
, opp
->file
, opp
->file_len
))
672 #if !HAVE_UNLINK_OPEN_FILE
674 if (u
->file
&& u
->flags
.status
== STATUS_SCRATCH
)
676 path
= (char *) gfc_alloca (u
->file_len
+ 1);
677 unpack_filename (path
, u
->file
, u
->file_len
);
681 if (sclose (u
->s
) == -1)
684 generate_error (&opp
->common
, LIBERROR_OS
,
685 "Error closing file in OPEN statement");
694 #if !HAVE_UNLINK_OPEN_FILE
699 u
= new_unit (opp
, u
, flags
);
705 edit_modes (opp
, u
, flags
);
711 extern void st_open (st_parameter_open
*opp
);
712 export_proto(st_open
);
715 st_open (st_parameter_open
*opp
)
719 GFC_INTEGER_4 cf
= opp
->common
.flags
;
722 library_start (&opp
->common
);
724 /* Decode options. */
726 flags
.access
= !(cf
& IOPARM_OPEN_HAS_ACCESS
) ? ACCESS_UNSPECIFIED
:
727 find_option (&opp
->common
, opp
->access
, opp
->access_len
,
728 access_opt
, "Bad ACCESS parameter in OPEN statement");
730 flags
.action
= !(cf
& IOPARM_OPEN_HAS_ACTION
) ? ACTION_UNSPECIFIED
:
731 find_option (&opp
->common
, opp
->action
, opp
->action_len
,
732 action_opt
, "Bad ACTION parameter in OPEN statement");
734 flags
.blank
= !(cf
& IOPARM_OPEN_HAS_BLANK
) ? BLANK_UNSPECIFIED
:
735 find_option (&opp
->common
, opp
->blank
, opp
->blank_len
,
736 blank_opt
, "Bad BLANK parameter in OPEN statement");
738 flags
.delim
= !(cf
& IOPARM_OPEN_HAS_DELIM
) ? DELIM_UNSPECIFIED
:
739 find_option (&opp
->common
, opp
->delim
, opp
->delim_len
,
740 delim_opt
, "Bad DELIM parameter in OPEN statement");
742 flags
.pad
= !(cf
& IOPARM_OPEN_HAS_PAD
) ? PAD_UNSPECIFIED
:
743 find_option (&opp
->common
, opp
->pad
, opp
->pad_len
,
744 pad_opt
, "Bad PAD parameter in OPEN statement");
746 flags
.decimal
= !(cf
& IOPARM_OPEN_HAS_DECIMAL
) ? DECIMAL_UNSPECIFIED
:
747 find_option (&opp
->common
, opp
->decimal
, opp
->decimal_len
,
748 decimal_opt
, "Bad DECIMAL parameter in OPEN statement");
750 flags
.encoding
= !(cf
& IOPARM_OPEN_HAS_ENCODING
) ? ENCODING_UNSPECIFIED
:
751 find_option (&opp
->common
, opp
->encoding
, opp
->encoding_len
,
752 encoding_opt
, "Bad ENCODING parameter in OPEN statement");
754 flags
.async
= !(cf
& IOPARM_OPEN_HAS_ASYNCHRONOUS
) ? ASYNC_UNSPECIFIED
:
755 find_option (&opp
->common
, opp
->asynchronous
, opp
->asynchronous_len
,
756 async_opt
, "Bad ASYNCHRONOUS parameter in OPEN statement");
758 flags
.round
= !(cf
& IOPARM_OPEN_HAS_ROUND
) ? ROUND_UNSPECIFIED
:
759 find_option (&opp
->common
, opp
->round
, opp
->round_len
,
760 round_opt
, "Bad ROUND parameter in OPEN statement");
762 flags
.sign
= !(cf
& IOPARM_OPEN_HAS_SIGN
) ? SIGN_UNSPECIFIED
:
763 find_option (&opp
->common
, opp
->sign
, opp
->sign_len
,
764 sign_opt
, "Bad SIGN parameter in OPEN statement");
766 flags
.form
= !(cf
& IOPARM_OPEN_HAS_FORM
) ? FORM_UNSPECIFIED
:
767 find_option (&opp
->common
, opp
->form
, opp
->form_len
,
768 form_opt
, "Bad FORM parameter in OPEN statement");
770 flags
.position
= !(cf
& IOPARM_OPEN_HAS_POSITION
) ? POSITION_UNSPECIFIED
:
771 find_option (&opp
->common
, opp
->position
, opp
->position_len
,
772 position_opt
, "Bad POSITION parameter in OPEN statement");
774 flags
.status
= !(cf
& IOPARM_OPEN_HAS_STATUS
) ? STATUS_UNSPECIFIED
:
775 find_option (&opp
->common
, opp
->status
, opp
->status_len
,
776 status_opt
, "Bad STATUS parameter in OPEN statement");
778 /* First, we check wether the convert flag has been set via environment
779 variable. This overrides the convert tag in the open statement. */
781 conv
= get_unformatted_convert (opp
->common
.unit
);
783 if (conv
== GFC_CONVERT_NONE
)
785 /* Nothing has been set by environment variable, check the convert tag. */
786 if (cf
& IOPARM_OPEN_HAS_CONVERT
)
787 conv
= find_option (&opp
->common
, opp
->convert
, opp
->convert_len
,
789 "Bad CONVERT parameter in OPEN statement");
791 conv
= compile_options
.convert
;
794 /* We use big_endian, which is 0 on little-endian machines
795 and 1 on big-endian machines. */
798 case GFC_CONVERT_NATIVE
:
799 case GFC_CONVERT_SWAP
:
802 case GFC_CONVERT_BIG
:
803 conv
= big_endian
? GFC_CONVERT_NATIVE
: GFC_CONVERT_SWAP
;
806 case GFC_CONVERT_LITTLE
:
807 conv
= big_endian
? GFC_CONVERT_SWAP
: GFC_CONVERT_NATIVE
;
811 internal_error (&opp
->common
, "Illegal value for CONVERT");
815 flags
.convert
= conv
;
817 if (!(opp
->common
.flags
& IOPARM_OPEN_HAS_NEWUNIT
) && opp
->common
.unit
< 0)
818 generate_error (&opp
->common
, LIBERROR_BAD_OPTION
,
819 "Bad unit number in OPEN statement");
821 if (flags
.position
!= POSITION_UNSPECIFIED
822 && flags
.access
== ACCESS_DIRECT
)
823 generate_error (&opp
->common
, LIBERROR_BAD_OPTION
,
824 "Cannot use POSITION with direct access files");
826 if (flags
.access
== ACCESS_APPEND
)
828 if (flags
.position
!= POSITION_UNSPECIFIED
829 && flags
.position
!= POSITION_APPEND
)
830 generate_error (&opp
->common
, LIBERROR_BAD_OPTION
,
831 "Conflicting ACCESS and POSITION flags in"
834 notify_std (&opp
->common
, GFC_STD_GNU
,
835 "Extension: APPEND as a value for ACCESS in OPEN statement");
836 flags
.access
= ACCESS_SEQUENTIAL
;
837 flags
.position
= POSITION_APPEND
;
840 if (flags
.position
== POSITION_UNSPECIFIED
)
841 flags
.position
= POSITION_ASIS
;
843 if ((opp
->common
.flags
& IOPARM_LIBRETURN_MASK
) == IOPARM_LIBRETURN_OK
)
845 if ((opp
->common
.flags
& IOPARM_OPEN_HAS_NEWUNIT
))
846 opp
->common
.unit
= get_unique_unit_number(opp
);
848 u
= find_or_create_unit (opp
->common
.unit
);
851 u
= new_unit (opp
, u
, &flags
);
856 already_open (opp
, u
, &flags
);
859 if ((opp
->common
.flags
& IOPARM_OPEN_HAS_NEWUNIT
)
860 && (opp
->common
.flags
& IOPARM_LIBRETURN_MASK
) == IOPARM_LIBRETURN_OK
)
861 *opp
->newunit
= opp
->common
.unit
;