1 /* Copyright (C) 2002, 2003, 2005 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 */
34 #include "libgfortran.h"
38 static const char undefined
[] = "UNDEFINED";
41 /* inquire_via_unit()-- Inquiry via unit number. The unit might not exist. */
44 inquire_via_unit (st_parameter_inquire
*iqp
, gfc_unit
* u
)
47 GFC_INTEGER_4 cf
= iqp
->common
.flags
;
49 if ((cf
& IOPARM_INQUIRE_HAS_EXIST
) != 0)
50 *iqp
->exist
= iqp
->common
.unit
>= 0;
52 if ((cf
& IOPARM_INQUIRE_HAS_OPENED
) != 0)
53 *iqp
->opened
= (u
!= NULL
);
55 if ((cf
& IOPARM_INQUIRE_HAS_NUMBER
) != 0)
56 *iqp
->number
= (u
!= NULL
) ? u
->unit_number
: -1;
58 if ((cf
& IOPARM_INQUIRE_HAS_NAMED
) != 0)
59 *iqp
->named
= (u
!= NULL
&& u
->flags
.status
!= STATUS_SCRATCH
);
61 if ((cf
& IOPARM_INQUIRE_HAS_NAME
) != 0
62 && u
!= NULL
&& u
->flags
.status
!= STATUS_SCRATCH
)
63 fstrcpy (iqp
->name
, iqp
->name_len
, u
->file
, u
->file_len
);
65 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
70 switch (u
->flags
.access
)
72 case ACCESS_SEQUENTIAL
:
82 internal_error (&iqp
->common
, "inquire_via_unit(): Bad access");
85 cf_strcpy (iqp
->access
, iqp
->access_len
, p
);
88 if ((cf
& IOPARM_INQUIRE_HAS_SEQUENTIAL
) != 0)
91 p
= inquire_sequential (NULL
, 0);
94 /* disallow an open direct access file to be accessed sequentially */
95 if (u
->flags
.access
== ACCESS_DIRECT
)
98 p
= inquire_sequential (u
->file
, u
->file_len
);
101 cf_strcpy (iqp
->sequential
, iqp
->sequential_len
, p
);
104 if ((cf
& IOPARM_INQUIRE_HAS_DIRECT
) != 0)
106 p
= (u
== NULL
) ? inquire_direct (NULL
, 0) :
107 inquire_direct (u
->file
, u
->file_len
);
109 cf_strcpy (iqp
->direct
, iqp
->direct_len
, p
);
112 if ((cf
& IOPARM_INQUIRE_HAS_FORM
) != 0)
117 switch (u
->flags
.form
)
122 case FORM_UNFORMATTED
:
126 internal_error (&iqp
->common
, "inquire_via_unit(): Bad form");
129 cf_strcpy (iqp
->form
, iqp
->form_len
, p
);
132 if ((cf
& IOPARM_INQUIRE_HAS_FORMATTED
) != 0)
134 p
= (u
== NULL
) ? inquire_formatted (NULL
, 0) :
135 inquire_formatted (u
->file
, u
->file_len
);
137 cf_strcpy (iqp
->formatted
, iqp
->formatted_len
, p
);
140 if ((cf
& IOPARM_INQUIRE_HAS_UNFORMATTED
) != 0)
142 p
= (u
== NULL
) ? inquire_unformatted (NULL
, 0) :
143 inquire_unformatted (u
->file
, u
->file_len
);
145 cf_strcpy (iqp
->unformatted
, iqp
->unformatted_len
, p
);
148 if ((cf
& IOPARM_INQUIRE_HAS_RECL_OUT
) != 0)
149 *iqp
->recl_out
= (u
!= NULL
) ? u
->recl
: 0;
151 if ((cf
& IOPARM_INQUIRE_HAS_STRM_POS_OUT
) != 0)
152 *iqp
->strm_pos_out
= (u
!= NULL
) ? u
->strm_pos
: 0;
154 if ((cf
& IOPARM_INQUIRE_HAS_NEXTREC
) != 0)
156 /* This only makes sense in the context of DIRECT access. */
157 if (u
!= NULL
&& u
->flags
.access
== ACCESS_DIRECT
)
158 *iqp
->nextrec
= u
->last_record
+ 1;
163 if ((cf
& IOPARM_INQUIRE_HAS_BLANK
) != 0)
168 switch (u
->flags
.blank
)
177 internal_error (&iqp
->common
, "inquire_via_unit(): Bad blank");
180 cf_strcpy (iqp
->blank
, iqp
->blank_len
, p
);
183 if ((cf
& IOPARM_INQUIRE_HAS_POSITION
) != 0)
185 if (u
== NULL
|| u
->flags
.access
== ACCESS_DIRECT
)
188 switch (u
->flags
.position
)
190 case POSITION_REWIND
:
193 case POSITION_APPEND
:
200 /* if not direct access, it must be
201 either REWIND, APPEND, or ASIS.
202 ASIS seems to be the best default */
206 cf_strcpy (iqp
->position
, iqp
->position_len
, p
);
209 if ((cf
& IOPARM_INQUIRE_HAS_ACTION
) != 0)
214 switch (u
->flags
.action
)
222 case ACTION_READWRITE
:
226 internal_error (&iqp
->common
, "inquire_via_unit(): Bad action");
229 cf_strcpy (iqp
->action
, iqp
->action_len
, p
);
232 if ((cf
& IOPARM_INQUIRE_HAS_READ
) != 0)
234 p
= (u
== NULL
) ? inquire_read (NULL
, 0) :
235 inquire_read (u
->file
, u
->file_len
);
237 cf_strcpy (iqp
->read
, iqp
->read_len
, p
);
240 if ((cf
& IOPARM_INQUIRE_HAS_WRITE
) != 0)
242 p
= (u
== NULL
) ? inquire_write (NULL
, 0) :
243 inquire_write (u
->file
, u
->file_len
);
245 cf_strcpy (iqp
->write
, iqp
->write_len
, p
);
248 if ((cf
& IOPARM_INQUIRE_HAS_READWRITE
) != 0)
250 p
= (u
== NULL
) ? inquire_readwrite (NULL
, 0) :
251 inquire_readwrite (u
->file
, u
->file_len
);
253 cf_strcpy (iqp
->readwrite
, iqp
->readwrite_len
, p
);
256 if ((cf
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
258 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
261 switch (u
->flags
.delim
)
269 case DELIM_APOSTROPHE
:
273 internal_error (&iqp
->common
, "inquire_via_unit(): Bad delim");
276 cf_strcpy (iqp
->delim
, iqp
->delim_len
, p
);
279 if ((cf
& IOPARM_INQUIRE_HAS_PAD
) != 0)
281 if (u
== NULL
|| u
->flags
.form
!= FORM_FORMATTED
)
284 switch (u
->flags
.pad
)
293 internal_error (&iqp
->common
, "inquire_via_unit(): Bad pad");
296 cf_strcpy (iqp
->pad
, iqp
->pad_len
, p
);
299 if ((cf
& IOPARM_INQUIRE_HAS_CONVERT
) != 0)
304 switch (u
->flags
.convert
)
306 /* l8_to_l4_offset is 0 for little-endian, 1 for big-endian. */
308 p
= l8_to_l4_offset
? "BIG_ENDIAN" : "LITTLE_ENDIAN";
312 p
= l8_to_l4_offset
? "LITTLE_ENDIAN" : "BIG_ENDIAN";
316 internal_error (&iqp
->common
, "inquire_via_unit(): Bad convert");
319 cf_strcpy (iqp
->convert
, iqp
->convert_len
, p
);
324 /* inquire_via_filename()-- Inquiry via filename. This subroutine is
325 * only used if the filename is *not* connected to a unit number. */
328 inquire_via_filename (st_parameter_inquire
*iqp
)
331 GFC_INTEGER_4 cf
= iqp
->common
.flags
;
333 if ((cf
& IOPARM_INQUIRE_HAS_EXIST
) != 0)
334 *iqp
->exist
= file_exists (iqp
->file
, iqp
->file_len
);
336 if ((cf
& IOPARM_INQUIRE_HAS_OPENED
) != 0)
339 if ((cf
& IOPARM_INQUIRE_HAS_NUMBER
) != 0)
342 if ((cf
& IOPARM_INQUIRE_HAS_NAMED
) != 0)
345 if ((cf
& IOPARM_INQUIRE_HAS_NAME
) != 0)
346 fstrcpy (iqp
->name
, iqp
->name_len
, iqp
->file
, iqp
->file_len
);
348 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
349 cf_strcpy (iqp
->access
, iqp
->access_len
, undefined
);
351 if ((cf
& IOPARM_INQUIRE_HAS_SEQUENTIAL
) != 0)
353 p
= inquire_sequential (iqp
->file
, iqp
->file_len
);
354 cf_strcpy (iqp
->sequential
, iqp
->sequential_len
, p
);
357 if ((cf
& IOPARM_INQUIRE_HAS_DIRECT
) != 0)
359 p
= inquire_direct (iqp
->file
, iqp
->file_len
);
360 cf_strcpy (iqp
->direct
, iqp
->direct_len
, p
);
363 if ((cf
& IOPARM_INQUIRE_HAS_FORM
) != 0)
364 cf_strcpy (iqp
->form
, iqp
->form_len
, undefined
);
366 if ((cf
& IOPARM_INQUIRE_HAS_FORMATTED
) != 0)
368 p
= inquire_formatted (iqp
->file
, iqp
->file_len
);
369 cf_strcpy (iqp
->formatted
, iqp
->formatted_len
, p
);
372 if ((cf
& IOPARM_INQUIRE_HAS_UNFORMATTED
) != 0)
374 p
= inquire_unformatted (iqp
->file
, iqp
->file_len
);
375 cf_strcpy (iqp
->unformatted
, iqp
->unformatted_len
, p
);
378 if ((cf
& IOPARM_INQUIRE_HAS_RECL_OUT
) != 0)
381 if ((cf
& IOPARM_INQUIRE_HAS_NEXTREC
) != 0)
384 if ((cf
& IOPARM_INQUIRE_HAS_BLANK
) != 0)
385 cf_strcpy (iqp
->blank
, iqp
->blank_len
, undefined
);
387 if ((cf
& IOPARM_INQUIRE_HAS_POSITION
) != 0)
388 cf_strcpy (iqp
->position
, iqp
->position_len
, undefined
);
390 if ((cf
& IOPARM_INQUIRE_HAS_ACCESS
) != 0)
391 cf_strcpy (iqp
->access
, iqp
->access_len
, undefined
);
393 if ((cf
& IOPARM_INQUIRE_HAS_READ
) != 0)
395 p
= inquire_read (iqp
->file
, iqp
->file_len
);
396 cf_strcpy (iqp
->read
, iqp
->read_len
, p
);
399 if ((cf
& IOPARM_INQUIRE_HAS_WRITE
) != 0)
401 p
= inquire_write (iqp
->file
, iqp
->file_len
);
402 cf_strcpy (iqp
->write
, iqp
->write_len
, p
);
405 if ((cf
& IOPARM_INQUIRE_HAS_READWRITE
) != 0)
407 p
= inquire_read (iqp
->file
, iqp
->file_len
);
408 cf_strcpy (iqp
->readwrite
, iqp
->readwrite_len
, p
);
411 if ((cf
& IOPARM_INQUIRE_HAS_DELIM
) != 0)
412 cf_strcpy (iqp
->delim
, iqp
->delim_len
, undefined
);
414 if ((cf
& IOPARM_INQUIRE_HAS_PAD
) != 0)
415 cf_strcpy (iqp
->pad
, iqp
->pad_len
, undefined
);
419 /* Library entry point for the INQUIRE statement (non-IOLENGTH
422 extern void st_inquire (st_parameter_inquire
*);
423 export_proto(st_inquire
);
426 st_inquire (st_parameter_inquire
*iqp
)
430 library_start (&iqp
->common
);
432 if ((iqp
->common
.flags
& IOPARM_INQUIRE_HAS_FILE
) == 0)
434 u
= find_unit (iqp
->common
.unit
);
435 inquire_via_unit (iqp
, u
);
439 u
= find_file (iqp
->file
, iqp
->file_len
);
441 inquire_via_filename (iqp
);
443 inquire_via_unit (iqp
, u
);