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 ((cf2
& IOPARM_INQUIRE_HAS_PENDING
) != 0)
258 if ((cf2
& IOPARM_INQUIRE_HAS_ID
) != 0)
261 if ((cf2
& IOPARM_INQUIRE_HAS_ENCODING
) != 0)
263 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
266 switch (u
->flags
.encoding
)
268 case ENCODING_DEFAULT
:
275 internal_error (&iqp
->common
, "inquire_via_unit(): Bad encoding");
278 cf_strcpy (iqp
->encoding
, iqp
->encoding_len
, p
);
281 if ((cf2
& IOPARM_INQUIRE_HAS_DECIMAL
) != 0)
283 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
286 switch (u
->flags
.decimal
)
295 internal_error (&iqp
->common
, "inquire_via_unit(): Bad comma");
298 cf_strcpy (iqp
->decimal
, iqp
->decimal_len
, p
);
301 if ((cf2
& IOPARM_INQUIRE_HAS_ASYNCHRONOUS
) != 0)
306 switch (u
->flags
.async
)
315 internal_error (&iqp
->common
, "inquire_via_unit(): Bad async");
318 cf_strcpy (iqp
->asynchronous
, iqp
->asynchronous_len
, p
);
321 if ((cf2
& IOPARM_INQUIRE_HAS_SIGN
) != 0)
326 switch (u
->flags
.sign
)
328 case SIGN_PROCDEFINED
:
329 p
= "PROCESSOR_DEFINED";
338 internal_error (&iqp
->common
, "inquire_via_unit(): Bad sign");
341 cf_strcpy (iqp
->sign
, iqp
->sign_len
, p
);
344 if ((cf2
& IOPARM_INQUIRE_HAS_ROUND
) != 0)
349 switch (u
->flags
.round
)
363 case ROUND_COMPATIBLE
:
366 case ROUND_PROCDEFINED
:
367 p
= "PROCESSOR_DEFINED";
370 internal_error (&iqp
->common
, "inquire_via_unit(): Bad round");
373 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
;
525 GFC_INTEGER_4 cf2
= iqp
->flags2
;
527 if ((cf
& IOPARM_INQUIRE_HAS_EXIST
) != 0)
528 *iqp
->exist
= file_exists (iqp
->file
, iqp
->file_len
);
530 if ((cf
& IOPARM_INQUIRE_HAS_OPENED
) != 0)
533 if ((cf
& IOPARM_INQUIRE_HAS_NUMBER
) != 0)
536 if ((cf
& IOPARM_INQUIRE_HAS_NAMED
) != 0)
539 if ((cf
& IOPARM_INQUIRE_HAS_NAME
) != 0)
540 fstrcpy (iqp
->name
, iqp
->name_len
, iqp
->file
, iqp
->file_len
);
542 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
543 cf_strcpy (iqp
->access
, iqp
->access_len
, undefined
);
545 if ((cf
& IOPARM_INQUIRE_HAS_SEQUENTIAL
) != 0)
548 cf_strcpy (iqp
->sequential
, iqp
->sequential_len
, p
);
551 if ((cf
& IOPARM_INQUIRE_HAS_DIRECT
) != 0)
554 cf_strcpy (iqp
->direct
, iqp
->direct_len
, p
);
557 if ((cf
& IOPARM_INQUIRE_HAS_FORM
) != 0)
558 cf_strcpy (iqp
->form
, iqp
->form_len
, undefined
);
560 if ((cf
& IOPARM_INQUIRE_HAS_FORMATTED
) != 0)
563 cf_strcpy (iqp
->formatted
, iqp
->formatted_len
, p
);
566 if ((cf
& IOPARM_INQUIRE_HAS_UNFORMATTED
) != 0)
569 cf_strcpy (iqp
->unformatted
, iqp
->unformatted_len
, p
);
572 if ((cf
& IOPARM_INQUIRE_HAS_RECL_OUT
) != 0)
575 if ((cf
& IOPARM_INQUIRE_HAS_NEXTREC
) != 0)
578 if ((cf
& IOPARM_INQUIRE_HAS_BLANK
) != 0)
579 cf_strcpy (iqp
->blank
, iqp
->blank_len
, undefined
);
581 if ((cf
& IOPARM_INQUIRE_HAS_PAD
) != 0)
582 cf_strcpy (iqp
->pad
, iqp
->pad_len
, undefined
);
584 if ((cf2
& IOPARM_INQUIRE_HAS_ENCODING
) != 0)
585 cf_strcpy (iqp
->encoding
, iqp
->encoding_len
, undefined
);
587 if ((cf2
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
588 cf_strcpy (iqp
->delim
, iqp
->delim_len
, undefined
);
590 if ((cf2
& IOPARM_INQUIRE_HAS_DECIMAL
) != 0)
591 cf_strcpy (iqp
->decimal
, iqp
->decimal_len
, undefined
);
593 if ((cf
& IOPARM_INQUIRE_HAS_POSITION
) != 0)
594 cf_strcpy (iqp
->position
, iqp
->position_len
, undefined
);
596 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
597 cf_strcpy (iqp
->access
, iqp
->access_len
, undefined
);
599 if ((cf
& IOPARM_INQUIRE_HAS_READ
) != 0)
601 p
= inquire_read (iqp
->file
, iqp
->file_len
);
602 cf_strcpy (iqp
->read
, iqp
->read_len
, p
);
605 if ((cf
& IOPARM_INQUIRE_HAS_WRITE
) != 0)
607 p
= inquire_write (iqp
->file
, iqp
->file_len
);
608 cf_strcpy (iqp
->write
, iqp
->write_len
, p
);
611 if ((cf
& IOPARM_INQUIRE_HAS_READWRITE
) != 0)
613 p
= inquire_read (iqp
->file
, iqp
->file_len
);
614 cf_strcpy (iqp
->readwrite
, iqp
->readwrite_len
, p
);
617 if ((cf2
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
618 cf_strcpy (iqp
->delim
, iqp
->delim_len
, undefined
);
620 if ((cf2
& IOPARM_INQUIRE_HAS_PAD
) != 0)
621 cf_strcpy (iqp
->pad
, iqp
->pad_len
, undefined
);
623 if ((cf2
& IOPARM_INQUIRE_HAS_ENCODING
) != 0)
624 cf_strcpy (iqp
->encoding
, iqp
->encoding_len
, undefined
);
628 /* Library entry point for the INQUIRE statement (non-IOLENGTH
631 extern void st_inquire (st_parameter_inquire
*);
632 export_proto(st_inquire
);
635 st_inquire (st_parameter_inquire
*iqp
)
639 library_start (&iqp
->common
);
641 if ((iqp
->common
.flags
& IOPARM_INQUIRE_HAS_FILE
) == 0)
643 u
= find_unit (iqp
->common
.unit
);
644 inquire_via_unit (iqp
, u
);
648 u
= find_file (iqp
->file
, iqp
->file_len
);
650 inquire_via_filename (iqp
);
652 inquire_via_unit (iqp
, u
);