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);
103 /* disallow an open direct access file to be accessed sequentially */
104 if (u
->flags
.access
== ACCESS_DIRECT
)
107 p
= inquire_sequential (u
->file
, u
->file_len
);
110 cf_strcpy (iqp
->sequential
, iqp
->sequential_len
, p
);
113 if ((cf
& IOPARM_INQUIRE_HAS_DIRECT
) != 0)
115 p
= (u
== NULL
) ? inquire_direct (NULL
, 0) :
116 inquire_direct (u
->file
, u
->file_len
);
118 cf_strcpy (iqp
->direct
, iqp
->direct_len
, p
);
121 if ((cf
& IOPARM_INQUIRE_HAS_FORM
) != 0)
126 switch (u
->flags
.form
)
131 case FORM_UNFORMATTED
:
135 internal_error (&iqp
->common
, "inquire_via_unit(): Bad form");
138 cf_strcpy (iqp
->form
, iqp
->form_len
, p
);
141 if ((cf
& IOPARM_INQUIRE_HAS_FORMATTED
) != 0)
143 p
= (u
== NULL
) ? inquire_formatted (NULL
, 0) :
144 inquire_formatted (u
->file
, u
->file_len
);
146 cf_strcpy (iqp
->formatted
, iqp
->formatted_len
, p
);
149 if ((cf
& IOPARM_INQUIRE_HAS_UNFORMATTED
) != 0)
151 p
= (u
== NULL
) ? inquire_unformatted (NULL
, 0) :
152 inquire_unformatted (u
->file
, u
->file_len
);
154 cf_strcpy (iqp
->unformatted
, iqp
->unformatted_len
, p
);
157 if ((cf
& IOPARM_INQUIRE_HAS_RECL_OUT
) != 0)
158 *iqp
->recl_out
= (u
!= NULL
) ? u
->recl
: 0;
160 if ((cf
& IOPARM_INQUIRE_HAS_STRM_POS_OUT
) != 0)
161 *iqp
->strm_pos_out
= (u
!= NULL
) ? u
->strm_pos
: 0;
163 if ((cf
& IOPARM_INQUIRE_HAS_NEXTREC
) != 0)
165 /* This only makes sense in the context of DIRECT access. */
166 if (u
!= NULL
&& u
->flags
.access
== ACCESS_DIRECT
)
167 *iqp
->nextrec
= u
->last_record
+ 1;
172 if ((cf
& IOPARM_INQUIRE_HAS_BLANK
) != 0)
177 switch (u
->flags
.blank
)
186 internal_error (&iqp
->common
, "inquire_via_unit(): Bad blank");
189 cf_strcpy (iqp
->blank
, iqp
->blank_len
, p
);
192 if ((cf
& IOPARM_INQUIRE_HAS_POSITION
) != 0)
194 if (u
== NULL
|| u
->flags
.access
== ACCESS_DIRECT
)
197 switch (u
->flags
.position
)
199 case POSITION_REWIND
:
202 case POSITION_APPEND
:
209 /* if not direct access, it must be
210 either REWIND, APPEND, or ASIS.
211 ASIS seems to be the best default */
215 cf_strcpy (iqp
->position
, iqp
->position_len
, p
);
218 if ((cf
& IOPARM_INQUIRE_HAS_ACTION
) != 0)
223 switch (u
->flags
.action
)
231 case ACTION_READWRITE
:
235 internal_error (&iqp
->common
, "inquire_via_unit(): Bad action");
238 cf_strcpy (iqp
->action
, iqp
->action_len
, p
);
241 if ((cf
& IOPARM_INQUIRE_HAS_READ
) != 0)
243 p
= (u
== NULL
) ? inquire_read (NULL
, 0) :
244 inquire_read (u
->file
, u
->file_len
);
246 cf_strcpy (iqp
->read
, iqp
->read_len
, p
);
249 if ((cf
& IOPARM_INQUIRE_HAS_WRITE
) != 0)
251 p
= (u
== NULL
) ? inquire_write (NULL
, 0) :
252 inquire_write (u
->file
, u
->file_len
);
254 cf_strcpy (iqp
->write
, iqp
->write_len
, p
);
257 if ((cf
& IOPARM_INQUIRE_HAS_READWRITE
) != 0)
259 p
= (u
== NULL
) ? inquire_readwrite (NULL
, 0) :
260 inquire_readwrite (u
->file
, u
->file_len
);
262 cf_strcpy (iqp
->readwrite
, iqp
->readwrite_len
, p
);
265 if ((cf
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
267 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
270 switch (u
->flags
.delim
)
278 case DELIM_APOSTROPHE
:
282 internal_error (&iqp
->common
, "inquire_via_unit(): Bad delim");
285 cf_strcpy (iqp
->delim
, iqp
->delim_len
, p
);
288 if ((cf
& IOPARM_INQUIRE_HAS_PAD
) != 0)
290 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
293 switch (u
->flags
.pad
)
302 internal_error (&iqp
->common
, "inquire_via_unit(): Bad pad");
305 cf_strcpy (iqp
->pad
, iqp
->pad_len
, p
);
308 if ((cf
& IOPARM_INQUIRE_HAS_CONVERT
) != 0)
313 switch (u
->flags
.convert
)
315 /* l8_to_l4_offset is 0 for little-endian, 1 for big-endian. */
316 case GFC_CONVERT_NATIVE
:
317 p
= l8_to_l4_offset
? "BIG_ENDIAN" : "LITTLE_ENDIAN";
320 case GFC_CONVERT_SWAP
:
321 p
= l8_to_l4_offset
? "LITTLE_ENDIAN" : "BIG_ENDIAN";
325 internal_error (&iqp
->common
, "inquire_via_unit(): Bad convert");
328 cf_strcpy (iqp
->convert
, iqp
->convert_len
, p
);
333 /* inquire_via_filename()-- Inquiry via filename. This subroutine is
334 * only used if the filename is *not* connected to a unit number. */
337 inquire_via_filename (st_parameter_inquire
*iqp
)
340 GFC_INTEGER_4 cf
= iqp
->common
.flags
;
342 if ((cf
& IOPARM_INQUIRE_HAS_EXIST
) != 0)
343 *iqp
->exist
= file_exists (iqp
->file
, iqp
->file_len
);
345 if ((cf
& IOPARM_INQUIRE_HAS_OPENED
) != 0)
348 if ((cf
& IOPARM_INQUIRE_HAS_NUMBER
) != 0)
351 if ((cf
& IOPARM_INQUIRE_HAS_NAMED
) != 0)
354 if ((cf
& IOPARM_INQUIRE_HAS_NAME
) != 0)
355 fstrcpy (iqp
->name
, iqp
->name_len
, iqp
->file
, iqp
->file_len
);
357 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
358 cf_strcpy (iqp
->access
, iqp
->access_len
, undefined
);
360 if ((cf
& IOPARM_INQUIRE_HAS_SEQUENTIAL
) != 0)
362 p
= inquire_sequential (iqp
->file
, iqp
->file_len
);
363 cf_strcpy (iqp
->sequential
, iqp
->sequential_len
, p
);
366 if ((cf
& IOPARM_INQUIRE_HAS_DIRECT
) != 0)
368 p
= inquire_direct (iqp
->file
, iqp
->file_len
);
369 cf_strcpy (iqp
->direct
, iqp
->direct_len
, p
);
372 if ((cf
& IOPARM_INQUIRE_HAS_FORM
) != 0)
373 cf_strcpy (iqp
->form
, iqp
->form_len
, undefined
);
375 if ((cf
& IOPARM_INQUIRE_HAS_FORMATTED
) != 0)
377 p
= inquire_formatted (iqp
->file
, iqp
->file_len
);
378 cf_strcpy (iqp
->formatted
, iqp
->formatted_len
, p
);
381 if ((cf
& IOPARM_INQUIRE_HAS_UNFORMATTED
) != 0)
383 p
= inquire_unformatted (iqp
->file
, iqp
->file_len
);
384 cf_strcpy (iqp
->unformatted
, iqp
->unformatted_len
, p
);
387 if ((cf
& IOPARM_INQUIRE_HAS_RECL_OUT
) != 0)
390 if ((cf
& IOPARM_INQUIRE_HAS_NEXTREC
) != 0)
393 if ((cf
& IOPARM_INQUIRE_HAS_BLANK
) != 0)
394 cf_strcpy (iqp
->blank
, iqp
->blank_len
, undefined
);
396 if ((cf
& IOPARM_INQUIRE_HAS_POSITION
) != 0)
397 cf_strcpy (iqp
->position
, iqp
->position_len
, undefined
);
399 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
400 cf_strcpy (iqp
->access
, iqp
->access_len
, undefined
);
402 if ((cf
& IOPARM_INQUIRE_HAS_READ
) != 0)
404 p
= inquire_read (iqp
->file
, iqp
->file_len
);
405 cf_strcpy (iqp
->read
, iqp
->read_len
, p
);
408 if ((cf
& IOPARM_INQUIRE_HAS_WRITE
) != 0)
410 p
= inquire_write (iqp
->file
, iqp
->file_len
);
411 cf_strcpy (iqp
->write
, iqp
->write_len
, p
);
414 if ((cf
& IOPARM_INQUIRE_HAS_READWRITE
) != 0)
416 p
= inquire_read (iqp
->file
, iqp
->file_len
);
417 cf_strcpy (iqp
->readwrite
, iqp
->readwrite_len
, p
);
420 if ((cf
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
421 cf_strcpy (iqp
->delim
, iqp
->delim_len
, undefined
);
423 if ((cf
& IOPARM_INQUIRE_HAS_PAD
) != 0)
424 cf_strcpy (iqp
->pad
, iqp
->pad_len
, undefined
);
428 /* Library entry point for the INQUIRE statement (non-IOLENGTH
431 extern void st_inquire (st_parameter_inquire
*);
432 export_proto(st_inquire
);
435 st_inquire (st_parameter_inquire
*iqp
)
439 library_start (&iqp
->common
);
441 if ((iqp
->common
.flags
& IOPARM_INQUIRE_HAS_FILE
) == 0)
443 u
= find_unit (iqp
->common
.unit
);
444 inquire_via_unit (iqp
, u
);
448 u
= find_file (iqp
->file
, iqp
->file_len
);
450 inquire_via_filename (iqp
);
452 inquire_via_unit (iqp
, u
);