1 /* Copyright (C) 2002, 2003, 2005, 2007, 2009, 2010, 2011
2 Free Software Foundation, Inc.
3 Contributed by Andy Vaught
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/>. */
27 /* Implement the non-IOLENGTH variant of the INQUIRY statement */
34 static const char undefined
[] = "UNDEFINED";
37 /* inquire_via_unit()-- Inquiry via unit number. The unit might not exist. */
40 inquire_via_unit (st_parameter_inquire
*iqp
, gfc_unit
* u
)
43 GFC_INTEGER_4 cf
= iqp
->common
.flags
;
45 if ((cf
& IOPARM_INQUIRE_HAS_EXIST
) != 0)
47 *iqp
->exist
= (iqp
->common
.unit
>= 0
48 && iqp
->common
.unit
<= GFC_INTEGER_4_HUGE
);
50 if ((cf
& IOPARM_INQUIRE_HAS_FILE
) == 0)
53 *iqp
->common
.iostat
= LIBERROR_BAD_UNIT
;
54 *iqp
->exist
= *iqp
->exist
55 && (*iqp
->common
.iostat
!= LIBERROR_BAD_UNIT
);
59 if ((cf
& IOPARM_INQUIRE_HAS_OPENED
) != 0)
60 *iqp
->opened
= (u
!= NULL
);
62 if ((cf
& IOPARM_INQUIRE_HAS_NUMBER
) != 0)
63 *iqp
->number
= (u
!= NULL
) ? u
->unit_number
: -1;
65 if ((cf
& IOPARM_INQUIRE_HAS_NAMED
) != 0)
66 *iqp
->named
= (u
!= NULL
&& u
->flags
.status
!= STATUS_SCRATCH
);
68 if ((cf
& IOPARM_INQUIRE_HAS_NAME
) != 0
69 && u
!= NULL
&& u
->flags
.status
!= STATUS_SCRATCH
)
71 #if defined(HAVE_TTYNAME_R) || defined(HAVE_TTYNAME)
72 if (u
->unit_number
== options
.stdin_unit
73 || u
->unit_number
== options
.stdout_unit
74 || u
->unit_number
== options
.stderr_unit
)
76 int err
= stream_ttyname (u
->s
, iqp
->name
, iqp
->name_len
);
79 gfc_charlen_type tmplen
= strlen (iqp
->name
);
80 if (iqp
->name_len
> tmplen
)
81 memset (&iqp
->name
[tmplen
], ' ', iqp
->name_len
- tmplen
);
83 else /* If ttyname does not work, go with the default. */
84 fstrcpy (iqp
->name
, iqp
->name_len
, u
->file
, u
->file_len
);
87 fstrcpy (iqp
->name
, iqp
->name_len
, u
->file
, u
->file_len
);
88 #elif defined __MINGW32__
89 if (u
->unit_number
== options
.stdin_unit
)
90 fstrcpy (iqp
->name
, iqp
->name_len
, "CONIN$", sizeof("CONIN$"));
91 else if (u
->unit_number
== options
.stdout_unit
)
92 fstrcpy (iqp
->name
, iqp
->name_len
, "CONOUT$", sizeof("CONOUT$"));
93 else if (u
->unit_number
== options
.stderr_unit
)
94 fstrcpy (iqp
->name
, iqp
->name_len
, "CONERR$", sizeof("CONERR$"));
96 fstrcpy (iqp
->name
, iqp
->name_len
, u
->file
, u
->file_len
);
98 fstrcpy (iqp
->name
, iqp
->name_len
, u
->file
, u
->file_len
);
102 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
107 switch (u
->flags
.access
)
109 case ACCESS_SEQUENTIAL
:
119 internal_error (&iqp
->common
, "inquire_via_unit(): Bad access");
122 cf_strcpy (iqp
->access
, iqp
->access_len
, p
);
125 if ((cf
& IOPARM_INQUIRE_HAS_SEQUENTIAL
) != 0)
128 p
= inquire_sequential (NULL
, 0);
130 switch (u
->flags
.access
)
136 case ACCESS_SEQUENTIAL
:
140 internal_error (&iqp
->common
, "inquire_via_unit(): Bad access");
143 cf_strcpy (iqp
->sequential
, iqp
->sequential_len
, p
);
146 if ((cf
& IOPARM_INQUIRE_HAS_DIRECT
) != 0)
149 p
= inquire_direct (NULL
, 0);
151 switch (u
->flags
.access
)
153 case ACCESS_SEQUENTIAL
:
161 internal_error (&iqp
->common
, "inquire_via_unit(): Bad access");
164 cf_strcpy (iqp
->direct
, iqp
->direct_len
, p
);
167 if ((cf
& IOPARM_INQUIRE_HAS_FORM
) != 0)
172 switch (u
->flags
.form
)
177 case FORM_UNFORMATTED
:
181 internal_error (&iqp
->common
, "inquire_via_unit(): Bad form");
184 cf_strcpy (iqp
->form
, iqp
->form_len
, p
);
187 if ((cf
& IOPARM_INQUIRE_HAS_FORMATTED
) != 0)
190 p
= inquire_formatted (NULL
, 0);
192 switch (u
->flags
.form
)
197 case FORM_UNFORMATTED
:
201 internal_error (&iqp
->common
, "inquire_via_unit(): Bad form");
204 cf_strcpy (iqp
->formatted
, iqp
->formatted_len
, p
);
207 if ((cf
& IOPARM_INQUIRE_HAS_UNFORMATTED
) != 0)
210 p
= inquire_unformatted (NULL
, 0);
212 switch (u
->flags
.form
)
217 case FORM_UNFORMATTED
:
221 internal_error (&iqp
->common
, "inquire_via_unit(): Bad form");
224 cf_strcpy (iqp
->unformatted
, iqp
->unformatted_len
, p
);
227 if ((cf
& IOPARM_INQUIRE_HAS_RECL_OUT
) != 0)
228 *iqp
->recl_out
= (u
!= NULL
) ? u
->recl
: 0;
230 if ((cf
& IOPARM_INQUIRE_HAS_STRM_POS_OUT
) != 0)
231 *iqp
->strm_pos_out
= (u
!= NULL
) ? u
->strm_pos
: 0;
233 if ((cf
& IOPARM_INQUIRE_HAS_NEXTREC
) != 0)
235 /* This only makes sense in the context of DIRECT access. */
236 if (u
!= NULL
&& u
->flags
.access
== ACCESS_DIRECT
)
237 *iqp
->nextrec
= u
->last_record
+ 1;
242 if ((cf
& IOPARM_INQUIRE_HAS_BLANK
) != 0)
244 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
247 switch (u
->flags
.blank
)
256 internal_error (&iqp
->common
, "inquire_via_unit(): Bad blank");
259 cf_strcpy (iqp
->blank
, iqp
->blank_len
, p
);
262 if ((cf
& IOPARM_INQUIRE_HAS_PAD
) != 0)
264 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
267 switch (u
->flags
.pad
)
276 internal_error (&iqp
->common
, "inquire_via_unit(): Bad pad");
279 cf_strcpy (iqp
->pad
, iqp
->pad_len
, p
);
282 if (cf
& IOPARM_INQUIRE_HAS_FLAGS2
)
284 GFC_INTEGER_4 cf2
= iqp
->flags2
;
286 if ((cf2
& IOPARM_INQUIRE_HAS_PENDING
) != 0)
289 if ((cf2
& IOPARM_INQUIRE_HAS_ID
) != 0)
292 if ((cf2
& IOPARM_INQUIRE_HAS_ENCODING
) != 0)
294 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
297 switch (u
->flags
.encoding
)
299 case ENCODING_DEFAULT
:
306 internal_error (&iqp
->common
, "inquire_via_unit(): Bad encoding");
309 cf_strcpy (iqp
->encoding
, iqp
->encoding_len
, p
);
312 if ((cf2
& IOPARM_INQUIRE_HAS_DECIMAL
) != 0)
314 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
317 switch (u
->flags
.decimal
)
326 internal_error (&iqp
->common
, "inquire_via_unit(): Bad comma");
329 cf_strcpy (iqp
->decimal
, iqp
->decimal_len
, p
);
332 if ((cf2
& IOPARM_INQUIRE_HAS_ASYNCHRONOUS
) != 0)
337 switch (u
->flags
.async
)
346 internal_error (&iqp
->common
, "inquire_via_unit(): Bad async");
349 cf_strcpy (iqp
->asynchronous
, iqp
->asynchronous_len
, p
);
352 if ((cf2
& IOPARM_INQUIRE_HAS_SIGN
) != 0)
357 switch (u
->flags
.sign
)
359 case SIGN_PROCDEFINED
:
360 p
= "PROCESSOR_DEFINED";
369 internal_error (&iqp
->common
, "inquire_via_unit(): Bad sign");
372 cf_strcpy (iqp
->sign
, iqp
->sign_len
, p
);
375 if ((cf2
& IOPARM_INQUIRE_HAS_ROUND
) != 0)
380 switch (u
->flags
.round
)
394 case ROUND_COMPATIBLE
:
397 case ROUND_PROCDEFINED
:
398 p
= "PROCESSOR_DEFINED";
401 internal_error (&iqp
->common
, "inquire_via_unit(): Bad round");
404 cf_strcpy (iqp
->round
, iqp
->round_len
, p
);
407 if ((cf2
& IOPARM_INQUIRE_HAS_SIZE
) != 0)
414 *iqp
->size
= ssize (u
->s
);
419 if ((cf
& IOPARM_INQUIRE_HAS_POSITION
) != 0)
421 if (u
== NULL
|| u
->flags
.access
== ACCESS_DIRECT
)
425 /* If the position is unspecified, check if we can figure
426 out whether it's at the beginning or end. */
427 if (u
->flags
.position
== POSITION_UNSPECIFIED
)
429 gfc_offset cur
= stell (u
->s
);
431 u
->flags
.position
= POSITION_REWIND
;
432 else if (cur
!= -1 && (ssize (u
->s
) == cur
))
433 u
->flags
.position
= POSITION_APPEND
;
435 switch (u
->flags
.position
)
437 case POSITION_REWIND
:
440 case POSITION_APPEND
:
447 /* If the position has changed and is not rewind or
448 append, it must be set to a processor-dependent
454 cf_strcpy (iqp
->position
, iqp
->position_len
, p
);
457 if ((cf
& IOPARM_INQUIRE_HAS_ACTION
) != 0)
462 switch (u
->flags
.action
)
470 case ACTION_READWRITE
:
474 internal_error (&iqp
->common
, "inquire_via_unit(): Bad action");
477 cf_strcpy (iqp
->action
, iqp
->action_len
, p
);
480 if ((cf
& IOPARM_INQUIRE_HAS_READ
) != 0)
482 p
= (u
== NULL
) ? inquire_read (NULL
, 0) :
483 inquire_read (u
->file
, u
->file_len
);
485 cf_strcpy (iqp
->read
, iqp
->read_len
, p
);
488 if ((cf
& IOPARM_INQUIRE_HAS_WRITE
) != 0)
490 p
= (u
== NULL
) ? inquire_write (NULL
, 0) :
491 inquire_write (u
->file
, u
->file_len
);
493 cf_strcpy (iqp
->write
, iqp
->write_len
, p
);
496 if ((cf
& IOPARM_INQUIRE_HAS_READWRITE
) != 0)
498 p
= (u
== NULL
) ? inquire_readwrite (NULL
, 0) :
499 inquire_readwrite (u
->file
, u
->file_len
);
501 cf_strcpy (iqp
->readwrite
, iqp
->readwrite_len
, p
);
504 if ((cf
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
506 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
509 switch (u
->flags
.delim
)
517 case DELIM_APOSTROPHE
:
521 internal_error (&iqp
->common
, "inquire_via_unit(): Bad delim");
524 cf_strcpy (iqp
->delim
, iqp
->delim_len
, p
);
527 if ((cf
& IOPARM_INQUIRE_HAS_PAD
) != 0)
529 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
532 switch (u
->flags
.pad
)
541 internal_error (&iqp
->common
, "inquire_via_unit(): Bad pad");
544 cf_strcpy (iqp
->pad
, iqp
->pad_len
, p
);
547 if ((cf
& IOPARM_INQUIRE_HAS_CONVERT
) != 0)
552 switch (u
->flags
.convert
)
554 /* big_endian is 0 for little-endian, 1 for big-endian. */
555 case GFC_CONVERT_NATIVE
:
556 p
= big_endian
? "BIG_ENDIAN" : "LITTLE_ENDIAN";
559 case GFC_CONVERT_SWAP
:
560 p
= big_endian
? "LITTLE_ENDIAN" : "BIG_ENDIAN";
564 internal_error (&iqp
->common
, "inquire_via_unit(): Bad convert");
567 cf_strcpy (iqp
->convert
, iqp
->convert_len
, p
);
572 /* inquire_via_filename()-- Inquiry via filename. This subroutine is
573 * only used if the filename is *not* connected to a unit number. */
576 inquire_via_filename (st_parameter_inquire
*iqp
)
579 GFC_INTEGER_4 cf
= iqp
->common
.flags
;
581 if ((cf
& IOPARM_INQUIRE_HAS_EXIST
) != 0)
582 *iqp
->exist
= file_exists (iqp
->file
, iqp
->file_len
);
584 if ((cf
& IOPARM_INQUIRE_HAS_OPENED
) != 0)
587 if ((cf
& IOPARM_INQUIRE_HAS_NUMBER
) != 0)
590 if ((cf
& IOPARM_INQUIRE_HAS_NAMED
) != 0)
593 if ((cf
& IOPARM_INQUIRE_HAS_NAME
) != 0)
594 fstrcpy (iqp
->name
, iqp
->name_len
, iqp
->file
, iqp
->file_len
);
596 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
597 cf_strcpy (iqp
->access
, iqp
->access_len
, undefined
);
599 if ((cf
& IOPARM_INQUIRE_HAS_SEQUENTIAL
) != 0)
602 cf_strcpy (iqp
->sequential
, iqp
->sequential_len
, p
);
605 if ((cf
& IOPARM_INQUIRE_HAS_DIRECT
) != 0)
608 cf_strcpy (iqp
->direct
, iqp
->direct_len
, p
);
611 if ((cf
& IOPARM_INQUIRE_HAS_FORM
) != 0)
612 cf_strcpy (iqp
->form
, iqp
->form_len
, undefined
);
614 if ((cf
& IOPARM_INQUIRE_HAS_FORMATTED
) != 0)
617 cf_strcpy (iqp
->formatted
, iqp
->formatted_len
, p
);
620 if ((cf
& IOPARM_INQUIRE_HAS_UNFORMATTED
) != 0)
623 cf_strcpy (iqp
->unformatted
, iqp
->unformatted_len
, p
);
626 if ((cf
& IOPARM_INQUIRE_HAS_RECL_OUT
) != 0)
629 if ((cf
& IOPARM_INQUIRE_HAS_NEXTREC
) != 0)
632 if ((cf
& IOPARM_INQUIRE_HAS_BLANK
) != 0)
633 cf_strcpy (iqp
->blank
, iqp
->blank_len
, undefined
);
635 if ((cf
& IOPARM_INQUIRE_HAS_PAD
) != 0)
636 cf_strcpy (iqp
->pad
, iqp
->pad_len
, undefined
);
638 if (cf
& IOPARM_INQUIRE_HAS_FLAGS2
)
640 GFC_INTEGER_4 cf2
= iqp
->flags2
;
642 if ((cf2
& IOPARM_INQUIRE_HAS_ENCODING
) != 0)
643 cf_strcpy (iqp
->encoding
, iqp
->encoding_len
, undefined
);
645 if ((cf2
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
646 cf_strcpy (iqp
->delim
, iqp
->delim_len
, undefined
);
648 if ((cf2
& IOPARM_INQUIRE_HAS_DECIMAL
) != 0)
649 cf_strcpy (iqp
->decimal
, iqp
->decimal_len
, undefined
);
651 if ((cf2
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
652 cf_strcpy (iqp
->delim
, iqp
->delim_len
, undefined
);
654 if ((cf2
& IOPARM_INQUIRE_HAS_PAD
) != 0)
655 cf_strcpy (iqp
->pad
, iqp
->pad_len
, undefined
);
657 if ((cf2
& IOPARM_INQUIRE_HAS_ENCODING
) != 0)
658 cf_strcpy (iqp
->encoding
, iqp
->encoding_len
, undefined
);
660 if ((cf2
& IOPARM_INQUIRE_HAS_SIZE
) != 0)
661 *iqp
->size
= file_size (iqp
->file
, iqp
->file_len
);
664 if ((cf
& IOPARM_INQUIRE_HAS_POSITION
) != 0)
665 cf_strcpy (iqp
->position
, iqp
->position_len
, undefined
);
667 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
668 cf_strcpy (iqp
->access
, iqp
->access_len
, undefined
);
670 if ((cf
& IOPARM_INQUIRE_HAS_READ
) != 0)
672 p
= inquire_read (iqp
->file
, iqp
->file_len
);
673 cf_strcpy (iqp
->read
, iqp
->read_len
, p
);
676 if ((cf
& IOPARM_INQUIRE_HAS_WRITE
) != 0)
678 p
= inquire_write (iqp
->file
, iqp
->file_len
);
679 cf_strcpy (iqp
->write
, iqp
->write_len
, p
);
682 if ((cf
& IOPARM_INQUIRE_HAS_READWRITE
) != 0)
684 p
= inquire_read (iqp
->file
, iqp
->file_len
);
685 cf_strcpy (iqp
->readwrite
, iqp
->readwrite_len
, p
);
690 /* Library entry point for the INQUIRE statement (non-IOLENGTH
693 extern void st_inquire (st_parameter_inquire
*);
694 export_proto(st_inquire
);
697 st_inquire (st_parameter_inquire
*iqp
)
701 library_start (&iqp
->common
);
703 if ((iqp
->common
.flags
& IOPARM_INQUIRE_HAS_FILE
) == 0)
705 u
= find_unit (iqp
->common
.unit
);
706 inquire_via_unit (iqp
, u
);
710 u
= find_file (iqp
->file
, iqp
->file_len
);
712 inquire_via_filename (iqp
);
714 inquire_via_unit (iqp
, u
);