1 /* Copyright (C) 2002, 2003, 2005, 2007, 2009, 2010
2 Free Software Foundation, Inc.
3 Contributed by Andy Vaught
5 This file is part of the GNU Fortran 95 runtime library (libgfortran).
7 Libgfortran is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 Libgfortran is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
27 /* Implement the non-IOLENGTH variant of the INQUIRY statement */
33 static const char undefined[] = "UNDEFINED";
36 /* inquire_via_unit()-- Inquiry via unit number. The unit might not exist. */
39 inquire_via_unit (st_parameter_inquire *iqp, gfc_unit * u)
42 GFC_INTEGER_4 cf = iqp->common.flags;
44 if ((cf & IOPARM_INQUIRE_HAS_EXIST) != 0)
46 *iqp->exist = (iqp->common.unit >= 0
47 && iqp->common.unit <= GFC_INTEGER_4_HUGE);
49 if ((cf & IOPARM_INQUIRE_HAS_FILE) == 0)
52 *iqp->common.iostat = LIBERROR_BAD_UNIT;
53 *iqp->exist = *iqp->exist
54 && (*iqp->common.iostat != LIBERROR_BAD_UNIT);
58 if ((cf & IOPARM_INQUIRE_HAS_OPENED) != 0)
59 *iqp->opened = (u != NULL);
61 if ((cf & IOPARM_INQUIRE_HAS_NUMBER) != 0)
62 *iqp->number = (u != NULL) ? u->unit_number : -1;
64 if ((cf & IOPARM_INQUIRE_HAS_NAMED) != 0)
65 *iqp->named = (u != NULL && u->flags.status != STATUS_SCRATCH);
67 if ((cf & IOPARM_INQUIRE_HAS_NAME) != 0
68 && u != NULL && u->flags.status != STATUS_SCRATCH)
69 fstrcpy (iqp->name, iqp->name_len, u->file, u->file_len);
71 if ((cf & IOPARM_INQUIRE_HAS_ACCESS) != 0)
76 switch (u->flags.access)
78 case ACCESS_SEQUENTIAL:
88 internal_error (&iqp->common, "inquire_via_unit(): Bad access");
91 cf_strcpy (iqp->access, iqp->access_len, p);
94 if ((cf & IOPARM_INQUIRE_HAS_SEQUENTIAL) != 0)
97 p = inquire_sequential (NULL, 0);
99 switch (u->flags.access)
105 case ACCESS_SEQUENTIAL:
109 internal_error (&iqp->common, "inquire_via_unit(): Bad access");
112 cf_strcpy (iqp->sequential, iqp->sequential_len, p);
115 if ((cf & IOPARM_INQUIRE_HAS_DIRECT) != 0)
118 p = inquire_direct (NULL, 0);
120 switch (u->flags.access)
122 case ACCESS_SEQUENTIAL:
130 internal_error (&iqp->common, "inquire_via_unit(): Bad access");
133 cf_strcpy (iqp->direct, iqp->direct_len, p);
136 if ((cf & IOPARM_INQUIRE_HAS_FORM) != 0)
141 switch (u->flags.form)
146 case FORM_UNFORMATTED:
150 internal_error (&iqp->common, "inquire_via_unit(): Bad form");
153 cf_strcpy (iqp->form, iqp->form_len, p);
156 if ((cf & IOPARM_INQUIRE_HAS_FORMATTED) != 0)
159 p = inquire_formatted (NULL, 0);
161 switch (u->flags.form)
166 case FORM_UNFORMATTED:
170 internal_error (&iqp->common, "inquire_via_unit(): Bad form");
173 cf_strcpy (iqp->formatted, iqp->formatted_len, p);
176 if ((cf & IOPARM_INQUIRE_HAS_UNFORMATTED) != 0)
179 p = inquire_unformatted (NULL, 0);
181 switch (u->flags.form)
186 case FORM_UNFORMATTED:
190 internal_error (&iqp->common, "inquire_via_unit(): Bad form");
193 cf_strcpy (iqp->unformatted, iqp->unformatted_len, p);
196 if ((cf & IOPARM_INQUIRE_HAS_RECL_OUT) != 0)
197 *iqp->recl_out = (u != NULL) ? u->recl : 0;
199 if ((cf & IOPARM_INQUIRE_HAS_STRM_POS_OUT) != 0)
200 *iqp->strm_pos_out = (u != NULL) ? u->strm_pos : 0;
202 if ((cf & IOPARM_INQUIRE_HAS_NEXTREC) != 0)
204 /* This only makes sense in the context of DIRECT access. */
205 if (u != NULL && u->flags.access == ACCESS_DIRECT)
206 *iqp->nextrec = u->last_record + 1;
211 if ((cf & IOPARM_INQUIRE_HAS_BLANK) != 0)
213 if (u == NULL || u->flags.form != FORM_FORMATTED)
216 switch (u->flags.blank)
225 internal_error (&iqp->common, "inquire_via_unit(): Bad blank");
228 cf_strcpy (iqp->blank, iqp->blank_len, p);
231 if ((cf & IOPARM_INQUIRE_HAS_PAD) != 0)
233 if (u == NULL || u->flags.form != FORM_FORMATTED)
236 switch (u->flags.pad)
245 internal_error (&iqp->common, "inquire_via_unit(): Bad pad");
248 cf_strcpy (iqp->pad, iqp->pad_len, p);
251 if (cf & IOPARM_INQUIRE_HAS_FLAGS2)
253 GFC_INTEGER_4 cf2 = iqp->flags2;
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 ((cf2 & IOPARM_INQUIRE_HAS_SIZE) != 0)
381 *iqp->size = file_size (u->file, (gfc_charlen_type) u->file_len);
385 if ((cf & IOPARM_INQUIRE_HAS_POSITION) != 0)
387 if (u == NULL || u->flags.access == ACCESS_DIRECT)
390 switch (u->flags.position)
392 case POSITION_REWIND:
395 case POSITION_APPEND:
402 /* if not direct access, it must be
403 either REWIND, APPEND, or ASIS.
404 ASIS seems to be the best default */
408 cf_strcpy (iqp->position, iqp->position_len, p);
411 if ((cf & IOPARM_INQUIRE_HAS_ACTION) != 0)
416 switch (u->flags.action)
424 case ACTION_READWRITE:
428 internal_error (&iqp->common, "inquire_via_unit(): Bad action");
431 cf_strcpy (iqp->action, iqp->action_len, p);
434 if ((cf & IOPARM_INQUIRE_HAS_READ) != 0)
436 p = (u == NULL) ? inquire_read (NULL, 0) :
437 inquire_read (u->file, u->file_len);
439 cf_strcpy (iqp->read, iqp->read_len, p);
442 if ((cf & IOPARM_INQUIRE_HAS_WRITE) != 0)
444 p = (u == NULL) ? inquire_write (NULL, 0) :
445 inquire_write (u->file, u->file_len);
447 cf_strcpy (iqp->write, iqp->write_len, p);
450 if ((cf & IOPARM_INQUIRE_HAS_READWRITE) != 0)
452 p = (u == NULL) ? inquire_readwrite (NULL, 0) :
453 inquire_readwrite (u->file, u->file_len);
455 cf_strcpy (iqp->readwrite, iqp->readwrite_len, p);
458 if ((cf & IOPARM_INQUIRE_HAS_DELIM) != 0)
460 if (u == NULL || u->flags.form != FORM_FORMATTED)
463 switch (u->flags.delim)
471 case DELIM_APOSTROPHE:
475 internal_error (&iqp->common, "inquire_via_unit(): Bad delim");
478 cf_strcpy (iqp->delim, iqp->delim_len, p);
481 if ((cf & IOPARM_INQUIRE_HAS_PAD) != 0)
483 if (u == NULL || u->flags.form != FORM_FORMATTED)
486 switch (u->flags.pad)
495 internal_error (&iqp->common, "inquire_via_unit(): Bad pad");
498 cf_strcpy (iqp->pad, iqp->pad_len, p);
501 if ((cf & IOPARM_INQUIRE_HAS_CONVERT) != 0)
506 switch (u->flags.convert)
508 /* big_endian is 0 for little-endian, 1 for big-endian. */
509 case GFC_CONVERT_NATIVE:
510 p = big_endian ? "BIG_ENDIAN" : "LITTLE_ENDIAN";
513 case GFC_CONVERT_SWAP:
514 p = big_endian ? "LITTLE_ENDIAN" : "BIG_ENDIAN";
518 internal_error (&iqp->common, "inquire_via_unit(): Bad convert");
521 cf_strcpy (iqp->convert, iqp->convert_len, p);
526 /* inquire_via_filename()-- Inquiry via filename. This subroutine is
527 * only used if the filename is *not* connected to a unit number. */
530 inquire_via_filename (st_parameter_inquire *iqp)
533 GFC_INTEGER_4 cf = iqp->common.flags;
535 if ((cf & IOPARM_INQUIRE_HAS_EXIST) != 0)
536 *iqp->exist = file_exists (iqp->file, iqp->file_len);
538 if ((cf & IOPARM_INQUIRE_HAS_OPENED) != 0)
541 if ((cf & IOPARM_INQUIRE_HAS_NUMBER) != 0)
544 if ((cf & IOPARM_INQUIRE_HAS_NAMED) != 0)
547 if ((cf & IOPARM_INQUIRE_HAS_NAME) != 0)
548 fstrcpy (iqp->name, iqp->name_len, iqp->file, iqp->file_len);
550 if ((cf & IOPARM_INQUIRE_HAS_ACCESS) != 0)
551 cf_strcpy (iqp->access, iqp->access_len, undefined);
553 if ((cf & IOPARM_INQUIRE_HAS_SEQUENTIAL) != 0)
556 cf_strcpy (iqp->sequential, iqp->sequential_len, p);
559 if ((cf & IOPARM_INQUIRE_HAS_DIRECT) != 0)
562 cf_strcpy (iqp->direct, iqp->direct_len, p);
565 if ((cf & IOPARM_INQUIRE_HAS_FORM) != 0)
566 cf_strcpy (iqp->form, iqp->form_len, undefined);
568 if ((cf & IOPARM_INQUIRE_HAS_FORMATTED) != 0)
571 cf_strcpy (iqp->formatted, iqp->formatted_len, p);
574 if ((cf & IOPARM_INQUIRE_HAS_UNFORMATTED) != 0)
577 cf_strcpy (iqp->unformatted, iqp->unformatted_len, p);
580 if ((cf & IOPARM_INQUIRE_HAS_RECL_OUT) != 0)
583 if ((cf & IOPARM_INQUIRE_HAS_NEXTREC) != 0)
586 if ((cf & IOPARM_INQUIRE_HAS_BLANK) != 0)
587 cf_strcpy (iqp->blank, iqp->blank_len, undefined);
589 if ((cf & IOPARM_INQUIRE_HAS_PAD) != 0)
590 cf_strcpy (iqp->pad, iqp->pad_len, undefined);
592 if (cf & IOPARM_INQUIRE_HAS_FLAGS2)
594 GFC_INTEGER_4 cf2 = iqp->flags2;
596 if ((cf2 & IOPARM_INQUIRE_HAS_ENCODING) != 0)
597 cf_strcpy (iqp->encoding, iqp->encoding_len, undefined);
599 if ((cf2 & IOPARM_INQUIRE_HAS_DELIM) != 0)
600 cf_strcpy (iqp->delim, iqp->delim_len, undefined);
602 if ((cf2 & IOPARM_INQUIRE_HAS_DECIMAL) != 0)
603 cf_strcpy (iqp->decimal, iqp->decimal_len, undefined);
605 if ((cf2 & IOPARM_INQUIRE_HAS_DELIM) != 0)
606 cf_strcpy (iqp->delim, iqp->delim_len, undefined);
608 if ((cf2 & IOPARM_INQUIRE_HAS_PAD) != 0)
609 cf_strcpy (iqp->pad, iqp->pad_len, undefined);
611 if ((cf2 & IOPARM_INQUIRE_HAS_ENCODING) != 0)
612 cf_strcpy (iqp->encoding, iqp->encoding_len, undefined);
614 if ((cf2 & IOPARM_INQUIRE_HAS_SIZE) != 0)
615 *iqp->size = file_size (iqp->file, iqp->file_len);
618 if ((cf & IOPARM_INQUIRE_HAS_POSITION) != 0)
619 cf_strcpy (iqp->position, iqp->position_len, undefined);
621 if ((cf & IOPARM_INQUIRE_HAS_ACCESS) != 0)
622 cf_strcpy (iqp->access, iqp->access_len, undefined);
624 if ((cf & IOPARM_INQUIRE_HAS_READ) != 0)
626 p = inquire_read (iqp->file, iqp->file_len);
627 cf_strcpy (iqp->read, iqp->read_len, p);
630 if ((cf & IOPARM_INQUIRE_HAS_WRITE) != 0)
632 p = inquire_write (iqp->file, iqp->file_len);
633 cf_strcpy (iqp->write, iqp->write_len, p);
636 if ((cf & IOPARM_INQUIRE_HAS_READWRITE) != 0)
638 p = inquire_read (iqp->file, iqp->file_len);
639 cf_strcpy (iqp->readwrite, iqp->readwrite_len, p);
644 /* Library entry point for the INQUIRE statement (non-IOLENGTH
647 extern void st_inquire (st_parameter_inquire *);
648 export_proto(st_inquire);
651 st_inquire (st_parameter_inquire *iqp)
655 library_start (&iqp->common);
657 if ((iqp->common.flags & IOPARM_INQUIRE_HAS_FILE) == 0)
659 u = find_unit (iqp->common.unit);
660 inquire_via_unit (iqp, u);
664 u = find_file (iqp->file, iqp->file_len);
666 inquire_via_filename (iqp);
668 inquire_via_unit (iqp, u);