PR 53796 Improve INQUIRE(RECL=...) handling
[official-gcc.git] / libgfortran / io / inquire.c
blob848a08f61571a2561977af8824a7f4e90c7afc4a
1 /* Copyright (C) 2002-2017 Free Software Foundation, Inc.
2 Contributed by Andy Vaught
4 This file is part of the GNU Fortran 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 3, or (at your option)
9 any later version.
11 Libgfortran is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 Under Section 7 of GPL version 3, you are granted additional
17 permissions described in the GCC Runtime Library Exception, version
18 3.1, as published by the Free Software Foundation.
20 You should have received a copy of the GNU General Public License and
21 a copy of the GCC Runtime Library Exception along with this program;
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 <http://www.gnu.org/licenses/>. */
26 /* Implement the non-IOLENGTH variant of the INQUIRY statement */
28 #include "io.h"
29 #include "unix.h"
30 #include <string.h>
33 static const char yes[] = "YES", no[] = "NO", undefined[] = "UNDEFINED";
36 /* inquire_via_unit()-- Inquiry via unit number. The unit might not exist. */
38 static void
39 inquire_via_unit (st_parameter_inquire *iqp, gfc_unit *u)
41 const char *p;
42 GFC_INTEGER_4 cf = iqp->common.flags;
44 if (iqp->common.unit == GFC_INTERNAL_UNIT ||
45 iqp->common.unit == GFC_INTERNAL_UNIT4 ||
46 (u != NULL && u->internal_unit_kind != 0))
47 generate_error (&iqp->common, LIBERROR_INQUIRE_INTERNAL_UNIT, NULL);
49 if ((cf & IOPARM_INQUIRE_HAS_EXIST) != 0)
50 *iqp->exist = (u != NULL) || (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)
64 #if defined(HAVE_TTYNAME_R) || defined(HAVE_TTYNAME)
65 if (u->unit_number == options.stdin_unit
66 || u->unit_number == options.stdout_unit
67 || u->unit_number == options.stderr_unit)
69 int err = stream_ttyname (u->s, iqp->name, iqp->name_len);
70 if (err == 0)
72 gfc_charlen_type tmplen = strlen (iqp->name);
73 if (iqp->name_len > tmplen)
74 memset (&iqp->name[tmplen], ' ', iqp->name_len - tmplen);
76 else /* If ttyname does not work, go with the default. */
77 cf_strcpy (iqp->name, iqp->name_len, u->filename);
79 else
80 cf_strcpy (iqp->name, iqp->name_len, u->filename);
81 #elif defined __MINGW32__
82 if (u->unit_number == options.stdin_unit)
83 fstrcpy (iqp->name, iqp->name_len, "CONIN$", sizeof("CONIN$"));
84 else if (u->unit_number == options.stdout_unit)
85 fstrcpy (iqp->name, iqp->name_len, "CONOUT$", sizeof("CONOUT$"));
86 else if (u->unit_number == options.stderr_unit)
87 fstrcpy (iqp->name, iqp->name_len, "CONERR$", sizeof("CONERR$"));
88 else
89 cf_strcpy (iqp->name, iqp->name_len, u->filename);
90 #else
91 cf_strcpy (iqp->name, iqp->name_len, u->filename);
92 #endif
95 if ((cf & IOPARM_INQUIRE_HAS_ACCESS) != 0)
97 if (u == NULL)
98 p = undefined;
99 else
100 switch (u->flags.access)
102 case ACCESS_SEQUENTIAL:
103 p = "SEQUENTIAL";
104 break;
105 case ACCESS_DIRECT:
106 p = "DIRECT";
107 break;
108 case ACCESS_STREAM:
109 p = "STREAM";
110 break;
111 default:
112 internal_error (&iqp->common, "inquire_via_unit(): Bad access");
115 cf_strcpy (iqp->access, iqp->access_len, p);
118 if ((cf & IOPARM_INQUIRE_HAS_SEQUENTIAL) != 0)
120 if (u == NULL)
121 p = inquire_sequential (NULL, 0);
122 else
123 switch (u->flags.access)
125 case ACCESS_DIRECT:
126 case ACCESS_STREAM:
127 p = no;
128 break;
129 case ACCESS_SEQUENTIAL:
130 p = yes;
131 break;
132 default:
133 internal_error (&iqp->common, "inquire_via_unit(): Bad access");
136 cf_strcpy (iqp->sequential, iqp->sequential_len, p);
139 if ((cf & IOPARM_INQUIRE_HAS_DIRECT) != 0)
141 if (u == NULL)
142 p = inquire_direct (NULL, 0);
143 else
144 switch (u->flags.access)
146 case ACCESS_SEQUENTIAL:
147 case ACCESS_STREAM:
148 p = no;
149 break;
150 case ACCESS_DIRECT:
151 p = yes;
152 break;
153 default:
154 internal_error (&iqp->common, "inquire_via_unit(): Bad access");
157 cf_strcpy (iqp->direct, iqp->direct_len, p);
160 if ((cf & IOPARM_INQUIRE_HAS_FORM) != 0)
162 if (u == NULL)
163 p = undefined;
164 else
165 switch (u->flags.form)
167 case FORM_FORMATTED:
168 p = "FORMATTED";
169 break;
170 case FORM_UNFORMATTED:
171 p = "UNFORMATTED";
172 break;
173 default:
174 internal_error (&iqp->common, "inquire_via_unit(): Bad form");
177 cf_strcpy (iqp->form, iqp->form_len, p);
180 if ((cf & IOPARM_INQUIRE_HAS_FORMATTED) != 0)
182 if (u == NULL)
183 p = inquire_formatted (NULL, 0);
184 else
185 switch (u->flags.form)
187 case FORM_FORMATTED:
188 p = yes;
189 break;
190 case FORM_UNFORMATTED:
191 p = no;
192 break;
193 default:
194 internal_error (&iqp->common, "inquire_via_unit(): Bad form");
197 cf_strcpy (iqp->formatted, iqp->formatted_len, p);
200 if ((cf & IOPARM_INQUIRE_HAS_UNFORMATTED) != 0)
202 if (u == NULL)
203 p = inquire_unformatted (NULL, 0);
204 else
205 switch (u->flags.form)
207 case FORM_FORMATTED:
208 p = no;
209 break;
210 case FORM_UNFORMATTED:
211 p = yes;
212 break;
213 default:
214 internal_error (&iqp->common, "inquire_via_unit(): Bad form");
217 cf_strcpy (iqp->unformatted, iqp->unformatted_len, p);
220 if ((cf & IOPARM_INQUIRE_HAS_RECL_OUT) != 0)
221 /* F2018 (N2137) 12.10.2.26: If there is no connection, recl is
222 assigned the value -1. */
223 *iqp->recl_out = (u != NULL) ? u->recl : -1;
225 if ((cf & IOPARM_INQUIRE_HAS_STRM_POS_OUT) != 0)
226 *iqp->strm_pos_out = (u != NULL) ? u->strm_pos : 0;
228 if ((cf & IOPARM_INQUIRE_HAS_NEXTREC) != 0)
230 /* This only makes sense in the context of DIRECT access. */
231 if (u != NULL && u->flags.access == ACCESS_DIRECT)
232 *iqp->nextrec = u->last_record + 1;
233 else
234 *iqp->nextrec = 0;
237 if ((cf & IOPARM_INQUIRE_HAS_BLANK) != 0)
239 if (u == NULL || u->flags.form != FORM_FORMATTED)
240 p = undefined;
241 else
242 switch (u->flags.blank)
244 case BLANK_NULL:
245 p = "NULL";
246 break;
247 case BLANK_ZERO:
248 p = "ZERO";
249 break;
250 default:
251 internal_error (&iqp->common, "inquire_via_unit(): Bad blank");
254 cf_strcpy (iqp->blank, iqp->blank_len, p);
257 if ((cf & IOPARM_INQUIRE_HAS_PAD) != 0)
259 if (u == NULL || u->flags.form != FORM_FORMATTED)
260 p = undefined;
261 else
262 switch (u->flags.pad)
264 case PAD_YES:
265 p = yes;
266 break;
267 case PAD_NO:
268 p = no;
269 break;
270 default:
271 internal_error (&iqp->common, "inquire_via_unit(): Bad pad");
274 cf_strcpy (iqp->pad, iqp->pad_len, p);
277 if (cf & IOPARM_INQUIRE_HAS_FLAGS2)
279 GFC_INTEGER_4 cf2 = iqp->flags2;
281 if ((cf2 & IOPARM_INQUIRE_HAS_PENDING) != 0)
282 *iqp->pending = 0;
284 if ((cf2 & IOPARM_INQUIRE_HAS_ID) != 0)
285 *iqp->id = 0;
287 if ((cf2 & IOPARM_INQUIRE_HAS_ENCODING) != 0)
289 if (u == NULL || u->flags.form != FORM_FORMATTED)
290 p = undefined;
291 else
292 switch (u->flags.encoding)
294 case ENCODING_DEFAULT:
295 p = "UNKNOWN";
296 break;
297 case ENCODING_UTF8:
298 p = "UTF-8";
299 break;
300 default:
301 internal_error (&iqp->common, "inquire_via_unit(): Bad encoding");
304 cf_strcpy (iqp->encoding, iqp->encoding_len, p);
307 if ((cf2 & IOPARM_INQUIRE_HAS_DECIMAL) != 0)
309 if (u == NULL || u->flags.form != FORM_FORMATTED)
310 p = undefined;
311 else
312 switch (u->flags.decimal)
314 case DECIMAL_POINT:
315 p = "POINT";
316 break;
317 case DECIMAL_COMMA:
318 p = "COMMA";
319 break;
320 default:
321 internal_error (&iqp->common, "inquire_via_unit(): Bad comma");
324 cf_strcpy (iqp->decimal, iqp->decimal_len, p);
327 if ((cf2 & IOPARM_INQUIRE_HAS_ASYNCHRONOUS) != 0)
329 if (u == NULL)
330 p = undefined;
331 else
332 switch (u->flags.async)
334 case ASYNC_YES:
335 p = yes;
336 break;
337 case ASYNC_NO:
338 p = no;
339 break;
340 default:
341 internal_error (&iqp->common, "inquire_via_unit(): Bad async");
344 cf_strcpy (iqp->asynchronous, iqp->asynchronous_len, p);
347 if ((cf2 & IOPARM_INQUIRE_HAS_SIGN) != 0)
349 if (u == NULL)
350 p = undefined;
351 else
352 switch (u->flags.sign)
354 case SIGN_PROCDEFINED:
355 p = "PROCESSOR_DEFINED";
356 break;
357 case SIGN_SUPPRESS:
358 p = "SUPPRESS";
359 break;
360 case SIGN_PLUS:
361 p = "PLUS";
362 break;
363 default:
364 internal_error (&iqp->common, "inquire_via_unit(): Bad sign");
367 cf_strcpy (iqp->sign, iqp->sign_len, p);
370 if ((cf2 & IOPARM_INQUIRE_HAS_ROUND) != 0)
372 if (u == NULL)
373 p = undefined;
374 else
375 switch (u->flags.round)
377 case ROUND_UP:
378 p = "UP";
379 break;
380 case ROUND_DOWN:
381 p = "DOWN";
382 break;
383 case ROUND_ZERO:
384 p = "ZERO";
385 break;
386 case ROUND_NEAREST:
387 p = "NEAREST";
388 break;
389 case ROUND_COMPATIBLE:
390 p = "COMPATIBLE";
391 break;
392 case ROUND_PROCDEFINED:
393 p = "PROCESSOR_DEFINED";
394 break;
395 default:
396 internal_error (&iqp->common, "inquire_via_unit(): Bad round");
399 cf_strcpy (iqp->round, iqp->round_len, p);
402 if ((cf2 & IOPARM_INQUIRE_HAS_SIZE) != 0)
404 if (u == NULL)
405 *iqp->size = -1;
406 else
408 sflush (u->s);
409 *iqp->size = ssize (u->s);
413 if ((cf2 & IOPARM_INQUIRE_HAS_IQSTREAM) != 0)
415 if (u == NULL)
416 p = "UNKNOWN";
417 else
418 switch (u->flags.access)
420 case ACCESS_SEQUENTIAL:
421 case ACCESS_DIRECT:
422 p = no;
423 break;
424 case ACCESS_STREAM:
425 p = yes;
426 break;
427 default:
428 internal_error (&iqp->common, "inquire_via_unit(): Bad pad");
431 cf_strcpy (iqp->iqstream, iqp->iqstream_len, p);
434 if ((cf2 & IOPARM_INQUIRE_HAS_SHARE) != 0)
436 if (u == NULL)
437 p = "UNKNOWN";
438 else
439 switch (u->flags.share)
441 case SHARE_DENYRW:
442 p = "DENYRW";
443 break;
444 case SHARE_DENYNONE:
445 p = "DENYNONE";
446 break;
447 case SHARE_UNSPECIFIED:
448 p = "NODENY";
449 break;
450 default:
451 internal_error (&iqp->common,
452 "inquire_via_unit(): Bad share");
453 break;
456 cf_strcpy (iqp->share, iqp->share_len, p);
459 if ((cf2 & IOPARM_INQUIRE_HAS_CC) != 0)
461 if (u == NULL)
462 p = "UNKNOWN";
463 else
464 switch (u->flags.cc)
466 case CC_FORTRAN:
467 p = "FORTRAN";
468 break;
469 case CC_LIST:
470 p = "LIST";
471 break;
472 case CC_NONE:
473 p = "NONE";
474 break;
475 case CC_UNSPECIFIED:
476 p = "UNKNOWN";
477 break;
478 default:
479 internal_error (&iqp->common, "inquire_via_unit(): Bad cc");
480 break;
483 cf_strcpy (iqp->cc, iqp->cc_len, p);
487 if ((cf & IOPARM_INQUIRE_HAS_POSITION) != 0)
489 if (u == NULL || u->flags.access == ACCESS_DIRECT)
490 p = undefined;
491 else
493 /* If the position is unspecified, check if we can figure
494 out whether it's at the beginning or end. */
495 if (u->flags.position == POSITION_UNSPECIFIED)
497 gfc_offset cur = stell (u->s);
498 if (cur == 0)
499 u->flags.position = POSITION_REWIND;
500 else if (cur != -1 && (ssize (u->s) == cur))
501 u->flags.position = POSITION_APPEND;
503 switch (u->flags.position)
505 case POSITION_REWIND:
506 p = "REWIND";
507 break;
508 case POSITION_APPEND:
509 p = "APPEND";
510 break;
511 case POSITION_ASIS:
512 p = "ASIS";
513 break;
514 default:
515 /* If the position has changed and is not rewind or
516 append, it must be set to a processor-dependent
517 value. */
518 p = "UNSPECIFIED";
519 break;
522 cf_strcpy (iqp->position, iqp->position_len, p);
525 if ((cf & IOPARM_INQUIRE_HAS_ACTION) != 0)
527 if (u == NULL)
528 p = undefined;
529 else
530 switch (u->flags.action)
532 case ACTION_READ:
533 p = "READ";
534 break;
535 case ACTION_WRITE:
536 p = "WRITE";
537 break;
538 case ACTION_READWRITE:
539 p = "READWRITE";
540 break;
541 default:
542 internal_error (&iqp->common, "inquire_via_unit(): Bad action");
545 cf_strcpy (iqp->action, iqp->action_len, p);
548 if ((cf & IOPARM_INQUIRE_HAS_READ) != 0)
550 p = (!u || u->flags.action == ACTION_WRITE) ? no : yes;
551 cf_strcpy (iqp->read, iqp->read_len, p);
554 if ((cf & IOPARM_INQUIRE_HAS_WRITE) != 0)
556 p = (!u || u->flags.action == ACTION_READ) ? no : yes;
557 cf_strcpy (iqp->write, iqp->write_len, p);
560 if ((cf & IOPARM_INQUIRE_HAS_READWRITE) != 0)
562 p = (!u || u->flags.action != ACTION_READWRITE) ? no : yes;
563 cf_strcpy (iqp->readwrite, iqp->readwrite_len, p);
566 if ((cf & IOPARM_INQUIRE_HAS_DELIM) != 0)
568 if (u == NULL || u->flags.form != FORM_FORMATTED)
569 p = undefined;
570 else
571 switch (u->flags.delim)
573 case DELIM_NONE:
574 case DELIM_UNSPECIFIED:
575 p = "NONE";
576 break;
577 case DELIM_QUOTE:
578 p = "QUOTE";
579 break;
580 case DELIM_APOSTROPHE:
581 p = "APOSTROPHE";
582 break;
583 default:
584 internal_error (&iqp->common, "inquire_via_unit(): Bad delim");
587 cf_strcpy (iqp->delim, iqp->delim_len, p);
590 if ((cf & IOPARM_INQUIRE_HAS_PAD) != 0)
592 if (u == NULL || u->flags.form != FORM_FORMATTED)
593 p = undefined;
594 else
595 switch (u->flags.pad)
597 case PAD_NO:
598 p = no;
599 break;
600 case PAD_YES:
601 p = yes;
602 break;
603 default:
604 internal_error (&iqp->common, "inquire_via_unit(): Bad pad");
607 cf_strcpy (iqp->pad, iqp->pad_len, p);
610 if ((cf & IOPARM_INQUIRE_HAS_CONVERT) != 0)
612 if (u == NULL)
613 p = undefined;
614 else
615 switch (u->flags.convert)
617 case GFC_CONVERT_NATIVE:
618 p = __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ? "BIG_ENDIAN" : "LITTLE_ENDIAN";
619 break;
621 case GFC_CONVERT_SWAP:
622 p = __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ? "LITTLE_ENDIAN" : "BIG_ENDIAN";
623 break;
625 default:
626 internal_error (&iqp->common, "inquire_via_unit(): Bad convert");
629 cf_strcpy (iqp->convert, iqp->convert_len, p);
634 /* inquire_via_filename()-- Inquiry via filename. This subroutine is
635 only used if the filename is *not* connected to a unit number. */
637 static void
638 inquire_via_filename (st_parameter_inquire *iqp)
640 const char *p;
641 GFC_INTEGER_4 cf = iqp->common.flags;
643 if ((cf & IOPARM_INQUIRE_HAS_EXIST) != 0)
644 *iqp->exist = file_exists (iqp->file, iqp->file_len);
646 if ((cf & IOPARM_INQUIRE_HAS_OPENED) != 0)
647 *iqp->opened = 0;
649 if ((cf & IOPARM_INQUIRE_HAS_NUMBER) != 0)
650 *iqp->number = -1;
652 if ((cf & IOPARM_INQUIRE_HAS_NAMED) != 0)
653 *iqp->named = 1;
655 if ((cf & IOPARM_INQUIRE_HAS_NAME) != 0)
656 fstrcpy (iqp->name, iqp->name_len, iqp->file, iqp->file_len);
658 if ((cf & IOPARM_INQUIRE_HAS_ACCESS) != 0)
659 cf_strcpy (iqp->access, iqp->access_len, undefined);
661 if ((cf & IOPARM_INQUIRE_HAS_SEQUENTIAL) != 0)
663 p = "UNKNOWN";
664 cf_strcpy (iqp->sequential, iqp->sequential_len, p);
667 if ((cf & IOPARM_INQUIRE_HAS_DIRECT) != 0)
669 p = "UNKNOWN";
670 cf_strcpy (iqp->direct, iqp->direct_len, p);
673 if ((cf & IOPARM_INQUIRE_HAS_FORM) != 0)
674 cf_strcpy (iqp->form, iqp->form_len, undefined);
676 if ((cf & IOPARM_INQUIRE_HAS_FORMATTED) != 0)
678 p = "UNKNOWN";
679 cf_strcpy (iqp->formatted, iqp->formatted_len, p);
682 if ((cf & IOPARM_INQUIRE_HAS_UNFORMATTED) != 0)
684 p = "UNKNOWN";
685 cf_strcpy (iqp->unformatted, iqp->unformatted_len, p);
688 if ((cf & IOPARM_INQUIRE_HAS_RECL_OUT) != 0)
689 *iqp->recl_out = 0;
691 if ((cf & IOPARM_INQUIRE_HAS_NEXTREC) != 0)
692 *iqp->nextrec = 0;
694 if ((cf & IOPARM_INQUIRE_HAS_BLANK) != 0)
695 cf_strcpy (iqp->blank, iqp->blank_len, undefined);
697 if ((cf & IOPARM_INQUIRE_HAS_PAD) != 0)
698 cf_strcpy (iqp->pad, iqp->pad_len, undefined);
700 if (cf & IOPARM_INQUIRE_HAS_FLAGS2)
702 GFC_INTEGER_4 cf2 = iqp->flags2;
704 if ((cf2 & IOPARM_INQUIRE_HAS_ENCODING) != 0)
705 cf_strcpy (iqp->encoding, iqp->encoding_len, undefined);
707 if ((cf2 & IOPARM_INQUIRE_HAS_DELIM) != 0)
708 cf_strcpy (iqp->delim, iqp->delim_len, undefined);
710 if ((cf2 & IOPARM_INQUIRE_HAS_DECIMAL) != 0)
711 cf_strcpy (iqp->decimal, iqp->decimal_len, undefined);
713 if ((cf2 & IOPARM_INQUIRE_HAS_DELIM) != 0)
714 cf_strcpy (iqp->delim, iqp->delim_len, undefined);
716 if ((cf2 & IOPARM_INQUIRE_HAS_PAD) != 0)
717 cf_strcpy (iqp->pad, iqp->pad_len, undefined);
719 if ((cf2 & IOPARM_INQUIRE_HAS_ENCODING) != 0)
720 cf_strcpy (iqp->encoding, iqp->encoding_len, undefined);
722 if ((cf2 & IOPARM_INQUIRE_HAS_SIZE) != 0)
723 *iqp->size = file_size (iqp->file, iqp->file_len);
725 if ((cf2 & IOPARM_INQUIRE_HAS_IQSTREAM) != 0)
726 cf_strcpy (iqp->iqstream, iqp->iqstream_len, "UNKNOWN");
728 if ((cf2 & IOPARM_INQUIRE_HAS_SHARE) != 0)
729 cf_strcpy (iqp->share, iqp->share_len, "UNKNOWN");
731 if ((cf2 & IOPARM_INQUIRE_HAS_CC) != 0)
732 cf_strcpy (iqp->cc, iqp->cc_len, "UNKNOWN");
735 if ((cf & IOPARM_INQUIRE_HAS_POSITION) != 0)
736 cf_strcpy (iqp->position, iqp->position_len, undefined);
738 if ((cf & IOPARM_INQUIRE_HAS_ACCESS) != 0)
739 cf_strcpy (iqp->access, iqp->access_len, undefined);
741 if ((cf & IOPARM_INQUIRE_HAS_READ) != 0)
743 p = inquire_read (iqp->file, iqp->file_len);
744 cf_strcpy (iqp->read, iqp->read_len, p);
747 if ((cf & IOPARM_INQUIRE_HAS_WRITE) != 0)
749 p = inquire_write (iqp->file, iqp->file_len);
750 cf_strcpy (iqp->write, iqp->write_len, p);
753 if ((cf & IOPARM_INQUIRE_HAS_READWRITE) != 0)
755 p = inquire_read (iqp->file, iqp->file_len);
756 cf_strcpy (iqp->readwrite, iqp->readwrite_len, p);
761 /* Library entry point for the INQUIRE statement (non-IOLENGTH
762 form). */
764 extern void st_inquire (st_parameter_inquire *);
765 export_proto(st_inquire);
767 void
768 st_inquire (st_parameter_inquire *iqp)
770 gfc_unit *u;
772 library_start (&iqp->common);
774 if ((iqp->common.flags & IOPARM_INQUIRE_HAS_FILE) == 0)
776 u = find_unit (iqp->common.unit);
777 inquire_via_unit (iqp, u);
779 else
781 u = find_file (iqp->file, iqp->file_len);
782 if (u == NULL)
783 inquire_via_filename (iqp);
784 else
785 inquire_via_unit (iqp, u);
787 if (u != NULL)
788 unlock_unit (u);
790 library_end ();