2008-10-01 Kai Tietz <kai.tietz@onevision.com>
[official-gcc.git] / libgfortran / io / inquire.c
blob3b5f3f74473ae144e10ef4a309e63cec9321739d
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)
9 any later version.
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
18 executable.)
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 */
33 #include "io.h"
36 static const char undefined[] = "UNDEFINED";
39 /* inquire_via_unit()-- Inquiry via unit number. The unit might not exist. */
41 static void
42 inquire_via_unit (st_parameter_inquire *iqp, gfc_unit * u)
44 const char *p;
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)
55 if (!(*iqp->exist))
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)
77 if (u == NULL)
78 p = undefined;
79 else
80 switch (u->flags.access)
82 case ACCESS_SEQUENTIAL:
83 p = "SEQUENTIAL";
84 break;
85 case ACCESS_DIRECT:
86 p = "DIRECT";
87 break;
88 case ACCESS_STREAM:
89 p = "STREAM";
90 break;
91 default:
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)
100 if (u == NULL)
101 p = inquire_sequential (NULL, 0);
102 else
103 switch (u->flags.access)
105 case ACCESS_DIRECT:
106 case ACCESS_STREAM:
107 p = "NO";
108 break;
109 case ACCESS_SEQUENTIAL:
110 p = "YES";
111 break;
112 default:
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)
121 if (u == NULL)
122 p = inquire_direct (NULL, 0);
123 else
124 switch (u->flags.access)
126 case ACCESS_SEQUENTIAL:
127 case ACCESS_STREAM:
128 p = "NO";
129 break;
130 case ACCESS_DIRECT:
131 p = "YES";
132 break;
133 default:
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)
142 if (u == NULL)
143 p = undefined;
144 else
145 switch (u->flags.form)
147 case FORM_FORMATTED:
148 p = "FORMATTED";
149 break;
150 case FORM_UNFORMATTED:
151 p = "UNFORMATTED";
152 break;
153 default:
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)
162 if (u == NULL)
163 p = inquire_formatted (NULL, 0);
164 else
165 switch (u->flags.form)
167 case FORM_FORMATTED:
168 p = "YES";
169 break;
170 case FORM_UNFORMATTED:
171 p = "NO";
172 break;
173 default:
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)
182 if (u == NULL)
183 p = inquire_unformatted (NULL, 0);
184 else
185 switch (u->flags.form)
187 case FORM_FORMATTED:
188 p = "NO";
189 break;
190 case FORM_UNFORMATTED:
191 p = "YES";
192 break;
193 default:
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;
211 else
212 *iqp->nextrec = 0;
215 if ((cf & IOPARM_INQUIRE_HAS_BLANK) != 0)
217 if (u == NULL || u->flags.form != FORM_FORMATTED)
218 p = undefined;
219 else
220 switch (u->flags.blank)
222 case BLANK_NULL:
223 p = "NULL";
224 break;
225 case BLANK_ZERO:
226 p = "ZERO";
227 break;
228 default:
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)
238 p = undefined;
239 else
240 switch (u->flags.pad)
242 case PAD_YES:
243 p = "YES";
244 break;
245 case PAD_NO:
246 p = "NO";
247 break;
248 default:
249 internal_error (&iqp->common, "inquire_via_unit(): Bad pad");
252 cf_strcpy (iqp->pad, iqp->pad_len, p);
255 if (cf & IOPARM_INQUIRE_HAS_FLAGS2)
257 if ((cf2 & IOPARM_INQUIRE_HAS_PENDING) != 0)
258 *iqp->pending = 0;
260 if ((cf2 & IOPARM_INQUIRE_HAS_ID) != 0)
261 *iqp->id = 0;
263 if ((cf2 & IOPARM_INQUIRE_HAS_ENCODING) != 0)
265 if (u == NULL || u->flags.form != FORM_FORMATTED)
266 p = undefined;
267 else
268 switch (u->flags.encoding)
270 case ENCODING_DEFAULT:
271 p = "UNKNOWN";
272 break;
273 case ENCODING_UTF8:
274 p = "UTF-8";
275 break;
276 default:
277 internal_error (&iqp->common, "inquire_via_unit(): Bad encoding");
280 cf_strcpy (iqp->encoding, iqp->encoding_len, p);
283 if ((cf2 & IOPARM_INQUIRE_HAS_DECIMAL) != 0)
285 if (u == NULL || u->flags.form != FORM_FORMATTED)
286 p = undefined;
287 else
288 switch (u->flags.decimal)
290 case DECIMAL_POINT:
291 p = "POINT";
292 break;
293 case DECIMAL_COMMA:
294 p = "COMMA";
295 break;
296 default:
297 internal_error (&iqp->common, "inquire_via_unit(): Bad comma");
300 cf_strcpy (iqp->decimal, iqp->decimal_len, p);
303 if ((cf2 & IOPARM_INQUIRE_HAS_ASYNCHRONOUS) != 0)
305 if (u == NULL)
306 p = undefined;
307 else
308 switch (u->flags.async)
310 case ASYNC_YES:
311 p = "YES";
312 break;
313 case ASYNC_NO:
314 p = "NO";
315 break;
316 default:
317 internal_error (&iqp->common, "inquire_via_unit(): Bad async");
320 cf_strcpy (iqp->asynchronous, iqp->asynchronous_len, p);
323 if ((cf2 & IOPARM_INQUIRE_HAS_SIGN) != 0)
325 if (u == NULL)
326 p = undefined;
327 else
328 switch (u->flags.sign)
330 case SIGN_PROCDEFINED:
331 p = "PROCESSOR_DEFINED";
332 break;
333 case SIGN_SUPPRESS:
334 p = "SUPPRESS";
335 break;
336 case SIGN_PLUS:
337 p = "PLUS";
338 break;
339 default:
340 internal_error (&iqp->common, "inquire_via_unit(): Bad sign");
343 cf_strcpy (iqp->sign, iqp->sign_len, p);
346 if ((cf2 & IOPARM_INQUIRE_HAS_ROUND) != 0)
348 if (u == NULL)
349 p = undefined;
350 else
351 switch (u->flags.round)
353 case ROUND_UP:
354 p = "UP";
355 break;
356 case ROUND_DOWN:
357 p = "DOWN";
358 break;
359 case ROUND_ZERO:
360 p = "ZERO";
361 break;
362 case ROUND_NEAREST:
363 p = "NEAREST";
364 break;
365 case ROUND_COMPATIBLE:
366 p = "COMPATIBLE";
367 break;
368 case ROUND_PROCDEFINED:
369 p = "PROCESSOR_DEFINED";
370 break;
371 default:
372 internal_error (&iqp->common, "inquire_via_unit(): Bad round");
375 cf_strcpy (iqp->round, iqp->round_len, p);
379 if ((cf & IOPARM_INQUIRE_HAS_POSITION) != 0)
381 if (u == NULL || u->flags.access == ACCESS_DIRECT)
382 p = undefined;
383 else
384 switch (u->flags.position)
386 case POSITION_REWIND:
387 p = "REWIND";
388 break;
389 case POSITION_APPEND:
390 p = "APPEND";
391 break;
392 case POSITION_ASIS:
393 p = "ASIS";
394 break;
395 default:
396 /* if not direct access, it must be
397 either REWIND, APPEND, or ASIS.
398 ASIS seems to be the best default */
399 p = "ASIS";
400 break;
402 cf_strcpy (iqp->position, iqp->position_len, p);
405 if ((cf & IOPARM_INQUIRE_HAS_ACTION) != 0)
407 if (u == NULL)
408 p = undefined;
409 else
410 switch (u->flags.action)
412 case ACTION_READ:
413 p = "READ";
414 break;
415 case ACTION_WRITE:
416 p = "WRITE";
417 break;
418 case ACTION_READWRITE:
419 p = "READWRITE";
420 break;
421 default:
422 internal_error (&iqp->common, "inquire_via_unit(): Bad action");
425 cf_strcpy (iqp->action, iqp->action_len, p);
428 if ((cf & IOPARM_INQUIRE_HAS_READ) != 0)
430 p = (u == NULL) ? inquire_read (NULL, 0) :
431 inquire_read (u->file, u->file_len);
433 cf_strcpy (iqp->read, iqp->read_len, p);
436 if ((cf & IOPARM_INQUIRE_HAS_WRITE) != 0)
438 p = (u == NULL) ? inquire_write (NULL, 0) :
439 inquire_write (u->file, u->file_len);
441 cf_strcpy (iqp->write, iqp->write_len, p);
444 if ((cf & IOPARM_INQUIRE_HAS_READWRITE) != 0)
446 p = (u == NULL) ? inquire_readwrite (NULL, 0) :
447 inquire_readwrite (u->file, u->file_len);
449 cf_strcpy (iqp->readwrite, iqp->readwrite_len, p);
452 if ((cf & IOPARM_INQUIRE_HAS_DELIM) != 0)
454 if (u == NULL || u->flags.form != FORM_FORMATTED)
455 p = undefined;
456 else
457 switch (u->flags.delim)
459 case DELIM_NONE:
460 p = "NONE";
461 break;
462 case DELIM_QUOTE:
463 p = "QUOTE";
464 break;
465 case DELIM_APOSTROPHE:
466 p = "APOSTROPHE";
467 break;
468 default:
469 internal_error (&iqp->common, "inquire_via_unit(): Bad delim");
472 cf_strcpy (iqp->delim, iqp->delim_len, p);
475 if ((cf & IOPARM_INQUIRE_HAS_PAD) != 0)
477 if (u == NULL || u->flags.form != FORM_FORMATTED)
478 p = undefined;
479 else
480 switch (u->flags.pad)
482 case PAD_NO:
483 p = "NO";
484 break;
485 case PAD_YES:
486 p = "YES";
487 break;
488 default:
489 internal_error (&iqp->common, "inquire_via_unit(): Bad pad");
492 cf_strcpy (iqp->pad, iqp->pad_len, p);
495 if ((cf & IOPARM_INQUIRE_HAS_CONVERT) != 0)
497 if (u == NULL)
498 p = undefined;
499 else
500 switch (u->flags.convert)
502 /* big_endian is 0 for little-endian, 1 for big-endian. */
503 case GFC_CONVERT_NATIVE:
504 p = big_endian ? "BIG_ENDIAN" : "LITTLE_ENDIAN";
505 break;
507 case GFC_CONVERT_SWAP:
508 p = big_endian ? "LITTLE_ENDIAN" : "BIG_ENDIAN";
509 break;
511 default:
512 internal_error (&iqp->common, "inquire_via_unit(): Bad convert");
515 cf_strcpy (iqp->convert, iqp->convert_len, p);
520 /* inquire_via_filename()-- Inquiry via filename. This subroutine is
521 * only used if the filename is *not* connected to a unit number. */
523 static void
524 inquire_via_filename (st_parameter_inquire *iqp)
526 const char *p;
527 GFC_INTEGER_4 cf = iqp->common.flags;
528 GFC_INTEGER_4 cf2 = iqp->flags2;
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)
534 *iqp->opened = 0;
536 if ((cf & IOPARM_INQUIRE_HAS_NUMBER) != 0)
537 *iqp->number = -1;
539 if ((cf & IOPARM_INQUIRE_HAS_NAMED) != 0)
540 *iqp->named = 1;
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)
550 p = "UNKNOWN";
551 cf_strcpy (iqp->sequential, iqp->sequential_len, p);
554 if ((cf & IOPARM_INQUIRE_HAS_DIRECT) != 0)
556 p = "UNKNOWN";
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)
565 p = "UNKNOWN";
566 cf_strcpy (iqp->formatted, iqp->formatted_len, p);
569 if ((cf & IOPARM_INQUIRE_HAS_UNFORMATTED) != 0)
571 p = "UNKNOWN";
572 cf_strcpy (iqp->unformatted, iqp->unformatted_len, p);
575 if ((cf & IOPARM_INQUIRE_HAS_RECL_OUT) != 0)
576 *iqp->recl_out = 0;
578 if ((cf & IOPARM_INQUIRE_HAS_NEXTREC) != 0)
579 *iqp->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 if ((cf2 & IOPARM_INQUIRE_HAS_ENCODING) != 0)
590 cf_strcpy (iqp->encoding, iqp->encoding_len, undefined);
592 if ((cf2 & IOPARM_INQUIRE_HAS_DELIM) != 0)
593 cf_strcpy (iqp->delim, iqp->delim_len, undefined);
595 if ((cf2 & IOPARM_INQUIRE_HAS_DECIMAL) != 0)
596 cf_strcpy (iqp->decimal, iqp->decimal_len, undefined);
598 if ((cf2 & IOPARM_INQUIRE_HAS_DELIM) != 0)
599 cf_strcpy (iqp->delim, iqp->delim_len, undefined);
601 if ((cf2 & IOPARM_INQUIRE_HAS_PAD) != 0)
602 cf_strcpy (iqp->pad, iqp->pad_len, undefined);
604 if ((cf2 & IOPARM_INQUIRE_HAS_ENCODING) != 0)
605 cf_strcpy (iqp->encoding, iqp->encoding_len, undefined);
608 if ((cf & IOPARM_INQUIRE_HAS_POSITION) != 0)
609 cf_strcpy (iqp->position, iqp->position_len, undefined);
611 if ((cf & IOPARM_INQUIRE_HAS_ACCESS) != 0)
612 cf_strcpy (iqp->access, iqp->access_len, undefined);
614 if ((cf & IOPARM_INQUIRE_HAS_READ) != 0)
616 p = inquire_read (iqp->file, iqp->file_len);
617 cf_strcpy (iqp->read, iqp->read_len, p);
620 if ((cf & IOPARM_INQUIRE_HAS_WRITE) != 0)
622 p = inquire_write (iqp->file, iqp->file_len);
623 cf_strcpy (iqp->write, iqp->write_len, p);
626 if ((cf & IOPARM_INQUIRE_HAS_READWRITE) != 0)
628 p = inquire_read (iqp->file, iqp->file_len);
629 cf_strcpy (iqp->readwrite, iqp->readwrite_len, p);
634 /* Library entry point for the INQUIRE statement (non-IOLENGTH
635 form). */
637 extern void st_inquire (st_parameter_inquire *);
638 export_proto(st_inquire);
640 void
641 st_inquire (st_parameter_inquire *iqp)
643 gfc_unit *u;
645 library_start (&iqp->common);
647 if ((iqp->common.flags & IOPARM_INQUIRE_HAS_FILE) == 0)
649 u = find_unit (iqp->common.unit);
650 inquire_via_unit (iqp, u);
652 else
654 u = find_file (iqp->file, iqp->file_len);
655 if (u == NULL)
656 inquire_via_filename (iqp);
657 else
658 inquire_via_unit (iqp, u);
660 if (u != NULL)
661 unlock_unit (u);
663 library_end ();