1 /* Copyright (C) 2002, 2003, 2005, 2007, 2009 Free Software Foundation, Inc.
2 Contributed by Andy Vaught
4 This file is part of the GNU Fortran 95 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 */
32 static const char undefined
[] = "UNDEFINED";
35 /* inquire_via_unit()-- Inquiry via unit number. The unit might not exist. */
38 inquire_via_unit (st_parameter_inquire
*iqp
, gfc_unit
* u
)
41 GFC_INTEGER_4 cf
= iqp
->common
.flags
;
43 if ((cf
& IOPARM_INQUIRE_HAS_EXIST
) != 0)
45 *iqp
->exist
= (iqp
->common
.unit
>= 0
46 && iqp
->common
.unit
<= GFC_INTEGER_4_HUGE
);
48 if ((cf
& IOPARM_INQUIRE_HAS_FILE
) == 0)
51 *iqp
->common
.iostat
= LIBERROR_BAD_UNIT
;
52 *iqp
->exist
= *iqp
->exist
53 && (*iqp
->common
.iostat
!= LIBERROR_BAD_UNIT
);
57 if ((cf
& IOPARM_INQUIRE_HAS_OPENED
) != 0)
58 *iqp
->opened
= (u
!= NULL
);
60 if ((cf
& IOPARM_INQUIRE_HAS_NUMBER
) != 0)
61 *iqp
->number
= (u
!= NULL
) ? u
->unit_number
: -1;
63 if ((cf
& IOPARM_INQUIRE_HAS_NAMED
) != 0)
64 *iqp
->named
= (u
!= NULL
&& u
->flags
.status
!= STATUS_SCRATCH
);
66 if ((cf
& IOPARM_INQUIRE_HAS_NAME
) != 0
67 && u
!= NULL
&& u
->flags
.status
!= STATUS_SCRATCH
)
68 fstrcpy (iqp
->name
, iqp
->name_len
, u
->file
, u
->file_len
);
70 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
75 switch (u
->flags
.access
)
77 case ACCESS_SEQUENTIAL
:
87 internal_error (&iqp
->common
, "inquire_via_unit(): Bad access");
90 cf_strcpy (iqp
->access
, iqp
->access_len
, p
);
93 if ((cf
& IOPARM_INQUIRE_HAS_SEQUENTIAL
) != 0)
96 p
= inquire_sequential (NULL
, 0);
98 switch (u
->flags
.access
)
104 case ACCESS_SEQUENTIAL
:
108 internal_error (&iqp
->common
, "inquire_via_unit(): Bad access");
111 cf_strcpy (iqp
->sequential
, iqp
->sequential_len
, p
);
114 if ((cf
& IOPARM_INQUIRE_HAS_DIRECT
) != 0)
117 p
= inquire_direct (NULL
, 0);
119 switch (u
->flags
.access
)
121 case ACCESS_SEQUENTIAL
:
129 internal_error (&iqp
->common
, "inquire_via_unit(): Bad access");
132 cf_strcpy (iqp
->direct
, iqp
->direct_len
, p
);
135 if ((cf
& IOPARM_INQUIRE_HAS_FORM
) != 0)
140 switch (u
->flags
.form
)
145 case FORM_UNFORMATTED
:
149 internal_error (&iqp
->common
, "inquire_via_unit(): Bad form");
152 cf_strcpy (iqp
->form
, iqp
->form_len
, p
);
155 if ((cf
& IOPARM_INQUIRE_HAS_FORMATTED
) != 0)
158 p
= inquire_formatted (NULL
, 0);
160 switch (u
->flags
.form
)
165 case FORM_UNFORMATTED
:
169 internal_error (&iqp
->common
, "inquire_via_unit(): Bad form");
172 cf_strcpy (iqp
->formatted
, iqp
->formatted_len
, p
);
175 if ((cf
& IOPARM_INQUIRE_HAS_UNFORMATTED
) != 0)
178 p
= inquire_unformatted (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
->unformatted
, iqp
->unformatted_len
, p
);
195 if ((cf
& IOPARM_INQUIRE_HAS_RECL_OUT
) != 0)
196 *iqp
->recl_out
= (u
!= NULL
) ? u
->recl
: 0;
198 if ((cf
& IOPARM_INQUIRE_HAS_STRM_POS_OUT
) != 0)
199 *iqp
->strm_pos_out
= (u
!= NULL
) ? u
->strm_pos
: 0;
201 if ((cf
& IOPARM_INQUIRE_HAS_NEXTREC
) != 0)
203 /* This only makes sense in the context of DIRECT access. */
204 if (u
!= NULL
&& u
->flags
.access
== ACCESS_DIRECT
)
205 *iqp
->nextrec
= u
->last_record
+ 1;
210 if ((cf
& IOPARM_INQUIRE_HAS_BLANK
) != 0)
212 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
215 switch (u
->flags
.blank
)
224 internal_error (&iqp
->common
, "inquire_via_unit(): Bad blank");
227 cf_strcpy (iqp
->blank
, iqp
->blank_len
, p
);
230 if ((cf
& IOPARM_INQUIRE_HAS_PAD
) != 0)
232 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
235 switch (u
->flags
.pad
)
244 internal_error (&iqp
->common
, "inquire_via_unit(): Bad pad");
247 cf_strcpy (iqp
->pad
, iqp
->pad_len
, p
);
250 if (cf
& IOPARM_INQUIRE_HAS_FLAGS2
)
252 GFC_INTEGER_4 cf2
= iqp
->flags2
;
254 if ((cf2
& IOPARM_INQUIRE_HAS_PENDING
) != 0)
257 if ((cf2
& IOPARM_INQUIRE_HAS_ID
) != 0)
260 if ((cf2
& IOPARM_INQUIRE_HAS_ENCODING
) != 0)
262 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
265 switch (u
->flags
.encoding
)
267 case ENCODING_DEFAULT
:
274 internal_error (&iqp
->common
, "inquire_via_unit(): Bad encoding");
277 cf_strcpy (iqp
->encoding
, iqp
->encoding_len
, p
);
280 if ((cf2
& IOPARM_INQUIRE_HAS_DECIMAL
) != 0)
282 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
285 switch (u
->flags
.decimal
)
294 internal_error (&iqp
->common
, "inquire_via_unit(): Bad comma");
297 cf_strcpy (iqp
->decimal
, iqp
->decimal_len
, p
);
300 if ((cf2
& IOPARM_INQUIRE_HAS_ASYNCHRONOUS
) != 0)
305 switch (u
->flags
.async
)
314 internal_error (&iqp
->common
, "inquire_via_unit(): Bad async");
317 cf_strcpy (iqp
->asynchronous
, iqp
->asynchronous_len
, p
);
320 if ((cf2
& IOPARM_INQUIRE_HAS_SIGN
) != 0)
325 switch (u
->flags
.sign
)
327 case SIGN_PROCDEFINED
:
328 p
= "PROCESSOR_DEFINED";
337 internal_error (&iqp
->common
, "inquire_via_unit(): Bad sign");
340 cf_strcpy (iqp
->sign
, iqp
->sign_len
, p
);
343 if ((cf2
& IOPARM_INQUIRE_HAS_ROUND
) != 0)
348 switch (u
->flags
.round
)
362 case ROUND_COMPATIBLE
:
365 case ROUND_PROCDEFINED
:
366 p
= "PROCESSOR_DEFINED";
369 internal_error (&iqp
->common
, "inquire_via_unit(): Bad round");
372 cf_strcpy (iqp
->round
, iqp
->round_len
, p
);
376 if ((cf
& IOPARM_INQUIRE_HAS_POSITION
) != 0)
378 if (u
== NULL
|| u
->flags
.access
== ACCESS_DIRECT
)
381 switch (u
->flags
.position
)
383 case POSITION_REWIND
:
386 case POSITION_APPEND
:
393 /* if not direct access, it must be
394 either REWIND, APPEND, or ASIS.
395 ASIS seems to be the best default */
399 cf_strcpy (iqp
->position
, iqp
->position_len
, p
);
402 if ((cf
& IOPARM_INQUIRE_HAS_ACTION
) != 0)
407 switch (u
->flags
.action
)
415 case ACTION_READWRITE
:
419 internal_error (&iqp
->common
, "inquire_via_unit(): Bad action");
422 cf_strcpy (iqp
->action
, iqp
->action_len
, p
);
425 if ((cf
& IOPARM_INQUIRE_HAS_READ
) != 0)
427 p
= (u
== NULL
) ? inquire_read (NULL
, 0) :
428 inquire_read (u
->file
, u
->file_len
);
430 cf_strcpy (iqp
->read
, iqp
->read_len
, p
);
433 if ((cf
& IOPARM_INQUIRE_HAS_WRITE
) != 0)
435 p
= (u
== NULL
) ? inquire_write (NULL
, 0) :
436 inquire_write (u
->file
, u
->file_len
);
438 cf_strcpy (iqp
->write
, iqp
->write_len
, p
);
441 if ((cf
& IOPARM_INQUIRE_HAS_READWRITE
) != 0)
443 p
= (u
== NULL
) ? inquire_readwrite (NULL
, 0) :
444 inquire_readwrite (u
->file
, u
->file_len
);
446 cf_strcpy (iqp
->readwrite
, iqp
->readwrite_len
, p
);
449 if ((cf
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
451 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
454 switch (u
->flags
.delim
)
462 case DELIM_APOSTROPHE
:
466 internal_error (&iqp
->common
, "inquire_via_unit(): Bad delim");
469 cf_strcpy (iqp
->delim
, iqp
->delim_len
, p
);
472 if ((cf
& IOPARM_INQUIRE_HAS_PAD
) != 0)
474 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
477 switch (u
->flags
.pad
)
486 internal_error (&iqp
->common
, "inquire_via_unit(): Bad pad");
489 cf_strcpy (iqp
->pad
, iqp
->pad_len
, p
);
492 if ((cf
& IOPARM_INQUIRE_HAS_CONVERT
) != 0)
497 switch (u
->flags
.convert
)
499 /* big_endian is 0 for little-endian, 1 for big-endian. */
500 case GFC_CONVERT_NATIVE
:
501 p
= big_endian
? "BIG_ENDIAN" : "LITTLE_ENDIAN";
504 case GFC_CONVERT_SWAP
:
505 p
= big_endian
? "LITTLE_ENDIAN" : "BIG_ENDIAN";
509 internal_error (&iqp
->common
, "inquire_via_unit(): Bad convert");
512 cf_strcpy (iqp
->convert
, iqp
->convert_len
, p
);
517 /* inquire_via_filename()-- Inquiry via filename. This subroutine is
518 * only used if the filename is *not* connected to a unit number. */
521 inquire_via_filename (st_parameter_inquire
*iqp
)
524 GFC_INTEGER_4 cf
= iqp
->common
.flags
;
526 if ((cf
& IOPARM_INQUIRE_HAS_EXIST
) != 0)
527 *iqp
->exist
= file_exists (iqp
->file
, iqp
->file_len
);
529 if ((cf
& IOPARM_INQUIRE_HAS_OPENED
) != 0)
532 if ((cf
& IOPARM_INQUIRE_HAS_NUMBER
) != 0)
535 if ((cf
& IOPARM_INQUIRE_HAS_NAMED
) != 0)
538 if ((cf
& IOPARM_INQUIRE_HAS_NAME
) != 0)
539 fstrcpy (iqp
->name
, iqp
->name_len
, iqp
->file
, iqp
->file_len
);
541 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
542 cf_strcpy (iqp
->access
, iqp
->access_len
, undefined
);
544 if ((cf
& IOPARM_INQUIRE_HAS_SEQUENTIAL
) != 0)
547 cf_strcpy (iqp
->sequential
, iqp
->sequential_len
, p
);
550 if ((cf
& IOPARM_INQUIRE_HAS_DIRECT
) != 0)
553 cf_strcpy (iqp
->direct
, iqp
->direct_len
, p
);
556 if ((cf
& IOPARM_INQUIRE_HAS_FORM
) != 0)
557 cf_strcpy (iqp
->form
, iqp
->form_len
, undefined
);
559 if ((cf
& IOPARM_INQUIRE_HAS_FORMATTED
) != 0)
562 cf_strcpy (iqp
->formatted
, iqp
->formatted_len
, p
);
565 if ((cf
& IOPARM_INQUIRE_HAS_UNFORMATTED
) != 0)
568 cf_strcpy (iqp
->unformatted
, iqp
->unformatted_len
, p
);
571 if ((cf
& IOPARM_INQUIRE_HAS_RECL_OUT
) != 0)
574 if ((cf
& IOPARM_INQUIRE_HAS_NEXTREC
) != 0)
577 if ((cf
& IOPARM_INQUIRE_HAS_BLANK
) != 0)
578 cf_strcpy (iqp
->blank
, iqp
->blank_len
, undefined
);
580 if ((cf
& IOPARM_INQUIRE_HAS_PAD
) != 0)
581 cf_strcpy (iqp
->pad
, iqp
->pad_len
, undefined
);
583 if (cf
& IOPARM_INQUIRE_HAS_FLAGS2
)
585 GFC_INTEGER_4 cf2
= iqp
->flags2
;
587 if ((cf2
& IOPARM_INQUIRE_HAS_ENCODING
) != 0)
588 cf_strcpy (iqp
->encoding
, iqp
->encoding_len
, undefined
);
590 if ((cf2
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
591 cf_strcpy (iqp
->delim
, iqp
->delim_len
, undefined
);
593 if ((cf2
& IOPARM_INQUIRE_HAS_DECIMAL
) != 0)
594 cf_strcpy (iqp
->decimal
, iqp
->decimal_len
, undefined
);
596 if ((cf2
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
597 cf_strcpy (iqp
->delim
, iqp
->delim_len
, undefined
);
599 if ((cf2
& IOPARM_INQUIRE_HAS_PAD
) != 0)
600 cf_strcpy (iqp
->pad
, iqp
->pad_len
, undefined
);
602 if ((cf2
& IOPARM_INQUIRE_HAS_ENCODING
) != 0)
603 cf_strcpy (iqp
->encoding
, iqp
->encoding_len
, undefined
);
606 if ((cf
& IOPARM_INQUIRE_HAS_POSITION
) != 0)
607 cf_strcpy (iqp
->position
, iqp
->position_len
, undefined
);
609 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
610 cf_strcpy (iqp
->access
, iqp
->access_len
, undefined
);
612 if ((cf
& IOPARM_INQUIRE_HAS_READ
) != 0)
614 p
= inquire_read (iqp
->file
, iqp
->file_len
);
615 cf_strcpy (iqp
->read
, iqp
->read_len
, p
);
618 if ((cf
& IOPARM_INQUIRE_HAS_WRITE
) != 0)
620 p
= inquire_write (iqp
->file
, iqp
->file_len
);
621 cf_strcpy (iqp
->write
, iqp
->write_len
, p
);
624 if ((cf
& IOPARM_INQUIRE_HAS_READWRITE
) != 0)
626 p
= inquire_read (iqp
->file
, iqp
->file_len
);
627 cf_strcpy (iqp
->readwrite
, iqp
->readwrite_len
, p
);
632 /* Library entry point for the INQUIRE statement (non-IOLENGTH
635 extern void st_inquire (st_parameter_inquire
*);
636 export_proto(st_inquire
);
639 st_inquire (st_parameter_inquire
*iqp
)
643 library_start (&iqp
->common
);
645 if ((iqp
->common
.flags
& IOPARM_INQUIRE_HAS_FILE
) == 0)
647 u
= find_unit (iqp
->common
.unit
);
648 inquire_via_unit (iqp
, u
);
652 u
= find_file (iqp
->file
, iqp
->file_len
);
654 inquire_via_filename (iqp
);
656 inquire_via_unit (iqp
, u
);