1 /* Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
2 Free Software Foundation, Inc.
3 Contributed by Andy Vaught
4 F2003 I/O support contributed by Jerry DeLisle
6 This file is part of the GNU Fortran runtime library (libgfortran).
8 Libgfortran is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 Libgfortran is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. */
36 static const st_option access_opt
[] = {
37 {"sequential", ACCESS_SEQUENTIAL
},
38 {"direct", ACCESS_DIRECT
},
39 {"append", ACCESS_APPEND
},
40 {"stream", ACCESS_STREAM
},
44 static const st_option action_opt
[] =
46 { "read", ACTION_READ
},
47 { "write", ACTION_WRITE
},
48 { "readwrite", ACTION_READWRITE
},
52 static const st_option blank_opt
[] =
54 { "null", BLANK_NULL
},
55 { "zero", BLANK_ZERO
},
59 static const st_option delim_opt
[] =
61 { "none", DELIM_NONE
},
62 { "apostrophe", DELIM_APOSTROPHE
},
63 { "quote", DELIM_QUOTE
},
67 static const st_option form_opt
[] =
69 { "formatted", FORM_FORMATTED
},
70 { "unformatted", FORM_UNFORMATTED
},
74 static const st_option position_opt
[] =
76 { "asis", POSITION_ASIS
},
77 { "rewind", POSITION_REWIND
},
78 { "append", POSITION_APPEND
},
82 static const st_option status_opt
[] =
84 { "unknown", STATUS_UNKNOWN
},
87 { "replace", STATUS_REPLACE
},
88 { "scratch", STATUS_SCRATCH
},
92 static const st_option pad_opt
[] =
99 static const st_option decimal_opt
[] =
101 { "point", DECIMAL_POINT
},
102 { "comma", DECIMAL_COMMA
},
106 static const st_option encoding_opt
[] =
108 { "utf-8", ENCODING_UTF8
},
109 { "default", ENCODING_DEFAULT
},
113 static const st_option round_opt
[] =
116 { "down", ROUND_DOWN
},
117 { "zero", ROUND_ZERO
},
118 { "nearest", ROUND_NEAREST
},
119 { "compatible", ROUND_COMPATIBLE
},
120 { "processor_defined", ROUND_PROCDEFINED
},
124 static const st_option sign_opt
[] =
126 { "plus", SIGN_PLUS
},
127 { "suppress", SIGN_SUPPRESS
},
128 { "processor_defined", SIGN_PROCDEFINED
},
132 static const st_option convert_opt
[] =
134 { "native", GFC_CONVERT_NATIVE
},
135 { "swap", GFC_CONVERT_SWAP
},
136 { "big_endian", GFC_CONVERT_BIG
},
137 { "little_endian", GFC_CONVERT_LITTLE
},
141 static const st_option async_opt
[] =
148 /* Given a unit, test to see if the file is positioned at the terminal
149 point, and if so, change state from NO_ENDFILE flag to AT_ENDFILE.
150 This prevents us from changing the state from AFTER_ENDFILE to
154 test_endfile (gfc_unit
* u
)
156 if (u
->endfile
== NO_ENDFILE
&& file_length (u
->s
) == stell (u
->s
))
157 u
->endfile
= AT_ENDFILE
;
161 /* Change the modes of a file, those that are allowed * to be
165 edit_modes (st_parameter_open
*opp
, gfc_unit
* u
, unit_flags
* flags
)
167 /* Complain about attempts to change the unchangeable. */
169 if (flags
->status
!= STATUS_UNSPECIFIED
&& flags
->status
!= STATUS_OLD
&&
170 u
->flags
.status
!= flags
->status
)
171 generate_error (&opp
->common
, LIBERROR_BAD_OPTION
,
172 "Cannot change STATUS parameter in OPEN statement");
174 if (flags
->access
!= ACCESS_UNSPECIFIED
&& u
->flags
.access
!= flags
->access
)
175 generate_error (&opp
->common
, LIBERROR_BAD_OPTION
,
176 "Cannot change ACCESS parameter in OPEN statement");
178 if (flags
->form
!= FORM_UNSPECIFIED
&& u
->flags
.form
!= flags
->form
)
179 generate_error (&opp
->common
, LIBERROR_BAD_OPTION
,
180 "Cannot change FORM parameter in OPEN statement");
182 if ((opp
->common
.flags
& IOPARM_OPEN_HAS_RECL_IN
)
183 && opp
->recl_in
!= u
->recl
)
184 generate_error (&opp
->common
, LIBERROR_BAD_OPTION
,
185 "Cannot change RECL parameter in OPEN statement");
187 if (flags
->action
!= ACTION_UNSPECIFIED
&& u
->flags
.action
!= flags
->action
)
188 generate_error (&opp
->common
, LIBERROR_BAD_OPTION
,
189 "Cannot change ACTION parameter in OPEN statement");
191 /* Status must be OLD if present. */
193 if (flags
->status
!= STATUS_UNSPECIFIED
&& flags
->status
!= STATUS_OLD
&&
194 flags
->status
!= STATUS_UNKNOWN
)
196 if (flags
->status
== STATUS_SCRATCH
)
197 notify_std (&opp
->common
, GFC_STD_GNU
,
198 "OPEN statement must have a STATUS of OLD or UNKNOWN");
200 generate_error (&opp
->common
, LIBERROR_BAD_OPTION
,
201 "OPEN statement must have a STATUS of OLD or UNKNOWN");
204 if (u
->flags
.form
== FORM_UNFORMATTED
)
206 if (flags
->delim
!= DELIM_UNSPECIFIED
)
207 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
208 "DELIM parameter conflicts with UNFORMATTED form in "
211 if (flags
->blank
!= BLANK_UNSPECIFIED
)
212 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
213 "BLANK parameter conflicts with UNFORMATTED form in "
216 if (flags
->pad
!= PAD_UNSPECIFIED
)
217 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
218 "PAD parameter conflicts with UNFORMATTED form in "
221 if (flags
->decimal
!= DECIMAL_UNSPECIFIED
)
222 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
223 "DECIMAL parameter conflicts with UNFORMATTED form in "
226 if (flags
->encoding
!= ENCODING_UNSPECIFIED
)
227 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
228 "ENCODING parameter conflicts with UNFORMATTED form in "
231 if (flags
->round
!= ROUND_UNSPECIFIED
)
232 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
233 "ROUND parameter conflicts with UNFORMATTED form in "
236 if (flags
->sign
!= SIGN_UNSPECIFIED
)
237 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
238 "SIGN parameter conflicts with UNFORMATTED form in "
242 if ((opp
->common
.flags
& IOPARM_LIBRETURN_MASK
) == IOPARM_LIBRETURN_OK
)
244 /* Change the changeable: */
245 if (flags
->blank
!= BLANK_UNSPECIFIED
)
246 u
->flags
.blank
= flags
->blank
;
247 if (flags
->delim
!= DELIM_UNSPECIFIED
)
248 u
->flags
.delim
= flags
->delim
;
249 if (flags
->pad
!= PAD_UNSPECIFIED
)
250 u
->flags
.pad
= flags
->pad
;
251 if (flags
->decimal
!= DECIMAL_UNSPECIFIED
)
252 u
->flags
.decimal
= flags
->decimal
;
253 if (flags
->encoding
!= ENCODING_UNSPECIFIED
)
254 u
->flags
.encoding
= flags
->encoding
;
255 if (flags
->async
!= ASYNC_UNSPECIFIED
)
256 u
->flags
.async
= flags
->async
;
257 if (flags
->round
!= ROUND_UNSPECIFIED
)
258 u
->flags
.round
= flags
->round
;
259 if (flags
->sign
!= SIGN_UNSPECIFIED
)
260 u
->flags
.sign
= flags
->sign
;
263 /* Reposition the file if necessary. */
265 switch (flags
->position
)
267 case POSITION_UNSPECIFIED
:
271 case POSITION_REWIND
:
272 if (sseek (u
->s
, 0, SEEK_SET
) != 0)
275 u
->current_record
= 0;
281 case POSITION_APPEND
:
282 if (sseek (u
->s
, 0, SEEK_END
) < 0)
285 if (flags
->access
!= ACCESS_STREAM
)
286 u
->current_record
= 0;
288 u
->endfile
= AT_ENDFILE
; /* We are at the end. */
292 generate_error (&opp
->common
, LIBERROR_OS
, NULL
);
300 /* Open an unused unit. */
303 new_unit (st_parameter_open
*opp
, gfc_unit
*u
, unit_flags
* flags
)
307 char tmpname
[5 /* fort. */ + 10 /* digits of unit number */ + 1 /* 0 */];
309 /* Change unspecifieds to defaults. Leave (flags->action ==
310 ACTION_UNSPECIFIED) alone so open_external() can set it based on
311 what type of open actually works. */
313 if (flags
->access
== ACCESS_UNSPECIFIED
)
314 flags
->access
= ACCESS_SEQUENTIAL
;
316 if (flags
->form
== FORM_UNSPECIFIED
)
317 flags
->form
= (flags
->access
== ACCESS_SEQUENTIAL
)
318 ? FORM_FORMATTED
: FORM_UNFORMATTED
;
320 if (flags
->async
== ASYNC_UNSPECIFIED
)
321 flags
->async
= ASYNC_NO
;
323 if (flags
->status
== STATUS_UNSPECIFIED
)
324 flags
->status
= STATUS_UNKNOWN
;
328 if (flags
->delim
== DELIM_UNSPECIFIED
)
329 flags
->delim
= DELIM_NONE
;
332 if (flags
->form
== FORM_UNFORMATTED
)
334 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
335 "DELIM parameter conflicts with UNFORMATTED form in "
341 if (flags
->blank
== BLANK_UNSPECIFIED
)
342 flags
->blank
= BLANK_NULL
;
345 if (flags
->form
== FORM_UNFORMATTED
)
347 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
348 "BLANK parameter conflicts with UNFORMATTED form in "
354 if (flags
->pad
== PAD_UNSPECIFIED
)
355 flags
->pad
= PAD_YES
;
358 if (flags
->form
== FORM_UNFORMATTED
)
360 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
361 "PAD parameter conflicts with UNFORMATTED form in "
367 if (flags
->decimal
== DECIMAL_UNSPECIFIED
)
368 flags
->decimal
= DECIMAL_POINT
;
371 if (flags
->form
== FORM_UNFORMATTED
)
373 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
374 "DECIMAL parameter conflicts with UNFORMATTED form "
375 "in OPEN statement");
380 if (flags
->encoding
== ENCODING_UNSPECIFIED
)
381 flags
->encoding
= ENCODING_DEFAULT
;
384 if (flags
->form
== FORM_UNFORMATTED
)
386 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
387 "ENCODING parameter conflicts with UNFORMATTED form in "
393 /* NB: the value for ROUND when it's not specified by the user does not
394 have to be PROCESSOR_DEFINED; the standard says that it is
395 processor dependent, and requires that it is one of the
396 possible value (see F2003, 9.4.5.13). */
397 if (flags
->round
== ROUND_UNSPECIFIED
)
398 flags
->round
= ROUND_PROCDEFINED
;
401 if (flags
->form
== FORM_UNFORMATTED
)
403 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
404 "ROUND parameter conflicts with UNFORMATTED form in "
410 if (flags
->sign
== SIGN_UNSPECIFIED
)
411 flags
->sign
= SIGN_PROCDEFINED
;
414 if (flags
->form
== FORM_UNFORMATTED
)
416 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
417 "SIGN parameter conflicts with UNFORMATTED form in "
423 if (flags
->position
!= POSITION_ASIS
&& flags
->access
== ACCESS_DIRECT
)
425 generate_error (&opp
->common
, LIBERROR_OPTION_CONFLICT
,
426 "ACCESS parameter conflicts with SEQUENTIAL access in "
431 if (flags
->position
== POSITION_UNSPECIFIED
)
432 flags
->position
= POSITION_ASIS
;
434 if (flags
->access
== ACCESS_DIRECT
435 && (opp
->common
.flags
& IOPARM_OPEN_HAS_RECL_IN
) == 0)
437 generate_error (&opp
->common
, LIBERROR_MISSING_OPTION
,
438 "Missing RECL parameter in OPEN statement");
442 if ((opp
->common
.flags
& IOPARM_OPEN_HAS_RECL_IN
) && opp
->recl_in
<= 0)
444 generate_error (&opp
->common
, LIBERROR_BAD_OPTION
,
445 "RECL parameter is non-positive in OPEN statement");
449 switch (flags
->status
)
452 if ((opp
->common
.flags
& IOPARM_OPEN_HAS_FILE
) == 0)
458 generate_error (&opp
->common
, LIBERROR_BAD_OPTION
,
459 "FILE parameter must not be present in OPEN statement");
466 if ((opp
->common
.flags
& IOPARM_OPEN_HAS_FILE
))
471 opp
->file_len
= snprintf(opp
->file
, sizeof (tmpname
), "fort.%d",
472 (int) opp
->common
.unit
);
474 opp
->file_len
= sprintf(opp
->file
, "fort.%d", (int) opp
->common
.unit
);
479 internal_error (&opp
->common
, "new_unit(): Bad status");
482 /* Make sure the file isn't already open someplace else.
483 Do not error if opening file preconnected to stdin, stdout, stderr. */
486 if ((opp
->common
.flags
& IOPARM_OPEN_HAS_FILE
) != 0)
487 u2
= find_file (opp
->file
, opp
->file_len
);
489 && (options
.stdin_unit
< 0 || u2
->unit_number
!= options
.stdin_unit
)
490 && (options
.stdout_unit
< 0 || u2
->unit_number
!= options
.stdout_unit
)
491 && (options
.stderr_unit
< 0 || u2
->unit_number
!= options
.stderr_unit
))
494 generate_error (&opp
->common
, LIBERROR_ALREADY_OPEN
, NULL
);
503 s
= open_external (opp
, flags
);
507 path
= (char *) gfc_alloca (opp
->file_len
+ 1);
508 msg
= (char *) gfc_alloca (opp
->file_len
+ 51);
509 unpack_filename (path
, opp
->file
, opp
->file_len
);
514 sprintf (msg
, "File '%s' does not exist", path
);
518 sprintf (msg
, "File '%s' already exists", path
);
522 sprintf (msg
, "Permission denied trying to open file '%s'", path
);
526 sprintf (msg
, "'%s' is a directory", path
);
533 generate_error (&opp
->common
, LIBERROR_OS
, msg
);
537 if (flags
->status
== STATUS_NEW
|| flags
->status
== STATUS_REPLACE
)
538 flags
->status
= STATUS_OLD
;
540 /* Create the unit structure. */
542 u
->file
= get_mem (opp
->file_len
);
543 if (u
->unit_number
!= opp
->common
.unit
)
544 internal_error (&opp
->common
, "Unit number changed");
548 u
->endfile
= NO_ENDFILE
;
550 u
->current_record
= 0;
556 if (flags
->position
== POSITION_APPEND
)
558 if (file_size (opp
->file
, opp
->file_len
) > 0 && sseek (u
->s
, 0, SEEK_END
) < 0)
559 generate_error (&opp
->common
, LIBERROR_OS
, NULL
);
560 u
->endfile
= AT_ENDFILE
;
563 /* Unspecified recl ends up with a processor dependent value. */
565 if ((opp
->common
.flags
& IOPARM_OPEN_HAS_RECL_IN
))
567 u
->flags
.has_recl
= 1;
568 u
->recl
= opp
->recl_in
;
569 u
->recl_subrecord
= u
->recl
;
570 u
->bytes_left
= u
->recl
;
574 u
->flags
.has_recl
= 0;
575 u
->recl
= max_offset
;
576 if (compile_options
.max_subrecord_length
)
578 u
->recl_subrecord
= compile_options
.max_subrecord_length
;
582 switch (compile_options
.record_marker
)
586 case sizeof (GFC_INTEGER_4
):
587 u
->recl_subrecord
= GFC_MAX_SUBRECORD_LENGTH
;
590 case sizeof (GFC_INTEGER_8
):
591 u
->recl_subrecord
= max_offset
- 16;
595 runtime_error ("Illegal value for record marker");
601 /* If the file is direct access, calculate the maximum record number
602 via a division now instead of letting the multiplication overflow
605 if (flags
->access
== ACCESS_DIRECT
)
606 u
->maxrec
= max_offset
/ u
->recl
;
608 if (flags
->access
== ACCESS_STREAM
)
610 u
->maxrec
= max_offset
;
613 u
->strm_pos
= stell (u
->s
) + 1;
616 memmove (u
->file
, opp
->file
, opp
->file_len
);
617 u
->file_len
= opp
->file_len
;
619 /* Curiously, the standard requires that the
620 position specifier be ignored for new files so a newly connected
621 file starts out at the initial point. We still need to figure
622 out if the file is at the end or not. */
626 if (flags
->status
== STATUS_SCRATCH
&& opp
->file
!= NULL
)
629 if (flags
->form
== FORM_FORMATTED
)
631 if ((opp
->common
.flags
& IOPARM_OPEN_HAS_RECL_IN
))
632 fbuf_init (u
, u
->recl
);
645 /* Free memory associated with a temporary filename. */
647 if (flags
->status
== STATUS_SCRATCH
&& opp
->file
!= NULL
)
657 /* Open a unit which is already open. This involves changing the
658 modes or closing what is there now and opening the new file. */
661 already_open (st_parameter_open
*opp
, gfc_unit
* u
, unit_flags
* flags
)
663 if ((opp
->common
.flags
& IOPARM_OPEN_HAS_FILE
) == 0)
665 edit_modes (opp
, u
, flags
);
669 /* If the file is connected to something else, close it and open a
672 if (!compare_file_filename (u
, opp
->file
, opp
->file_len
))
674 #if !HAVE_UNLINK_OPEN_FILE
676 if (u
->file
&& u
->flags
.status
== STATUS_SCRATCH
)
678 path
= (char *) gfc_alloca (u
->file_len
+ 1);
679 unpack_filename (path
, u
->file
, u
->file_len
);
683 if (sclose (u
->s
) == -1)
686 generate_error (&opp
->common
, LIBERROR_OS
,
687 "Error closing file in OPEN statement");
697 #if !HAVE_UNLINK_OPEN_FILE
702 u
= new_unit (opp
, u
, flags
);
708 edit_modes (opp
, u
, flags
);
714 extern void st_open (st_parameter_open
*opp
);
715 export_proto(st_open
);
718 st_open (st_parameter_open
*opp
)
722 GFC_INTEGER_4 cf
= opp
->common
.flags
;
725 library_start (&opp
->common
);
727 /* Decode options. */
729 flags
.access
= !(cf
& IOPARM_OPEN_HAS_ACCESS
) ? ACCESS_UNSPECIFIED
:
730 find_option (&opp
->common
, opp
->access
, opp
->access_len
,
731 access_opt
, "Bad ACCESS parameter in OPEN statement");
733 flags
.action
= !(cf
& IOPARM_OPEN_HAS_ACTION
) ? ACTION_UNSPECIFIED
:
734 find_option (&opp
->common
, opp
->action
, opp
->action_len
,
735 action_opt
, "Bad ACTION parameter in OPEN statement");
737 flags
.blank
= !(cf
& IOPARM_OPEN_HAS_BLANK
) ? BLANK_UNSPECIFIED
:
738 find_option (&opp
->common
, opp
->blank
, opp
->blank_len
,
739 blank_opt
, "Bad BLANK parameter in OPEN statement");
741 flags
.delim
= !(cf
& IOPARM_OPEN_HAS_DELIM
) ? DELIM_UNSPECIFIED
:
742 find_option (&opp
->common
, opp
->delim
, opp
->delim_len
,
743 delim_opt
, "Bad DELIM parameter in OPEN statement");
745 flags
.pad
= !(cf
& IOPARM_OPEN_HAS_PAD
) ? PAD_UNSPECIFIED
:
746 find_option (&opp
->common
, opp
->pad
, opp
->pad_len
,
747 pad_opt
, "Bad PAD parameter in OPEN statement");
749 flags
.decimal
= !(cf
& IOPARM_OPEN_HAS_DECIMAL
) ? DECIMAL_UNSPECIFIED
:
750 find_option (&opp
->common
, opp
->decimal
, opp
->decimal_len
,
751 decimal_opt
, "Bad DECIMAL parameter in OPEN statement");
753 flags
.encoding
= !(cf
& IOPARM_OPEN_HAS_ENCODING
) ? ENCODING_UNSPECIFIED
:
754 find_option (&opp
->common
, opp
->encoding
, opp
->encoding_len
,
755 encoding_opt
, "Bad ENCODING parameter in OPEN statement");
757 flags
.async
= !(cf
& IOPARM_OPEN_HAS_ASYNCHRONOUS
) ? ASYNC_UNSPECIFIED
:
758 find_option (&opp
->common
, opp
->asynchronous
, opp
->asynchronous_len
,
759 async_opt
, "Bad ASYNCHRONOUS parameter in OPEN statement");
761 flags
.round
= !(cf
& IOPARM_OPEN_HAS_ROUND
) ? ROUND_UNSPECIFIED
:
762 find_option (&opp
->common
, opp
->round
, opp
->round_len
,
763 round_opt
, "Bad ROUND parameter in OPEN statement");
765 flags
.sign
= !(cf
& IOPARM_OPEN_HAS_SIGN
) ? SIGN_UNSPECIFIED
:
766 find_option (&opp
->common
, opp
->sign
, opp
->sign_len
,
767 sign_opt
, "Bad SIGN parameter in OPEN statement");
769 flags
.form
= !(cf
& IOPARM_OPEN_HAS_FORM
) ? FORM_UNSPECIFIED
:
770 find_option (&opp
->common
, opp
->form
, opp
->form_len
,
771 form_opt
, "Bad FORM parameter in OPEN statement");
773 flags
.position
= !(cf
& IOPARM_OPEN_HAS_POSITION
) ? POSITION_UNSPECIFIED
:
774 find_option (&opp
->common
, opp
->position
, opp
->position_len
,
775 position_opt
, "Bad POSITION parameter in OPEN statement");
777 flags
.status
= !(cf
& IOPARM_OPEN_HAS_STATUS
) ? STATUS_UNSPECIFIED
:
778 find_option (&opp
->common
, opp
->status
, opp
->status_len
,
779 status_opt
, "Bad STATUS parameter in OPEN statement");
781 /* First, we check wether the convert flag has been set via environment
782 variable. This overrides the convert tag in the open statement. */
784 conv
= get_unformatted_convert (opp
->common
.unit
);
786 if (conv
== GFC_CONVERT_NONE
)
788 /* Nothing has been set by environment variable, check the convert tag. */
789 if (cf
& IOPARM_OPEN_HAS_CONVERT
)
790 conv
= find_option (&opp
->common
, opp
->convert
, opp
->convert_len
,
792 "Bad CONVERT parameter in OPEN statement");
794 conv
= compile_options
.convert
;
797 /* We use big_endian, which is 0 on little-endian machines
798 and 1 on big-endian machines. */
801 case GFC_CONVERT_NATIVE
:
802 case GFC_CONVERT_SWAP
:
805 case GFC_CONVERT_BIG
:
806 conv
= big_endian
? GFC_CONVERT_NATIVE
: GFC_CONVERT_SWAP
;
809 case GFC_CONVERT_LITTLE
:
810 conv
= big_endian
? GFC_CONVERT_SWAP
: GFC_CONVERT_NATIVE
;
814 internal_error (&opp
->common
, "Illegal value for CONVERT");
818 flags
.convert
= conv
;
820 if (!(opp
->common
.flags
& IOPARM_OPEN_HAS_NEWUNIT
) && opp
->common
.unit
< 0)
821 generate_error (&opp
->common
, LIBERROR_BAD_OPTION
,
822 "Bad unit number in OPEN statement");
824 if (flags
.position
!= POSITION_UNSPECIFIED
825 && flags
.access
== ACCESS_DIRECT
)
826 generate_error (&opp
->common
, LIBERROR_BAD_OPTION
,
827 "Cannot use POSITION with direct access files");
829 if (flags
.access
== ACCESS_APPEND
)
831 if (flags
.position
!= POSITION_UNSPECIFIED
832 && flags
.position
!= POSITION_APPEND
)
833 generate_error (&opp
->common
, LIBERROR_BAD_OPTION
,
834 "Conflicting ACCESS and POSITION flags in"
837 notify_std (&opp
->common
, GFC_STD_GNU
,
838 "Extension: APPEND as a value for ACCESS in OPEN statement");
839 flags
.access
= ACCESS_SEQUENTIAL
;
840 flags
.position
= POSITION_APPEND
;
843 if (flags
.position
== POSITION_UNSPECIFIED
)
844 flags
.position
= POSITION_ASIS
;
846 if ((opp
->common
.flags
& IOPARM_LIBRETURN_MASK
) == IOPARM_LIBRETURN_OK
)
848 if ((opp
->common
.flags
& IOPARM_OPEN_HAS_NEWUNIT
))
850 *opp
->newunit
= get_unique_unit_number(opp
);
851 opp
->common
.unit
= *opp
->newunit
;
854 u
= find_or_create_unit (opp
->common
.unit
);
857 u
= new_unit (opp
, u
, &flags
);
862 already_open (opp
, u
, &flags
);