1 /* Copyright (C) 2002, 2003, 2005, 2007, 2009, 2010
2 Free Software Foundation, Inc.
3 Contributed by Andy Vaught
5 This file is part of the GNU Fortran 95 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
)
72 if (u
->unit_number
== options
.stdin_unit
73 || u
->unit_number
== options
.stdout_unit
74 || u
->unit_number
== options
.stderr_unit
)
76 char * tmp
= ttyname (((unix_stream
*) u
->s
)->fd
);
79 int tmplen
= strlen (tmp
);
80 fstrcpy (iqp
->name
, iqp
->name_len
, tmp
, tmplen
);
82 else /* If ttyname does not work, go with the default. */
83 fstrcpy (iqp
->name
, iqp
->name_len
, u
->file
, u
->file_len
);
87 fstrcpy (iqp
->name
, iqp
->name_len
, u
->file
, u
->file_len
);
90 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
95 switch (u
->flags
.access
)
97 case ACCESS_SEQUENTIAL
:
107 internal_error (&iqp
->common
, "inquire_via_unit(): Bad access");
110 cf_strcpy (iqp
->access
, iqp
->access_len
, p
);
113 if ((cf
& IOPARM_INQUIRE_HAS_SEQUENTIAL
) != 0)
116 p
= inquire_sequential (NULL
, 0);
118 switch (u
->flags
.access
)
124 case ACCESS_SEQUENTIAL
:
128 internal_error (&iqp
->common
, "inquire_via_unit(): Bad access");
131 cf_strcpy (iqp
->sequential
, iqp
->sequential_len
, p
);
134 if ((cf
& IOPARM_INQUIRE_HAS_DIRECT
) != 0)
137 p
= inquire_direct (NULL
, 0);
139 switch (u
->flags
.access
)
141 case ACCESS_SEQUENTIAL
:
149 internal_error (&iqp
->common
, "inquire_via_unit(): Bad access");
152 cf_strcpy (iqp
->direct
, iqp
->direct_len
, p
);
155 if ((cf
& IOPARM_INQUIRE_HAS_FORM
) != 0)
160 switch (u
->flags
.form
)
165 case FORM_UNFORMATTED
:
169 internal_error (&iqp
->common
, "inquire_via_unit(): Bad form");
172 cf_strcpy (iqp
->form
, iqp
->form_len
, p
);
175 if ((cf
& IOPARM_INQUIRE_HAS_FORMATTED
) != 0)
178 p
= inquire_formatted (NULL
, 0);
180 switch (u
->flags
.form
)
185 case FORM_UNFORMATTED
:
189 internal_error (&iqp
->common
, "inquire_via_unit(): Bad form");
192 cf_strcpy (iqp
->formatted
, iqp
->formatted_len
, p
);
195 if ((cf
& IOPARM_INQUIRE_HAS_UNFORMATTED
) != 0)
198 p
= inquire_unformatted (NULL
, 0);
200 switch (u
->flags
.form
)
205 case FORM_UNFORMATTED
:
209 internal_error (&iqp
->common
, "inquire_via_unit(): Bad form");
212 cf_strcpy (iqp
->unformatted
, iqp
->unformatted_len
, p
);
215 if ((cf
& IOPARM_INQUIRE_HAS_RECL_OUT
) != 0)
216 *iqp
->recl_out
= (u
!= NULL
) ? u
->recl
: 0;
218 if ((cf
& IOPARM_INQUIRE_HAS_STRM_POS_OUT
) != 0)
219 *iqp
->strm_pos_out
= (u
!= NULL
) ? u
->strm_pos
: 0;
221 if ((cf
& IOPARM_INQUIRE_HAS_NEXTREC
) != 0)
223 /* This only makes sense in the context of DIRECT access. */
224 if (u
!= NULL
&& u
->flags
.access
== ACCESS_DIRECT
)
225 *iqp
->nextrec
= u
->last_record
+ 1;
230 if ((cf
& IOPARM_INQUIRE_HAS_BLANK
) != 0)
232 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
235 switch (u
->flags
.blank
)
244 internal_error (&iqp
->common
, "inquire_via_unit(): Bad blank");
247 cf_strcpy (iqp
->blank
, iqp
->blank_len
, p
);
250 if ((cf
& IOPARM_INQUIRE_HAS_PAD
) != 0)
252 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
255 switch (u
->flags
.pad
)
264 internal_error (&iqp
->common
, "inquire_via_unit(): Bad pad");
267 cf_strcpy (iqp
->pad
, iqp
->pad_len
, p
);
270 if (cf
& IOPARM_INQUIRE_HAS_FLAGS2
)
272 GFC_INTEGER_4 cf2
= iqp
->flags2
;
274 if ((cf2
& IOPARM_INQUIRE_HAS_PENDING
) != 0)
277 if ((cf2
& IOPARM_INQUIRE_HAS_ID
) != 0)
280 if ((cf2
& IOPARM_INQUIRE_HAS_ENCODING
) != 0)
282 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
285 switch (u
->flags
.encoding
)
287 case ENCODING_DEFAULT
:
294 internal_error (&iqp
->common
, "inquire_via_unit(): Bad encoding");
297 cf_strcpy (iqp
->encoding
, iqp
->encoding_len
, p
);
300 if ((cf2
& IOPARM_INQUIRE_HAS_DECIMAL
) != 0)
302 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
305 switch (u
->flags
.decimal
)
314 internal_error (&iqp
->common
, "inquire_via_unit(): Bad comma");
317 cf_strcpy (iqp
->decimal
, iqp
->decimal_len
, p
);
320 if ((cf2
& IOPARM_INQUIRE_HAS_ASYNCHRONOUS
) != 0)
325 switch (u
->flags
.async
)
334 internal_error (&iqp
->common
, "inquire_via_unit(): Bad async");
337 cf_strcpy (iqp
->asynchronous
, iqp
->asynchronous_len
, p
);
340 if ((cf2
& IOPARM_INQUIRE_HAS_SIGN
) != 0)
345 switch (u
->flags
.sign
)
347 case SIGN_PROCDEFINED
:
348 p
= "PROCESSOR_DEFINED";
357 internal_error (&iqp
->common
, "inquire_via_unit(): Bad sign");
360 cf_strcpy (iqp
->sign
, iqp
->sign_len
, p
);
363 if ((cf2
& IOPARM_INQUIRE_HAS_ROUND
) != 0)
368 switch (u
->flags
.round
)
382 case ROUND_COMPATIBLE
:
385 case ROUND_PROCDEFINED
:
386 p
= "PROCESSOR_DEFINED";
389 internal_error (&iqp
->common
, "inquire_via_unit(): Bad round");
392 cf_strcpy (iqp
->round
, iqp
->round_len
, p
);
395 if ((cf2
& IOPARM_INQUIRE_HAS_SIZE
) != 0)
400 *iqp
->size
= file_size (u
->file
, (gfc_charlen_type
) u
->file_len
);
404 if ((cf
& IOPARM_INQUIRE_HAS_POSITION
) != 0)
406 if (u
== NULL
|| u
->flags
.access
== ACCESS_DIRECT
)
409 switch (u
->flags
.position
)
411 case POSITION_REWIND
:
414 case POSITION_APPEND
:
421 /* if not direct access, it must be
422 either REWIND, APPEND, or ASIS.
423 ASIS seems to be the best default */
427 cf_strcpy (iqp
->position
, iqp
->position_len
, p
);
430 if ((cf
& IOPARM_INQUIRE_HAS_ACTION
) != 0)
435 switch (u
->flags
.action
)
443 case ACTION_READWRITE
:
447 internal_error (&iqp
->common
, "inquire_via_unit(): Bad action");
450 cf_strcpy (iqp
->action
, iqp
->action_len
, p
);
453 if ((cf
& IOPARM_INQUIRE_HAS_READ
) != 0)
455 p
= (u
== NULL
) ? inquire_read (NULL
, 0) :
456 inquire_read (u
->file
, u
->file_len
);
458 cf_strcpy (iqp
->read
, iqp
->read_len
, p
);
461 if ((cf
& IOPARM_INQUIRE_HAS_WRITE
) != 0)
463 p
= (u
== NULL
) ? inquire_write (NULL
, 0) :
464 inquire_write (u
->file
, u
->file_len
);
466 cf_strcpy (iqp
->write
, iqp
->write_len
, p
);
469 if ((cf
& IOPARM_INQUIRE_HAS_READWRITE
) != 0)
471 p
= (u
== NULL
) ? inquire_readwrite (NULL
, 0) :
472 inquire_readwrite (u
->file
, u
->file_len
);
474 cf_strcpy (iqp
->readwrite
, iqp
->readwrite_len
, p
);
477 if ((cf
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
479 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
482 switch (u
->flags
.delim
)
490 case DELIM_APOSTROPHE
:
494 internal_error (&iqp
->common
, "inquire_via_unit(): Bad delim");
497 cf_strcpy (iqp
->delim
, iqp
->delim_len
, p
);
500 if ((cf
& IOPARM_INQUIRE_HAS_PAD
) != 0)
502 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
505 switch (u
->flags
.pad
)
514 internal_error (&iqp
->common
, "inquire_via_unit(): Bad pad");
517 cf_strcpy (iqp
->pad
, iqp
->pad_len
, p
);
520 if ((cf
& IOPARM_INQUIRE_HAS_CONVERT
) != 0)
525 switch (u
->flags
.convert
)
527 /* big_endian is 0 for little-endian, 1 for big-endian. */
528 case GFC_CONVERT_NATIVE
:
529 p
= big_endian
? "BIG_ENDIAN" : "LITTLE_ENDIAN";
532 case GFC_CONVERT_SWAP
:
533 p
= big_endian
? "LITTLE_ENDIAN" : "BIG_ENDIAN";
537 internal_error (&iqp
->common
, "inquire_via_unit(): Bad convert");
540 cf_strcpy (iqp
->convert
, iqp
->convert_len
, p
);
545 /* inquire_via_filename()-- Inquiry via filename. This subroutine is
546 * only used if the filename is *not* connected to a unit number. */
549 inquire_via_filename (st_parameter_inquire
*iqp
)
552 GFC_INTEGER_4 cf
= iqp
->common
.flags
;
554 if ((cf
& IOPARM_INQUIRE_HAS_EXIST
) != 0)
555 *iqp
->exist
= file_exists (iqp
->file
, iqp
->file_len
);
557 if ((cf
& IOPARM_INQUIRE_HAS_OPENED
) != 0)
560 if ((cf
& IOPARM_INQUIRE_HAS_NUMBER
) != 0)
563 if ((cf
& IOPARM_INQUIRE_HAS_NAMED
) != 0)
566 if ((cf
& IOPARM_INQUIRE_HAS_NAME
) != 0)
567 fstrcpy (iqp
->name
, iqp
->name_len
, iqp
->file
, iqp
->file_len
);
569 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
570 cf_strcpy (iqp
->access
, iqp
->access_len
, undefined
);
572 if ((cf
& IOPARM_INQUIRE_HAS_SEQUENTIAL
) != 0)
575 cf_strcpy (iqp
->sequential
, iqp
->sequential_len
, p
);
578 if ((cf
& IOPARM_INQUIRE_HAS_DIRECT
) != 0)
581 cf_strcpy (iqp
->direct
, iqp
->direct_len
, p
);
584 if ((cf
& IOPARM_INQUIRE_HAS_FORM
) != 0)
585 cf_strcpy (iqp
->form
, iqp
->form_len
, undefined
);
587 if ((cf
& IOPARM_INQUIRE_HAS_FORMATTED
) != 0)
590 cf_strcpy (iqp
->formatted
, iqp
->formatted_len
, p
);
593 if ((cf
& IOPARM_INQUIRE_HAS_UNFORMATTED
) != 0)
596 cf_strcpy (iqp
->unformatted
, iqp
->unformatted_len
, p
);
599 if ((cf
& IOPARM_INQUIRE_HAS_RECL_OUT
) != 0)
602 if ((cf
& IOPARM_INQUIRE_HAS_NEXTREC
) != 0)
605 if ((cf
& IOPARM_INQUIRE_HAS_BLANK
) != 0)
606 cf_strcpy (iqp
->blank
, iqp
->blank_len
, undefined
);
608 if ((cf
& IOPARM_INQUIRE_HAS_PAD
) != 0)
609 cf_strcpy (iqp
->pad
, iqp
->pad_len
, undefined
);
611 if (cf
& IOPARM_INQUIRE_HAS_FLAGS2
)
613 GFC_INTEGER_4 cf2
= iqp
->flags2
;
615 if ((cf2
& IOPARM_INQUIRE_HAS_ENCODING
) != 0)
616 cf_strcpy (iqp
->encoding
, iqp
->encoding_len
, undefined
);
618 if ((cf2
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
619 cf_strcpy (iqp
->delim
, iqp
->delim_len
, undefined
);
621 if ((cf2
& IOPARM_INQUIRE_HAS_DECIMAL
) != 0)
622 cf_strcpy (iqp
->decimal
, iqp
->decimal_len
, undefined
);
624 if ((cf2
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
625 cf_strcpy (iqp
->delim
, iqp
->delim_len
, undefined
);
627 if ((cf2
& IOPARM_INQUIRE_HAS_PAD
) != 0)
628 cf_strcpy (iqp
->pad
, iqp
->pad_len
, undefined
);
630 if ((cf2
& IOPARM_INQUIRE_HAS_ENCODING
) != 0)
631 cf_strcpy (iqp
->encoding
, iqp
->encoding_len
, undefined
);
633 if ((cf2
& IOPARM_INQUIRE_HAS_SIZE
) != 0)
634 *iqp
->size
= file_size (iqp
->file
, iqp
->file_len
);
637 if ((cf
& IOPARM_INQUIRE_HAS_POSITION
) != 0)
638 cf_strcpy (iqp
->position
, iqp
->position_len
, undefined
);
640 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
641 cf_strcpy (iqp
->access
, iqp
->access_len
, undefined
);
643 if ((cf
& IOPARM_INQUIRE_HAS_READ
) != 0)
645 p
= inquire_read (iqp
->file
, iqp
->file_len
);
646 cf_strcpy (iqp
->read
, iqp
->read_len
, p
);
649 if ((cf
& IOPARM_INQUIRE_HAS_WRITE
) != 0)
651 p
= inquire_write (iqp
->file
, iqp
->file_len
);
652 cf_strcpy (iqp
->write
, iqp
->write_len
, p
);
655 if ((cf
& IOPARM_INQUIRE_HAS_READWRITE
) != 0)
657 p
= inquire_read (iqp
->file
, iqp
->file_len
);
658 cf_strcpy (iqp
->readwrite
, iqp
->readwrite_len
, p
);
663 /* Library entry point for the INQUIRE statement (non-IOLENGTH
666 extern void st_inquire (st_parameter_inquire
*);
667 export_proto(st_inquire
);
670 st_inquire (st_parameter_inquire
*iqp
)
674 library_start (&iqp
->common
);
676 if ((iqp
->common
.flags
& IOPARM_INQUIRE_HAS_FILE
) == 0)
678 u
= find_unit (iqp
->common
.unit
);
679 inquire_via_unit (iqp
, u
);
683 u
= find_file (iqp
->file
, iqp
->file_len
);
685 inquire_via_filename (iqp
);
687 inquire_via_unit (iqp
, u
);