1 /* Copyright (C) 2002-2017 Free Software Foundation, Inc.
2 Contributed by Andy Vaught
4 This file is part of the GNU Fortran runtime library (libgfortran).
6 Libgfortran is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 Libgfortran is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 Under Section 7 of GPL version 3, you are granted additional
17 permissions described in the GCC Runtime Library Exception, version
18 3.1, as published by the Free Software Foundation.
20 You should have received a copy of the GNU General Public License and
21 a copy of the GCC Runtime Library Exception along with this program;
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 <http://www.gnu.org/licenses/>. */
26 /* Implement the non-IOLENGTH variant of the INQUIRY statement */
33 static const char yes
[] = "YES", no
[] = "NO", undefined
[] = "UNDEFINED";
36 /* inquire_via_unit()-- Inquiry via unit number. The unit might not exist. */
39 inquire_via_unit (st_parameter_inquire
*iqp
, gfc_unit
*u
)
42 GFC_INTEGER_4 cf
= iqp
->common
.flags
;
44 if (iqp
->common
.unit
== GFC_INTERNAL_UNIT
||
45 iqp
->common
.unit
== GFC_INTERNAL_UNIT4
||
46 (u
!= NULL
&& u
->internal_unit_kind
!= 0))
47 generate_error (&iqp
->common
, LIBERROR_INQUIRE_INTERNAL_UNIT
, NULL
);
49 if ((cf
& IOPARM_INQUIRE_HAS_EXIST
) != 0)
50 *iqp
->exist
= (u
!= NULL
) || (iqp
->common
.unit
>= 0);
52 if ((cf
& IOPARM_INQUIRE_HAS_OPENED
) != 0)
53 *iqp
->opened
= (u
!= NULL
);
55 if ((cf
& IOPARM_INQUIRE_HAS_NUMBER
) != 0)
56 *iqp
->number
= (u
!= NULL
) ? u
->unit_number
: -1;
58 if ((cf
& IOPARM_INQUIRE_HAS_NAMED
) != 0)
59 *iqp
->named
= (u
!= NULL
&& u
->flags
.status
!= STATUS_SCRATCH
);
61 if ((cf
& IOPARM_INQUIRE_HAS_NAME
) != 0
62 && u
!= NULL
&& u
->flags
.status
!= STATUS_SCRATCH
)
64 #if defined(HAVE_TTYNAME_R) || defined(HAVE_TTYNAME)
65 if (u
->unit_number
== options
.stdin_unit
66 || u
->unit_number
== options
.stdout_unit
67 || u
->unit_number
== options
.stderr_unit
)
69 int err
= stream_ttyname (u
->s
, iqp
->name
, iqp
->name_len
);
72 gfc_charlen_type tmplen
= strlen (iqp
->name
);
73 if (iqp
->name_len
> tmplen
)
74 memset (&iqp
->name
[tmplen
], ' ', iqp
->name_len
- tmplen
);
76 else /* If ttyname does not work, go with the default. */
77 cf_strcpy (iqp
->name
, iqp
->name_len
, u
->filename
);
80 cf_strcpy (iqp
->name
, iqp
->name_len
, u
->filename
);
81 #elif defined __MINGW32__
82 if (u
->unit_number
== options
.stdin_unit
)
83 fstrcpy (iqp
->name
, iqp
->name_len
, "CONIN$", sizeof("CONIN$"));
84 else if (u
->unit_number
== options
.stdout_unit
)
85 fstrcpy (iqp
->name
, iqp
->name_len
, "CONOUT$", sizeof("CONOUT$"));
86 else if (u
->unit_number
== options
.stderr_unit
)
87 fstrcpy (iqp
->name
, iqp
->name_len
, "CONERR$", sizeof("CONERR$"));
89 cf_strcpy (iqp
->name
, iqp
->name_len
, u
->filename
);
91 cf_strcpy (iqp
->name
, iqp
->name_len
, u
->filename
);
95 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
100 switch (u
->flags
.access
)
102 case ACCESS_SEQUENTIAL
:
112 internal_error (&iqp
->common
, "inquire_via_unit(): Bad access");
115 cf_strcpy (iqp
->access
, iqp
->access_len
, p
);
118 if ((cf
& IOPARM_INQUIRE_HAS_SEQUENTIAL
) != 0)
121 p
= inquire_sequential (NULL
, 0);
123 switch (u
->flags
.access
)
129 case ACCESS_SEQUENTIAL
:
133 internal_error (&iqp
->common
, "inquire_via_unit(): Bad access");
136 cf_strcpy (iqp
->sequential
, iqp
->sequential_len
, p
);
139 if ((cf
& IOPARM_INQUIRE_HAS_DIRECT
) != 0)
142 p
= inquire_direct (NULL
, 0);
144 switch (u
->flags
.access
)
146 case ACCESS_SEQUENTIAL
:
154 internal_error (&iqp
->common
, "inquire_via_unit(): Bad access");
157 cf_strcpy (iqp
->direct
, iqp
->direct_len
, p
);
160 if ((cf
& IOPARM_INQUIRE_HAS_FORM
) != 0)
165 switch (u
->flags
.form
)
170 case FORM_UNFORMATTED
:
174 internal_error (&iqp
->common
, "inquire_via_unit(): Bad form");
177 cf_strcpy (iqp
->form
, iqp
->form_len
, p
);
180 if ((cf
& IOPARM_INQUIRE_HAS_FORMATTED
) != 0)
183 p
= inquire_formatted (NULL
, 0);
185 switch (u
->flags
.form
)
190 case FORM_UNFORMATTED
:
194 internal_error (&iqp
->common
, "inquire_via_unit(): Bad form");
197 cf_strcpy (iqp
->formatted
, iqp
->formatted_len
, p
);
200 if ((cf
& IOPARM_INQUIRE_HAS_UNFORMATTED
) != 0)
203 p
= inquire_unformatted (NULL
, 0);
205 switch (u
->flags
.form
)
210 case FORM_UNFORMATTED
:
214 internal_error (&iqp
->common
, "inquire_via_unit(): Bad form");
217 cf_strcpy (iqp
->unformatted
, iqp
->unformatted_len
, p
);
220 if ((cf
& IOPARM_INQUIRE_HAS_RECL_OUT
) != 0)
221 /* F2018 (N2137) 12.10.2.26: If there is no connection, recl is
222 assigned the value -1. */
223 *iqp
->recl_out
= (u
!= NULL
) ? u
->recl
: -1;
225 if ((cf
& IOPARM_INQUIRE_HAS_STRM_POS_OUT
) != 0)
226 *iqp
->strm_pos_out
= (u
!= NULL
) ? u
->strm_pos
: 0;
228 if ((cf
& IOPARM_INQUIRE_HAS_NEXTREC
) != 0)
230 /* This only makes sense in the context of DIRECT access. */
231 if (u
!= NULL
&& u
->flags
.access
== ACCESS_DIRECT
)
232 *iqp
->nextrec
= u
->last_record
+ 1;
237 if ((cf
& IOPARM_INQUIRE_HAS_BLANK
) != 0)
239 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
242 switch (u
->flags
.blank
)
251 internal_error (&iqp
->common
, "inquire_via_unit(): Bad blank");
254 cf_strcpy (iqp
->blank
, iqp
->blank_len
, p
);
257 if ((cf
& IOPARM_INQUIRE_HAS_PAD
) != 0)
259 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
262 switch (u
->flags
.pad
)
271 internal_error (&iqp
->common
, "inquire_via_unit(): Bad pad");
274 cf_strcpy (iqp
->pad
, iqp
->pad_len
, p
);
277 if (cf
& IOPARM_INQUIRE_HAS_FLAGS2
)
279 GFC_INTEGER_4 cf2
= iqp
->flags2
;
281 if ((cf2
& IOPARM_INQUIRE_HAS_PENDING
) != 0)
284 if ((cf2
& IOPARM_INQUIRE_HAS_ID
) != 0)
287 if ((cf2
& IOPARM_INQUIRE_HAS_ENCODING
) != 0)
289 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
292 switch (u
->flags
.encoding
)
294 case ENCODING_DEFAULT
:
301 internal_error (&iqp
->common
, "inquire_via_unit(): Bad encoding");
304 cf_strcpy (iqp
->encoding
, iqp
->encoding_len
, p
);
307 if ((cf2
& IOPARM_INQUIRE_HAS_DECIMAL
) != 0)
309 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
312 switch (u
->flags
.decimal
)
321 internal_error (&iqp
->common
, "inquire_via_unit(): Bad comma");
324 cf_strcpy (iqp
->decimal
, iqp
->decimal_len
, p
);
327 if ((cf2
& IOPARM_INQUIRE_HAS_ASYNCHRONOUS
) != 0)
332 switch (u
->flags
.async
)
341 internal_error (&iqp
->common
, "inquire_via_unit(): Bad async");
344 cf_strcpy (iqp
->asynchronous
, iqp
->asynchronous_len
, p
);
347 if ((cf2
& IOPARM_INQUIRE_HAS_SIGN
) != 0)
352 switch (u
->flags
.sign
)
354 case SIGN_PROCDEFINED
:
355 p
= "PROCESSOR_DEFINED";
364 internal_error (&iqp
->common
, "inquire_via_unit(): Bad sign");
367 cf_strcpy (iqp
->sign
, iqp
->sign_len
, p
);
370 if ((cf2
& IOPARM_INQUIRE_HAS_ROUND
) != 0)
375 switch (u
->flags
.round
)
389 case ROUND_COMPATIBLE
:
392 case ROUND_PROCDEFINED
:
393 p
= "PROCESSOR_DEFINED";
396 internal_error (&iqp
->common
, "inquire_via_unit(): Bad round");
399 cf_strcpy (iqp
->round
, iqp
->round_len
, p
);
402 if ((cf2
& IOPARM_INQUIRE_HAS_SIZE
) != 0)
409 *iqp
->size
= ssize (u
->s
);
413 if ((cf2
& IOPARM_INQUIRE_HAS_IQSTREAM
) != 0)
418 switch (u
->flags
.access
)
420 case ACCESS_SEQUENTIAL
:
428 internal_error (&iqp
->common
, "inquire_via_unit(): Bad pad");
431 cf_strcpy (iqp
->iqstream
, iqp
->iqstream_len
, p
);
434 if ((cf2
& IOPARM_INQUIRE_HAS_SHARE
) != 0)
439 switch (u
->flags
.share
)
447 case SHARE_UNSPECIFIED
:
451 internal_error (&iqp
->common
,
452 "inquire_via_unit(): Bad share");
456 cf_strcpy (iqp
->share
, iqp
->share_len
, p
);
459 if ((cf2
& IOPARM_INQUIRE_HAS_CC
) != 0)
479 internal_error (&iqp
->common
, "inquire_via_unit(): Bad cc");
483 cf_strcpy (iqp
->cc
, iqp
->cc_len
, p
);
487 if ((cf
& IOPARM_INQUIRE_HAS_POSITION
) != 0)
489 if (u
== NULL
|| u
->flags
.access
== ACCESS_DIRECT
)
493 /* If the position is unspecified, check if we can figure
494 out whether it's at the beginning or end. */
495 if (u
->flags
.position
== POSITION_UNSPECIFIED
)
497 gfc_offset cur
= stell (u
->s
);
499 u
->flags
.position
= POSITION_REWIND
;
500 else if (cur
!= -1 && (ssize (u
->s
) == cur
))
501 u
->flags
.position
= POSITION_APPEND
;
503 switch (u
->flags
.position
)
505 case POSITION_REWIND
:
508 case POSITION_APPEND
:
515 /* If the position has changed and is not rewind or
516 append, it must be set to a processor-dependent
522 cf_strcpy (iqp
->position
, iqp
->position_len
, p
);
525 if ((cf
& IOPARM_INQUIRE_HAS_ACTION
) != 0)
530 switch (u
->flags
.action
)
538 case ACTION_READWRITE
:
542 internal_error (&iqp
->common
, "inquire_via_unit(): Bad action");
545 cf_strcpy (iqp
->action
, iqp
->action_len
, p
);
548 if ((cf
& IOPARM_INQUIRE_HAS_READ
) != 0)
550 p
= (!u
|| u
->flags
.action
== ACTION_WRITE
) ? no
: yes
;
551 cf_strcpy (iqp
->read
, iqp
->read_len
, p
);
554 if ((cf
& IOPARM_INQUIRE_HAS_WRITE
) != 0)
556 p
= (!u
|| u
->flags
.action
== ACTION_READ
) ? no
: yes
;
557 cf_strcpy (iqp
->write
, iqp
->write_len
, p
);
560 if ((cf
& IOPARM_INQUIRE_HAS_READWRITE
) != 0)
562 p
= (!u
|| u
->flags
.action
!= ACTION_READWRITE
) ? no
: yes
;
563 cf_strcpy (iqp
->readwrite
, iqp
->readwrite_len
, p
);
566 if ((cf
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
568 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
571 switch (u
->flags
.delim
)
574 case DELIM_UNSPECIFIED
:
580 case DELIM_APOSTROPHE
:
584 internal_error (&iqp
->common
, "inquire_via_unit(): Bad delim");
587 cf_strcpy (iqp
->delim
, iqp
->delim_len
, p
);
590 if ((cf
& IOPARM_INQUIRE_HAS_PAD
) != 0)
592 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
595 switch (u
->flags
.pad
)
604 internal_error (&iqp
->common
, "inquire_via_unit(): Bad pad");
607 cf_strcpy (iqp
->pad
, iqp
->pad_len
, p
);
610 if ((cf
& IOPARM_INQUIRE_HAS_CONVERT
) != 0)
615 switch (u
->flags
.convert
)
617 case GFC_CONVERT_NATIVE
:
618 p
= __BYTE_ORDER__
== __ORDER_BIG_ENDIAN__
? "BIG_ENDIAN" : "LITTLE_ENDIAN";
621 case GFC_CONVERT_SWAP
:
622 p
= __BYTE_ORDER__
== __ORDER_BIG_ENDIAN__
? "LITTLE_ENDIAN" : "BIG_ENDIAN";
626 internal_error (&iqp
->common
, "inquire_via_unit(): Bad convert");
629 cf_strcpy (iqp
->convert
, iqp
->convert_len
, p
);
634 /* inquire_via_filename()-- Inquiry via filename. This subroutine is
635 only used if the filename is *not* connected to a unit number. */
638 inquire_via_filename (st_parameter_inquire
*iqp
)
641 GFC_INTEGER_4 cf
= iqp
->common
.flags
;
643 if ((cf
& IOPARM_INQUIRE_HAS_EXIST
) != 0)
644 *iqp
->exist
= file_exists (iqp
->file
, iqp
->file_len
);
646 if ((cf
& IOPARM_INQUIRE_HAS_OPENED
) != 0)
649 if ((cf
& IOPARM_INQUIRE_HAS_NUMBER
) != 0)
652 if ((cf
& IOPARM_INQUIRE_HAS_NAMED
) != 0)
655 if ((cf
& IOPARM_INQUIRE_HAS_NAME
) != 0)
656 fstrcpy (iqp
->name
, iqp
->name_len
, iqp
->file
, iqp
->file_len
);
658 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
659 cf_strcpy (iqp
->access
, iqp
->access_len
, undefined
);
661 if ((cf
& IOPARM_INQUIRE_HAS_SEQUENTIAL
) != 0)
664 cf_strcpy (iqp
->sequential
, iqp
->sequential_len
, p
);
667 if ((cf
& IOPARM_INQUIRE_HAS_DIRECT
) != 0)
670 cf_strcpy (iqp
->direct
, iqp
->direct_len
, p
);
673 if ((cf
& IOPARM_INQUIRE_HAS_FORM
) != 0)
674 cf_strcpy (iqp
->form
, iqp
->form_len
, undefined
);
676 if ((cf
& IOPARM_INQUIRE_HAS_FORMATTED
) != 0)
679 cf_strcpy (iqp
->formatted
, iqp
->formatted_len
, p
);
682 if ((cf
& IOPARM_INQUIRE_HAS_UNFORMATTED
) != 0)
685 cf_strcpy (iqp
->unformatted
, iqp
->unformatted_len
, p
);
688 if ((cf
& IOPARM_INQUIRE_HAS_RECL_OUT
) != 0)
691 if ((cf
& IOPARM_INQUIRE_HAS_NEXTREC
) != 0)
694 if ((cf
& IOPARM_INQUIRE_HAS_BLANK
) != 0)
695 cf_strcpy (iqp
->blank
, iqp
->blank_len
, undefined
);
697 if ((cf
& IOPARM_INQUIRE_HAS_PAD
) != 0)
698 cf_strcpy (iqp
->pad
, iqp
->pad_len
, undefined
);
700 if (cf
& IOPARM_INQUIRE_HAS_FLAGS2
)
702 GFC_INTEGER_4 cf2
= iqp
->flags2
;
704 if ((cf2
& IOPARM_INQUIRE_HAS_ENCODING
) != 0)
705 cf_strcpy (iqp
->encoding
, iqp
->encoding_len
, undefined
);
707 if ((cf2
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
708 cf_strcpy (iqp
->delim
, iqp
->delim_len
, undefined
);
710 if ((cf2
& IOPARM_INQUIRE_HAS_DECIMAL
) != 0)
711 cf_strcpy (iqp
->decimal
, iqp
->decimal_len
, undefined
);
713 if ((cf2
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
714 cf_strcpy (iqp
->delim
, iqp
->delim_len
, undefined
);
716 if ((cf2
& IOPARM_INQUIRE_HAS_PAD
) != 0)
717 cf_strcpy (iqp
->pad
, iqp
->pad_len
, undefined
);
719 if ((cf2
& IOPARM_INQUIRE_HAS_ENCODING
) != 0)
720 cf_strcpy (iqp
->encoding
, iqp
->encoding_len
, undefined
);
722 if ((cf2
& IOPARM_INQUIRE_HAS_SIZE
) != 0)
723 *iqp
->size
= file_size (iqp
->file
, iqp
->file_len
);
725 if ((cf2
& IOPARM_INQUIRE_HAS_IQSTREAM
) != 0)
726 cf_strcpy (iqp
->iqstream
, iqp
->iqstream_len
, "UNKNOWN");
728 if ((cf2
& IOPARM_INQUIRE_HAS_SHARE
) != 0)
729 cf_strcpy (iqp
->share
, iqp
->share_len
, "UNKNOWN");
731 if ((cf2
& IOPARM_INQUIRE_HAS_CC
) != 0)
732 cf_strcpy (iqp
->cc
, iqp
->cc_len
, "UNKNOWN");
735 if ((cf
& IOPARM_INQUIRE_HAS_POSITION
) != 0)
736 cf_strcpy (iqp
->position
, iqp
->position_len
, undefined
);
738 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
739 cf_strcpy (iqp
->access
, iqp
->access_len
, undefined
);
741 if ((cf
& IOPARM_INQUIRE_HAS_READ
) != 0)
743 p
= inquire_read (iqp
->file
, iqp
->file_len
);
744 cf_strcpy (iqp
->read
, iqp
->read_len
, p
);
747 if ((cf
& IOPARM_INQUIRE_HAS_WRITE
) != 0)
749 p
= inquire_write (iqp
->file
, iqp
->file_len
);
750 cf_strcpy (iqp
->write
, iqp
->write_len
, p
);
753 if ((cf
& IOPARM_INQUIRE_HAS_READWRITE
) != 0)
755 p
= inquire_read (iqp
->file
, iqp
->file_len
);
756 cf_strcpy (iqp
->readwrite
, iqp
->readwrite_len
, p
);
761 /* Library entry point for the INQUIRE statement (non-IOLENGTH
764 extern void st_inquire (st_parameter_inquire
*);
765 export_proto(st_inquire
);
768 st_inquire (st_parameter_inquire
*iqp
)
772 library_start (&iqp
->common
);
774 if ((iqp
->common
.flags
& IOPARM_INQUIRE_HAS_FILE
) == 0)
776 u
= find_unit (iqp
->common
.unit
);
777 inquire_via_unit (iqp
, u
);
781 u
= find_file (iqp
->file
, iqp
->file_len
);
783 inquire_via_filename (iqp
);
785 inquire_via_unit (iqp
, u
);