1 /* Copyright (C) 2002, 2003, 2005, 2007 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 2, or (at your option)
11 In addition to the permissions in the GNU General Public License, the
12 Free Software Foundation gives you unlimited permission to link the
13 compiled version of this file into combinations with other programs,
14 and to distribute those combinations without any restriction coming
15 from the use of this file. (The General Public License restrictions
16 do apply in other respects; for example, they cover modification of
17 the file, and distribution when not linked into a combine
20 Libgfortran is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with Libgfortran; see the file COPYING. If not, write to
27 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
28 Boston, MA 02110-1301, USA. */
31 /* Implement the non-IOLENGTH variant of the INQUIRY statement */
36 static const char undefined
[] = "UNDEFINED";
39 /* inquire_via_unit()-- Inquiry via unit number. The unit might not exist. */
42 inquire_via_unit (st_parameter_inquire
*iqp
, gfc_unit
* u
)
45 GFC_INTEGER_4 cf
= iqp
->common
.flags
;
46 GFC_INTEGER_4 cf2
= iqp
->flags2
;
48 if ((cf
& IOPARM_INQUIRE_HAS_EXIST
) != 0)
50 *iqp
->exist
= (iqp
->common
.unit
>= 0
51 && iqp
->common
.unit
<= GFC_INTEGER_4_HUGE
);
53 if ((cf
& IOPARM_INQUIRE_HAS_FILE
) == 0)
56 *iqp
->common
.iostat
= LIBERROR_BAD_UNIT
;
57 *iqp
->exist
= *iqp
->exist
58 && (*iqp
->common
.iostat
!= LIBERROR_BAD_UNIT
);
62 if ((cf
& IOPARM_INQUIRE_HAS_OPENED
) != 0)
63 *iqp
->opened
= (u
!= NULL
);
65 if ((cf
& IOPARM_INQUIRE_HAS_NUMBER
) != 0)
66 *iqp
->number
= (u
!= NULL
) ? u
->unit_number
: -1;
68 if ((cf
& IOPARM_INQUIRE_HAS_NAMED
) != 0)
69 *iqp
->named
= (u
!= NULL
&& u
->flags
.status
!= STATUS_SCRATCH
);
71 if ((cf
& IOPARM_INQUIRE_HAS_NAME
) != 0
72 && u
!= NULL
&& u
->flags
.status
!= STATUS_SCRATCH
)
73 fstrcpy (iqp
->name
, iqp
->name_len
, u
->file
, u
->file_len
);
75 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
80 switch (u
->flags
.access
)
82 case ACCESS_SEQUENTIAL
:
92 internal_error (&iqp
->common
, "inquire_via_unit(): Bad access");
95 cf_strcpy (iqp
->access
, iqp
->access_len
, p
);
98 if ((cf
& IOPARM_INQUIRE_HAS_SEQUENTIAL
) != 0)
101 p
= inquire_sequential (NULL
, 0);
103 switch (u
->flags
.access
)
109 case ACCESS_SEQUENTIAL
:
113 internal_error (&iqp
->common
, "inquire_via_unit(): Bad access");
116 cf_strcpy (iqp
->sequential
, iqp
->sequential_len
, p
);
119 if ((cf
& IOPARM_INQUIRE_HAS_DIRECT
) != 0)
122 p
= inquire_direct (NULL
, 0);
124 switch (u
->flags
.access
)
126 case ACCESS_SEQUENTIAL
:
134 internal_error (&iqp
->common
, "inquire_via_unit(): Bad access");
137 cf_strcpy (iqp
->direct
, iqp
->direct_len
, p
);
140 if ((cf
& IOPARM_INQUIRE_HAS_FORM
) != 0)
145 switch (u
->flags
.form
)
150 case FORM_UNFORMATTED
:
154 internal_error (&iqp
->common
, "inquire_via_unit(): Bad form");
157 cf_strcpy (iqp
->form
, iqp
->form_len
, p
);
160 if ((cf
& IOPARM_INQUIRE_HAS_FORMATTED
) != 0)
163 p
= inquire_formatted (NULL
, 0);
165 switch (u
->flags
.form
)
170 case FORM_UNFORMATTED
:
174 internal_error (&iqp
->common
, "inquire_via_unit(): Bad form");
177 cf_strcpy (iqp
->formatted
, iqp
->formatted_len
, p
);
180 if ((cf
& IOPARM_INQUIRE_HAS_UNFORMATTED
) != 0)
183 p
= inquire_unformatted (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
->unformatted
, iqp
->unformatted_len
, p
);
200 if ((cf
& IOPARM_INQUIRE_HAS_RECL_OUT
) != 0)
201 *iqp
->recl_out
= (u
!= NULL
) ? u
->recl
: 0;
203 if ((cf
& IOPARM_INQUIRE_HAS_STRM_POS_OUT
) != 0)
204 *iqp
->strm_pos_out
= (u
!= NULL
) ? u
->strm_pos
: 0;
206 if ((cf
& IOPARM_INQUIRE_HAS_NEXTREC
) != 0)
208 /* This only makes sense in the context of DIRECT access. */
209 if (u
!= NULL
&& u
->flags
.access
== ACCESS_DIRECT
)
210 *iqp
->nextrec
= u
->last_record
+ 1;
215 if ((cf
& IOPARM_INQUIRE_HAS_BLANK
) != 0)
217 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
220 switch (u
->flags
.blank
)
229 internal_error (&iqp
->common
, "inquire_via_unit(): Bad blank");
232 cf_strcpy (iqp
->blank
, iqp
->blank_len
, p
);
235 if ((cf
& IOPARM_INQUIRE_HAS_PAD
) != 0)
237 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
240 switch (u
->flags
.pad
)
249 internal_error (&iqp
->common
, "inquire_via_unit(): Bad pad");
252 cf_strcpy (iqp
->pad
, iqp
->pad_len
, p
);
255 if (cf
& IOPARM_INQUIRE_HAS_FLAGS2
)
257 if ((cf2
& IOPARM_INQUIRE_HAS_PENDING
) != 0)
260 if ((cf2
& IOPARM_INQUIRE_HAS_ID
) != 0)
263 if ((cf2
& IOPARM_INQUIRE_HAS_ENCODING
) != 0)
265 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
268 switch (u
->flags
.encoding
)
270 case ENCODING_DEFAULT
:
277 internal_error (&iqp
->common
, "inquire_via_unit(): Bad encoding");
280 cf_strcpy (iqp
->encoding
, iqp
->encoding_len
, p
);
283 if ((cf2
& IOPARM_INQUIRE_HAS_DECIMAL
) != 0)
285 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
288 switch (u
->flags
.decimal
)
297 internal_error (&iqp
->common
, "inquire_via_unit(): Bad comma");
300 cf_strcpy (iqp
->decimal
, iqp
->decimal_len
, p
);
303 if ((cf2
& IOPARM_INQUIRE_HAS_ASYNCHRONOUS
) != 0)
308 switch (u
->flags
.async
)
317 internal_error (&iqp
->common
, "inquire_via_unit(): Bad async");
320 cf_strcpy (iqp
->asynchronous
, iqp
->asynchronous_len
, p
);
323 if ((cf2
& IOPARM_INQUIRE_HAS_SIGN
) != 0)
328 switch (u
->flags
.sign
)
330 case SIGN_PROCDEFINED
:
331 p
= "PROCESSOR_DEFINED";
340 internal_error (&iqp
->common
, "inquire_via_unit(): Bad sign");
343 cf_strcpy (iqp
->sign
, iqp
->sign_len
, p
);
346 if ((cf2
& IOPARM_INQUIRE_HAS_ROUND
) != 0)
351 switch (u
->flags
.round
)
365 case ROUND_COMPATIBLE
:
368 case ROUND_PROCDEFINED
:
369 p
= "PROCESSOR_DEFINED";
372 internal_error (&iqp
->common
, "inquire_via_unit(): Bad round");
375 cf_strcpy (iqp
->round
, iqp
->round_len
, p
);
379 if ((cf
& IOPARM_INQUIRE_HAS_POSITION
) != 0)
381 if (u
== NULL
|| u
->flags
.access
== ACCESS_DIRECT
)
384 switch (u
->flags
.position
)
386 case POSITION_REWIND
:
389 case POSITION_APPEND
:
396 /* if not direct access, it must be
397 either REWIND, APPEND, or ASIS.
398 ASIS seems to be the best default */
402 cf_strcpy (iqp
->position
, iqp
->position_len
, p
);
405 if ((cf
& IOPARM_INQUIRE_HAS_ACTION
) != 0)
410 switch (u
->flags
.action
)
418 case ACTION_READWRITE
:
422 internal_error (&iqp
->common
, "inquire_via_unit(): Bad action");
425 cf_strcpy (iqp
->action
, iqp
->action_len
, p
);
428 if ((cf
& IOPARM_INQUIRE_HAS_READ
) != 0)
430 p
= (u
== NULL
) ? inquire_read (NULL
, 0) :
431 inquire_read (u
->file
, u
->file_len
);
433 cf_strcpy (iqp
->read
, iqp
->read_len
, p
);
436 if ((cf
& IOPARM_INQUIRE_HAS_WRITE
) != 0)
438 p
= (u
== NULL
) ? inquire_write (NULL
, 0) :
439 inquire_write (u
->file
, u
->file_len
);
441 cf_strcpy (iqp
->write
, iqp
->write_len
, p
);
444 if ((cf
& IOPARM_INQUIRE_HAS_READWRITE
) != 0)
446 p
= (u
== NULL
) ? inquire_readwrite (NULL
, 0) :
447 inquire_readwrite (u
->file
, u
->file_len
);
449 cf_strcpy (iqp
->readwrite
, iqp
->readwrite_len
, p
);
452 if ((cf
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
454 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
457 switch (u
->flags
.delim
)
465 case DELIM_APOSTROPHE
:
469 internal_error (&iqp
->common
, "inquire_via_unit(): Bad delim");
472 cf_strcpy (iqp
->delim
, iqp
->delim_len
, p
);
475 if ((cf
& IOPARM_INQUIRE_HAS_PAD
) != 0)
477 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
480 switch (u
->flags
.pad
)
489 internal_error (&iqp
->common
, "inquire_via_unit(): Bad pad");
492 cf_strcpy (iqp
->pad
, iqp
->pad_len
, p
);
495 if ((cf
& IOPARM_INQUIRE_HAS_CONVERT
) != 0)
500 switch (u
->flags
.convert
)
502 /* big_endian is 0 for little-endian, 1 for big-endian. */
503 case GFC_CONVERT_NATIVE
:
504 p
= big_endian
? "BIG_ENDIAN" : "LITTLE_ENDIAN";
507 case GFC_CONVERT_SWAP
:
508 p
= big_endian
? "LITTLE_ENDIAN" : "BIG_ENDIAN";
512 internal_error (&iqp
->common
, "inquire_via_unit(): Bad convert");
515 cf_strcpy (iqp
->convert
, iqp
->convert_len
, p
);
520 /* inquire_via_filename()-- Inquiry via filename. This subroutine is
521 * only used if the filename is *not* connected to a unit number. */
524 inquire_via_filename (st_parameter_inquire
*iqp
)
527 GFC_INTEGER_4 cf
= iqp
->common
.flags
;
528 GFC_INTEGER_4 cf2
= iqp
->flags2
;
530 if ((cf
& IOPARM_INQUIRE_HAS_EXIST
) != 0)
531 *iqp
->exist
= file_exists (iqp
->file
, iqp
->file_len
);
533 if ((cf
& IOPARM_INQUIRE_HAS_OPENED
) != 0)
536 if ((cf
& IOPARM_INQUIRE_HAS_NUMBER
) != 0)
539 if ((cf
& IOPARM_INQUIRE_HAS_NAMED
) != 0)
542 if ((cf
& IOPARM_INQUIRE_HAS_NAME
) != 0)
543 fstrcpy (iqp
->name
, iqp
->name_len
, iqp
->file
, iqp
->file_len
);
545 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
546 cf_strcpy (iqp
->access
, iqp
->access_len
, undefined
);
548 if ((cf
& IOPARM_INQUIRE_HAS_SEQUENTIAL
) != 0)
551 cf_strcpy (iqp
->sequential
, iqp
->sequential_len
, p
);
554 if ((cf
& IOPARM_INQUIRE_HAS_DIRECT
) != 0)
557 cf_strcpy (iqp
->direct
, iqp
->direct_len
, p
);
560 if ((cf
& IOPARM_INQUIRE_HAS_FORM
) != 0)
561 cf_strcpy (iqp
->form
, iqp
->form_len
, undefined
);
563 if ((cf
& IOPARM_INQUIRE_HAS_FORMATTED
) != 0)
566 cf_strcpy (iqp
->formatted
, iqp
->formatted_len
, p
);
569 if ((cf
& IOPARM_INQUIRE_HAS_UNFORMATTED
) != 0)
572 cf_strcpy (iqp
->unformatted
, iqp
->unformatted_len
, p
);
575 if ((cf
& IOPARM_INQUIRE_HAS_RECL_OUT
) != 0)
578 if ((cf
& IOPARM_INQUIRE_HAS_NEXTREC
) != 0)
581 if ((cf
& IOPARM_INQUIRE_HAS_BLANK
) != 0)
582 cf_strcpy (iqp
->blank
, iqp
->blank_len
, undefined
);
584 if ((cf
& IOPARM_INQUIRE_HAS_PAD
) != 0)
585 cf_strcpy (iqp
->pad
, iqp
->pad_len
, undefined
);
587 if (cf
& IOPARM_INQUIRE_HAS_FLAGS2
)
589 if ((cf2
& IOPARM_INQUIRE_HAS_ENCODING
) != 0)
590 cf_strcpy (iqp
->encoding
, iqp
->encoding_len
, undefined
);
592 if ((cf2
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
593 cf_strcpy (iqp
->delim
, iqp
->delim_len
, undefined
);
595 if ((cf2
& IOPARM_INQUIRE_HAS_DECIMAL
) != 0)
596 cf_strcpy (iqp
->decimal
, iqp
->decimal_len
, undefined
);
598 if ((cf2
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
599 cf_strcpy (iqp
->delim
, iqp
->delim_len
, undefined
);
601 if ((cf2
& IOPARM_INQUIRE_HAS_PAD
) != 0)
602 cf_strcpy (iqp
->pad
, iqp
->pad_len
, undefined
);
604 if ((cf2
& IOPARM_INQUIRE_HAS_ENCODING
) != 0)
605 cf_strcpy (iqp
->encoding
, iqp
->encoding_len
, undefined
);
608 if ((cf
& IOPARM_INQUIRE_HAS_POSITION
) != 0)
609 cf_strcpy (iqp
->position
, iqp
->position_len
, undefined
);
611 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
612 cf_strcpy (iqp
->access
, iqp
->access_len
, undefined
);
614 if ((cf
& IOPARM_INQUIRE_HAS_READ
) != 0)
616 p
= inquire_read (iqp
->file
, iqp
->file_len
);
617 cf_strcpy (iqp
->read
, iqp
->read_len
, p
);
620 if ((cf
& IOPARM_INQUIRE_HAS_WRITE
) != 0)
622 p
= inquire_write (iqp
->file
, iqp
->file_len
);
623 cf_strcpy (iqp
->write
, iqp
->write_len
, p
);
626 if ((cf
& IOPARM_INQUIRE_HAS_READWRITE
) != 0)
628 p
= inquire_read (iqp
->file
, iqp
->file_len
);
629 cf_strcpy (iqp
->readwrite
, iqp
->readwrite_len
, p
);
634 /* Library entry point for the INQUIRE statement (non-IOLENGTH
637 extern void st_inquire (st_parameter_inquire
*);
638 export_proto(st_inquire
);
641 st_inquire (st_parameter_inquire
*iqp
)
645 library_start (&iqp
->common
);
647 if ((iqp
->common
.flags
& IOPARM_INQUIRE_HAS_FILE
) == 0)
649 u
= find_unit (iqp
->common
.unit
);
650 inquire_via_unit (iqp
, u
);
654 u
= find_file (iqp
->file
, iqp
->file_len
);
656 inquire_via_filename (iqp
);
658 inquire_via_unit (iqp
, u
);