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
;
47 if ((cf
& IOPARM_INQUIRE_HAS_EXIST
) != 0)
49 *iqp
->exist
= (iqp
->common
.unit
>= 0
50 && iqp
->common
.unit
<= GFC_INTEGER_4_HUGE
);
52 if ((cf
& IOPARM_INQUIRE_HAS_FILE
) == 0)
55 *iqp
->common
.iostat
= LIBERROR_BAD_UNIT
;
56 *iqp
->exist
= *iqp
->exist
57 && (*iqp
->common
.iostat
!= LIBERROR_BAD_UNIT
);
61 if ((cf
& IOPARM_INQUIRE_HAS_OPENED
) != 0)
62 *iqp
->opened
= (u
!= NULL
);
64 if ((cf
& IOPARM_INQUIRE_HAS_NUMBER
) != 0)
65 *iqp
->number
= (u
!= NULL
) ? u
->unit_number
: -1;
67 if ((cf
& IOPARM_INQUIRE_HAS_NAMED
) != 0)
68 *iqp
->named
= (u
!= NULL
&& u
->flags
.status
!= STATUS_SCRATCH
);
70 if ((cf
& IOPARM_INQUIRE_HAS_NAME
) != 0
71 && u
!= NULL
&& u
->flags
.status
!= STATUS_SCRATCH
)
72 fstrcpy (iqp
->name
, iqp
->name_len
, u
->file
, u
->file_len
);
74 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
79 switch (u
->flags
.access
)
81 case ACCESS_SEQUENTIAL
:
91 internal_error (&iqp
->common
, "inquire_via_unit(): Bad access");
94 cf_strcpy (iqp
->access
, iqp
->access_len
, p
);
97 if ((cf
& IOPARM_INQUIRE_HAS_SEQUENTIAL
) != 0)
100 p
= inquire_sequential (NULL
, 0);
102 switch (u
->flags
.access
)
108 case ACCESS_SEQUENTIAL
:
112 internal_error (&iqp
->common
, "inquire_via_unit(): Bad access");
115 cf_strcpy (iqp
->sequential
, iqp
->sequential_len
, p
);
118 if ((cf
& IOPARM_INQUIRE_HAS_DIRECT
) != 0)
121 p
= inquire_direct (NULL
, 0);
123 switch (u
->flags
.access
)
125 case ACCESS_SEQUENTIAL
:
133 internal_error (&iqp
->common
, "inquire_via_unit(): Bad access");
136 cf_strcpy (iqp
->direct
, iqp
->direct_len
, p
);
139 if ((cf
& IOPARM_INQUIRE_HAS_FORM
) != 0)
144 switch (u
->flags
.form
)
149 case FORM_UNFORMATTED
:
153 internal_error (&iqp
->common
, "inquire_via_unit(): Bad form");
156 cf_strcpy (iqp
->form
, iqp
->form_len
, p
);
159 if ((cf
& IOPARM_INQUIRE_HAS_FORMATTED
) != 0)
162 p
= inquire_formatted (NULL
, 0);
164 switch (u
->flags
.form
)
169 case FORM_UNFORMATTED
:
173 internal_error (&iqp
->common
, "inquire_via_unit(): Bad form");
176 cf_strcpy (iqp
->formatted
, iqp
->formatted_len
, p
);
179 if ((cf
& IOPARM_INQUIRE_HAS_UNFORMATTED
) != 0)
182 p
= inquire_unformatted (NULL
, 0);
184 switch (u
->flags
.form
)
189 case FORM_UNFORMATTED
:
193 internal_error (&iqp
->common
, "inquire_via_unit(): Bad form");
196 cf_strcpy (iqp
->unformatted
, iqp
->unformatted_len
, p
);
199 if ((cf
& IOPARM_INQUIRE_HAS_RECL_OUT
) != 0)
200 *iqp
->recl_out
= (u
!= NULL
) ? u
->recl
: 0;
202 if ((cf
& IOPARM_INQUIRE_HAS_STRM_POS_OUT
) != 0)
203 *iqp
->strm_pos_out
= (u
!= NULL
) ? u
->strm_pos
: 0;
205 if ((cf
& IOPARM_INQUIRE_HAS_NEXTREC
) != 0)
207 /* This only makes sense in the context of DIRECT access. */
208 if (u
!= NULL
&& u
->flags
.access
== ACCESS_DIRECT
)
209 *iqp
->nextrec
= u
->last_record
+ 1;
214 if ((cf
& IOPARM_INQUIRE_HAS_BLANK
) != 0)
216 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
219 switch (u
->flags
.blank
)
228 internal_error (&iqp
->common
, "inquire_via_unit(): Bad blank");
231 cf_strcpy (iqp
->blank
, iqp
->blank_len
, p
);
234 if ((cf
& IOPARM_INQUIRE_HAS_PAD
) != 0)
236 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
239 switch (u
->flags
.pad
)
248 internal_error (&iqp
->common
, "inquire_via_unit(): Bad pad");
251 cf_strcpy (iqp
->pad
, iqp
->pad_len
, p
);
254 if (cf
& IOPARM_INQUIRE_HAS_FLAGS2
)
256 GFC_INTEGER_4 cf2
= iqp
->flags2
;
258 if ((cf2
& IOPARM_INQUIRE_HAS_PENDING
) != 0)
261 if ((cf2
& IOPARM_INQUIRE_HAS_ID
) != 0)
264 if ((cf2
& IOPARM_INQUIRE_HAS_ENCODING
) != 0)
266 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
269 switch (u
->flags
.encoding
)
271 case ENCODING_DEFAULT
:
278 internal_error (&iqp
->common
, "inquire_via_unit(): Bad encoding");
281 cf_strcpy (iqp
->encoding
, iqp
->encoding_len
, p
);
284 if ((cf2
& IOPARM_INQUIRE_HAS_DECIMAL
) != 0)
286 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
289 switch (u
->flags
.decimal
)
298 internal_error (&iqp
->common
, "inquire_via_unit(): Bad comma");
301 cf_strcpy (iqp
->decimal
, iqp
->decimal_len
, p
);
304 if ((cf2
& IOPARM_INQUIRE_HAS_ASYNCHRONOUS
) != 0)
309 switch (u
->flags
.async
)
318 internal_error (&iqp
->common
, "inquire_via_unit(): Bad async");
321 cf_strcpy (iqp
->asynchronous
, iqp
->asynchronous_len
, p
);
324 if ((cf2
& IOPARM_INQUIRE_HAS_SIGN
) != 0)
329 switch (u
->flags
.sign
)
331 case SIGN_PROCDEFINED
:
332 p
= "PROCESSOR_DEFINED";
341 internal_error (&iqp
->common
, "inquire_via_unit(): Bad sign");
344 cf_strcpy (iqp
->sign
, iqp
->sign_len
, p
);
347 if ((cf2
& IOPARM_INQUIRE_HAS_ROUND
) != 0)
352 switch (u
->flags
.round
)
366 case ROUND_COMPATIBLE
:
369 case ROUND_PROCDEFINED
:
370 p
= "PROCESSOR_DEFINED";
373 internal_error (&iqp
->common
, "inquire_via_unit(): Bad round");
376 cf_strcpy (iqp
->round
, iqp
->round_len
, p
);
380 if ((cf
& IOPARM_INQUIRE_HAS_POSITION
) != 0)
382 if (u
== NULL
|| u
->flags
.access
== ACCESS_DIRECT
)
385 switch (u
->flags
.position
)
387 case POSITION_REWIND
:
390 case POSITION_APPEND
:
397 /* if not direct access, it must be
398 either REWIND, APPEND, or ASIS.
399 ASIS seems to be the best default */
403 cf_strcpy (iqp
->position
, iqp
->position_len
, p
);
406 if ((cf
& IOPARM_INQUIRE_HAS_ACTION
) != 0)
411 switch (u
->flags
.action
)
419 case ACTION_READWRITE
:
423 internal_error (&iqp
->common
, "inquire_via_unit(): Bad action");
426 cf_strcpy (iqp
->action
, iqp
->action_len
, p
);
429 if ((cf
& IOPARM_INQUIRE_HAS_READ
) != 0)
431 p
= (u
== NULL
) ? inquire_read (NULL
, 0) :
432 inquire_read (u
->file
, u
->file_len
);
434 cf_strcpy (iqp
->read
, iqp
->read_len
, p
);
437 if ((cf
& IOPARM_INQUIRE_HAS_WRITE
) != 0)
439 p
= (u
== NULL
) ? inquire_write (NULL
, 0) :
440 inquire_write (u
->file
, u
->file_len
);
442 cf_strcpy (iqp
->write
, iqp
->write_len
, p
);
445 if ((cf
& IOPARM_INQUIRE_HAS_READWRITE
) != 0)
447 p
= (u
== NULL
) ? inquire_readwrite (NULL
, 0) :
448 inquire_readwrite (u
->file
, u
->file_len
);
450 cf_strcpy (iqp
->readwrite
, iqp
->readwrite_len
, p
);
453 if ((cf
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
455 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
458 switch (u
->flags
.delim
)
466 case DELIM_APOSTROPHE
:
470 internal_error (&iqp
->common
, "inquire_via_unit(): Bad delim");
473 cf_strcpy (iqp
->delim
, iqp
->delim_len
, p
);
476 if ((cf
& IOPARM_INQUIRE_HAS_PAD
) != 0)
478 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
481 switch (u
->flags
.pad
)
490 internal_error (&iqp
->common
, "inquire_via_unit(): Bad pad");
493 cf_strcpy (iqp
->pad
, iqp
->pad_len
, p
);
496 if ((cf
& IOPARM_INQUIRE_HAS_CONVERT
) != 0)
501 switch (u
->flags
.convert
)
503 /* big_endian is 0 for little-endian, 1 for big-endian. */
504 case GFC_CONVERT_NATIVE
:
505 p
= big_endian
? "BIG_ENDIAN" : "LITTLE_ENDIAN";
508 case GFC_CONVERT_SWAP
:
509 p
= big_endian
? "LITTLE_ENDIAN" : "BIG_ENDIAN";
513 internal_error (&iqp
->common
, "inquire_via_unit(): Bad convert");
516 cf_strcpy (iqp
->convert
, iqp
->convert_len
, p
);
521 /* inquire_via_filename()-- Inquiry via filename. This subroutine is
522 * only used if the filename is *not* connected to a unit number. */
525 inquire_via_filename (st_parameter_inquire
*iqp
)
528 GFC_INTEGER_4 cf
= iqp
->common
.flags
;
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 GFC_INTEGER_4 cf2
= iqp
->flags2
;
591 if ((cf2
& IOPARM_INQUIRE_HAS_ENCODING
) != 0)
592 cf_strcpy (iqp
->encoding
, iqp
->encoding_len
, undefined
);
594 if ((cf2
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
595 cf_strcpy (iqp
->delim
, iqp
->delim_len
, undefined
);
597 if ((cf2
& IOPARM_INQUIRE_HAS_DECIMAL
) != 0)
598 cf_strcpy (iqp
->decimal
, iqp
->decimal_len
, undefined
);
600 if ((cf2
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
601 cf_strcpy (iqp
->delim
, iqp
->delim_len
, undefined
);
603 if ((cf2
& IOPARM_INQUIRE_HAS_PAD
) != 0)
604 cf_strcpy (iqp
->pad
, iqp
->pad_len
, undefined
);
606 if ((cf2
& IOPARM_INQUIRE_HAS_ENCODING
) != 0)
607 cf_strcpy (iqp
->encoding
, iqp
->encoding_len
, undefined
);
610 if ((cf
& IOPARM_INQUIRE_HAS_POSITION
) != 0)
611 cf_strcpy (iqp
->position
, iqp
->position_len
, undefined
);
613 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
614 cf_strcpy (iqp
->access
, iqp
->access_len
, undefined
);
616 if ((cf
& IOPARM_INQUIRE_HAS_READ
) != 0)
618 p
= inquire_read (iqp
->file
, iqp
->file_len
);
619 cf_strcpy (iqp
->read
, iqp
->read_len
, p
);
622 if ((cf
& IOPARM_INQUIRE_HAS_WRITE
) != 0)
624 p
= inquire_write (iqp
->file
, iqp
->file_len
);
625 cf_strcpy (iqp
->write
, iqp
->write_len
, p
);
628 if ((cf
& IOPARM_INQUIRE_HAS_READWRITE
) != 0)
630 p
= inquire_read (iqp
->file
, iqp
->file_len
);
631 cf_strcpy (iqp
->readwrite
, iqp
->readwrite_len
, p
);
636 /* Library entry point for the INQUIRE statement (non-IOLENGTH
639 extern void st_inquire (st_parameter_inquire
*);
640 export_proto(st_inquire
);
643 st_inquire (st_parameter_inquire
*iqp
)
647 library_start (&iqp
->common
);
649 if ((iqp
->common
.flags
& IOPARM_INQUIRE_HAS_FILE
) == 0)
651 u
= find_unit (iqp
->common
.unit
);
652 inquire_via_unit (iqp
, u
);
656 u
= find_file (iqp
->file
, iqp
->file_len
);
658 inquire_via_filename (iqp
);
660 inquire_via_unit (iqp
, u
);