inquire.c revision 1.1.1.4 1 1.1.1.4 mrg /* Copyright (C) 2002-2024 Free Software Foundation, Inc.
2 1.1 mrg Contributed by Andy Vaught
3 1.1 mrg
4 1.1 mrg This file is part of the GNU Fortran runtime library (libgfortran).
5 1.1 mrg
6 1.1 mrg Libgfortran is free software; you can redistribute it and/or modify
7 1.1 mrg it under the terms of the GNU General Public License as published by
8 1.1 mrg the Free Software Foundation; either version 3, or (at your option)
9 1.1 mrg any later version.
10 1.1 mrg
11 1.1 mrg Libgfortran is distributed in the hope that it will be useful,
12 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 1.1 mrg GNU General Public License for more details.
15 1.1 mrg
16 1.1 mrg Under Section 7 of GPL version 3, you are granted additional
17 1.1 mrg permissions described in the GCC Runtime Library Exception, version
18 1.1 mrg 3.1, as published by the Free Software Foundation.
19 1.1 mrg
20 1.1 mrg You should have received a copy of the GNU General Public License and
21 1.1 mrg a copy of the GCC Runtime Library Exception along with this program;
22 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 1.1 mrg <http://www.gnu.org/licenses/>. */
24 1.1 mrg
25 1.1 mrg
26 1.1 mrg /* Implement the non-IOLENGTH variant of the INQUIRY statement */
27 1.1 mrg
28 1.1 mrg #include "io.h"
29 1.1 mrg #include "async.h"
30 1.1 mrg #include "unix.h"
31 1.1 mrg #include <string.h>
32 1.1 mrg
33 1.1 mrg
34 1.1 mrg static const char yes[] = "YES", no[] = "NO", undefined[] = "UNDEFINED";
35 1.1 mrg
36 1.1 mrg
37 1.1 mrg /* inquire_via_unit()-- Inquiry via unit number. The unit might not exist. */
38 1.1 mrg
39 1.1 mrg static void
40 1.1 mrg inquire_via_unit (st_parameter_inquire *iqp, gfc_unit *u)
41 1.1 mrg {
42 1.1 mrg const char *p;
43 1.1 mrg GFC_INTEGER_4 cf = iqp->common.flags;
44 1.1 mrg
45 1.1 mrg if (iqp->common.unit == GFC_INTERNAL_UNIT ||
46 1.1 mrg iqp->common.unit == GFC_INTERNAL_UNIT4 ||
47 1.1 mrg (u != NULL && u->internal_unit_kind != 0))
48 1.1 mrg generate_error (&iqp->common, LIBERROR_INQUIRE_INTERNAL_UNIT, NULL);
49 1.1 mrg
50 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_EXIST) != 0)
51 1.1 mrg *iqp->exist = (u != NULL &&
52 1.1 mrg iqp->common.unit != GFC_INTERNAL_UNIT &&
53 1.1 mrg iqp->common.unit != GFC_INTERNAL_UNIT4)
54 1.1 mrg || (iqp->common.unit >= 0);
55 1.1 mrg
56 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_OPENED) != 0)
57 1.1 mrg *iqp->opened = (u != NULL);
58 1.1 mrg
59 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_NUMBER) != 0)
60 1.1 mrg *iqp->number = (u != NULL) ? u->unit_number : -1;
61 1.1 mrg
62 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_NAMED) != 0)
63 1.1 mrg *iqp->named = (u != NULL && u->flags.status != STATUS_SCRATCH);
64 1.1 mrg
65 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_NAME) != 0
66 1.1 mrg && u != NULL && u->flags.status != STATUS_SCRATCH)
67 1.1 mrg {
68 1.1 mrg #if defined(HAVE_TTYNAME_R) || defined(HAVE_TTYNAME)
69 1.1 mrg if (u->unit_number == options.stdin_unit
70 1.1 mrg || u->unit_number == options.stdout_unit
71 1.1 mrg || u->unit_number == options.stderr_unit)
72 1.1 mrg {
73 1.1 mrg int err = stream_ttyname (u->s, iqp->name, iqp->name_len);
74 1.1 mrg if (err == 0)
75 1.1 mrg {
76 1.1 mrg gfc_charlen_type tmplen = strlen (iqp->name);
77 1.1 mrg if (iqp->name_len > tmplen)
78 1.1 mrg memset (&iqp->name[tmplen], ' ', iqp->name_len - tmplen);
79 1.1 mrg }
80 1.1 mrg else /* If ttyname does not work, go with the default. */
81 1.1 mrg cf_strcpy (iqp->name, iqp->name_len, u->filename);
82 1.1 mrg }
83 1.1 mrg else
84 1.1 mrg cf_strcpy (iqp->name, iqp->name_len, u->filename);
85 1.1 mrg #elif defined __MINGW32__
86 1.1 mrg if (u->unit_number == options.stdin_unit)
87 1.1 mrg fstrcpy (iqp->name, iqp->name_len, "CONIN$", sizeof("CONIN$"));
88 1.1 mrg else if (u->unit_number == options.stdout_unit)
89 1.1 mrg fstrcpy (iqp->name, iqp->name_len, "CONOUT$", sizeof("CONOUT$"));
90 1.1 mrg else if (u->unit_number == options.stderr_unit)
91 1.1 mrg fstrcpy (iqp->name, iqp->name_len, "CONERR$", sizeof("CONERR$"));
92 1.1 mrg else
93 1.1 mrg cf_strcpy (iqp->name, iqp->name_len, u->filename);
94 1.1 mrg #else
95 1.1 mrg cf_strcpy (iqp->name, iqp->name_len, u->filename);
96 1.1 mrg #endif
97 1.1 mrg }
98 1.1 mrg
99 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_ACCESS) != 0)
100 1.1 mrg {
101 1.1 mrg if (u == NULL)
102 1.1 mrg p = undefined;
103 1.1 mrg else
104 1.1 mrg switch (u->flags.access)
105 1.1 mrg {
106 1.1 mrg case ACCESS_SEQUENTIAL:
107 1.1 mrg p = "SEQUENTIAL";
108 1.1 mrg break;
109 1.1 mrg case ACCESS_DIRECT:
110 1.1 mrg p = "DIRECT";
111 1.1 mrg break;
112 1.1 mrg case ACCESS_STREAM:
113 1.1 mrg p = "STREAM";
114 1.1 mrg break;
115 1.1 mrg default:
116 1.1 mrg internal_error (&iqp->common, "inquire_via_unit(): Bad access");
117 1.1 mrg }
118 1.1 mrg
119 1.1 mrg cf_strcpy (iqp->access, iqp->access_len, p);
120 1.1 mrg }
121 1.1 mrg
122 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_SEQUENTIAL) != 0)
123 1.1 mrg {
124 1.1 mrg if (u == NULL)
125 1.1 mrg p = inquire_sequential (NULL, 0);
126 1.1 mrg else
127 1.1 mrg switch (u->flags.access)
128 1.1 mrg {
129 1.1 mrg case ACCESS_DIRECT:
130 1.1 mrg case ACCESS_STREAM:
131 1.1 mrg p = no;
132 1.1 mrg break;
133 1.1 mrg case ACCESS_SEQUENTIAL:
134 1.1 mrg p = yes;
135 1.1 mrg break;
136 1.1 mrg default:
137 1.1 mrg internal_error (&iqp->common, "inquire_via_unit(): Bad access");
138 1.1 mrg }
139 1.1 mrg
140 1.1 mrg cf_strcpy (iqp->sequential, iqp->sequential_len, p);
141 1.1 mrg }
142 1.1 mrg
143 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_DIRECT) != 0)
144 1.1 mrg {
145 1.1 mrg if (u == NULL)
146 1.1 mrg p = inquire_direct (NULL, 0);
147 1.1 mrg else
148 1.1 mrg switch (u->flags.access)
149 1.1 mrg {
150 1.1 mrg case ACCESS_SEQUENTIAL:
151 1.1 mrg case ACCESS_STREAM:
152 1.1 mrg p = no;
153 1.1 mrg break;
154 1.1 mrg case ACCESS_DIRECT:
155 1.1 mrg p = yes;
156 1.1 mrg break;
157 1.1 mrg default:
158 1.1 mrg internal_error (&iqp->common, "inquire_via_unit(): Bad access");
159 1.1 mrg }
160 1.1 mrg
161 1.1 mrg cf_strcpy (iqp->direct, iqp->direct_len, p);
162 1.1 mrg }
163 1.1 mrg
164 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_FORM) != 0)
165 1.1 mrg {
166 1.1 mrg if (u == NULL)
167 1.1 mrg p = undefined;
168 1.1 mrg else
169 1.1 mrg switch (u->flags.form)
170 1.1 mrg {
171 1.1 mrg case FORM_FORMATTED:
172 1.1 mrg p = "FORMATTED";
173 1.1 mrg break;
174 1.1 mrg case FORM_UNFORMATTED:
175 1.1 mrg p = "UNFORMATTED";
176 1.1 mrg break;
177 1.1 mrg default:
178 1.1 mrg internal_error (&iqp->common, "inquire_via_unit(): Bad form");
179 1.1 mrg }
180 1.1 mrg
181 1.1 mrg cf_strcpy (iqp->form, iqp->form_len, p);
182 1.1 mrg }
183 1.1 mrg
184 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_FORMATTED) != 0)
185 1.1 mrg {
186 1.1 mrg if (u == NULL)
187 1.1 mrg p = inquire_formatted (NULL, 0);
188 1.1 mrg else
189 1.1 mrg switch (u->flags.form)
190 1.1 mrg {
191 1.1 mrg case FORM_FORMATTED:
192 1.1 mrg p = yes;
193 1.1 mrg break;
194 1.1 mrg case FORM_UNFORMATTED:
195 1.1 mrg p = no;
196 1.1 mrg break;
197 1.1 mrg default:
198 1.1 mrg internal_error (&iqp->common, "inquire_via_unit(): Bad form");
199 1.1 mrg }
200 1.1 mrg
201 1.1 mrg cf_strcpy (iqp->formatted, iqp->formatted_len, p);
202 1.1 mrg }
203 1.1 mrg
204 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_UNFORMATTED) != 0)
205 1.1 mrg {
206 1.1 mrg if (u == NULL)
207 1.1 mrg p = inquire_unformatted (NULL, 0);
208 1.1 mrg else
209 1.1 mrg switch (u->flags.form)
210 1.1 mrg {
211 1.1 mrg case FORM_FORMATTED:
212 1.1 mrg p = no;
213 1.1 mrg break;
214 1.1 mrg case FORM_UNFORMATTED:
215 1.1 mrg p = yes;
216 1.1 mrg break;
217 1.1 mrg default:
218 1.1 mrg internal_error (&iqp->common, "inquire_via_unit(): Bad form");
219 1.1 mrg }
220 1.1 mrg
221 1.1 mrg cf_strcpy (iqp->unformatted, iqp->unformatted_len, p);
222 1.1 mrg }
223 1.1 mrg
224 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_RECL_OUT) != 0)
225 1.1 mrg /* F2018 (N2137) 12.10.2.26: If there is no connection, recl is
226 1.1 mrg assigned the value -1. */
227 1.1 mrg *iqp->recl_out = (u != NULL) ? u->recl : -1;
228 1.1 mrg
229 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_STRM_POS_OUT) != 0)
230 1.1 mrg *iqp->strm_pos_out = (u != NULL) ? u->strm_pos : 0;
231 1.1 mrg
232 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_NEXTREC) != 0)
233 1.1 mrg {
234 1.1 mrg /* This only makes sense in the context of DIRECT access. */
235 1.1 mrg if (u != NULL && u->flags.access == ACCESS_DIRECT)
236 1.1 mrg *iqp->nextrec = u->last_record + 1;
237 1.1 mrg else
238 1.1 mrg *iqp->nextrec = 0;
239 1.1 mrg }
240 1.1 mrg
241 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_BLANK) != 0)
242 1.1 mrg {
243 1.1 mrg if (u == NULL || u->flags.form != FORM_FORMATTED)
244 1.1 mrg p = undefined;
245 1.1 mrg else
246 1.1 mrg switch (u->flags.blank)
247 1.1 mrg {
248 1.1 mrg case BLANK_NULL:
249 1.1 mrg p = "NULL";
250 1.1 mrg break;
251 1.1 mrg case BLANK_ZERO:
252 1.1 mrg p = "ZERO";
253 1.1 mrg break;
254 1.1 mrg default:
255 1.1 mrg internal_error (&iqp->common, "inquire_via_unit(): Bad blank");
256 1.1 mrg }
257 1.1 mrg
258 1.1 mrg cf_strcpy (iqp->blank, iqp->blank_len, p);
259 1.1 mrg }
260 1.1 mrg
261 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_PAD) != 0)
262 1.1 mrg {
263 1.1 mrg if (u == NULL || u->flags.form != FORM_FORMATTED)
264 1.1 mrg p = undefined;
265 1.1 mrg else
266 1.1 mrg switch (u->flags.pad)
267 1.1 mrg {
268 1.1 mrg case PAD_YES:
269 1.1 mrg p = yes;
270 1.1 mrg break;
271 1.1 mrg case PAD_NO:
272 1.1 mrg p = no;
273 1.1 mrg break;
274 1.1 mrg default:
275 1.1 mrg internal_error (&iqp->common, "inquire_via_unit(): Bad pad");
276 1.1 mrg }
277 1.1 mrg
278 1.1 mrg cf_strcpy (iqp->pad, iqp->pad_len, p);
279 1.1 mrg }
280 1.1 mrg
281 1.1 mrg if (cf & IOPARM_INQUIRE_HAS_FLAGS2)
282 1.1 mrg {
283 1.1 mrg GFC_INTEGER_4 cf2 = iqp->flags2;
284 1.1 mrg
285 1.1 mrg if ((cf2 & IOPARM_INQUIRE_HAS_ENCODING) != 0)
286 1.1 mrg {
287 1.1 mrg if (u == NULL || u->flags.form != FORM_FORMATTED)
288 1.1 mrg p = undefined;
289 1.1 mrg else
290 1.1 mrg switch (u->flags.encoding)
291 1.1 mrg {
292 1.1 mrg case ENCODING_DEFAULT:
293 1.1 mrg p = "UNKNOWN";
294 1.1 mrg break;
295 1.1 mrg case ENCODING_UTF8:
296 1.1 mrg p = "UTF-8";
297 1.1 mrg break;
298 1.1 mrg default:
299 1.1 mrg internal_error (&iqp->common, "inquire_via_unit(): Bad encoding");
300 1.1 mrg }
301 1.1 mrg
302 1.1 mrg cf_strcpy (iqp->encoding, iqp->encoding_len, p);
303 1.1 mrg }
304 1.1 mrg
305 1.1 mrg if ((cf2 & IOPARM_INQUIRE_HAS_DECIMAL) != 0)
306 1.1 mrg {
307 1.1 mrg if (u == NULL || u->flags.form != FORM_FORMATTED)
308 1.1 mrg p = undefined;
309 1.1 mrg else
310 1.1 mrg switch (u->flags.decimal)
311 1.1 mrg {
312 1.1 mrg case DECIMAL_POINT:
313 1.1 mrg p = "POINT";
314 1.1 mrg break;
315 1.1 mrg case DECIMAL_COMMA:
316 1.1 mrg p = "COMMA";
317 1.1 mrg break;
318 1.1 mrg default:
319 1.1 mrg internal_error (&iqp->common, "inquire_via_unit(): Bad comma");
320 1.1 mrg }
321 1.1 mrg
322 1.1 mrg cf_strcpy (iqp->decimal, iqp->decimal_len, p);
323 1.1 mrg }
324 1.1 mrg
325 1.1 mrg if ((cf2 & IOPARM_INQUIRE_HAS_ASYNCHRONOUS) != 0)
326 1.1 mrg {
327 1.1 mrg if (u == NULL)
328 1.1 mrg p = undefined;
329 1.1 mrg else
330 1.1 mrg {
331 1.1 mrg switch (u->flags.async)
332 1.1 mrg {
333 1.1 mrg case ASYNC_YES:
334 1.1 mrg p = yes;
335 1.1 mrg break;
336 1.1 mrg case ASYNC_NO:
337 1.1 mrg p = no;
338 1.1 mrg break;
339 1.1 mrg default:
340 1.1 mrg internal_error (&iqp->common, "inquire_via_unit(): Bad async");
341 1.1 mrg }
342 1.1 mrg }
343 1.1 mrg cf_strcpy (iqp->asynchronous, iqp->asynchronous_len, p);
344 1.1 mrg }
345 1.1 mrg
346 1.1 mrg if ((cf2 & IOPARM_INQUIRE_HAS_PENDING) != 0)
347 1.1 mrg {
348 1.1 mrg if (!ASYNC_IO || u->au == NULL)
349 1.1 mrg *(iqp->pending) = 0;
350 1.1 mrg else
351 1.1 mrg {
352 1.1 mrg LOCK (&(u->au->lock));
353 1.1 mrg if ((cf2 & IOPARM_INQUIRE_HAS_ID) != 0)
354 1.1 mrg {
355 1.1 mrg int id;
356 1.1 mrg id = *(iqp->id);
357 1.1 mrg *(iqp->pending) = id > u->au->id.low;
358 1.1 mrg }
359 1.1 mrg else
360 1.1 mrg {
361 1.1 mrg *(iqp->pending) = ! u->au->empty;
362 1.1 mrg }
363 1.1 mrg UNLOCK (&(u->au->lock));
364 1.1 mrg }
365 1.1 mrg }
366 1.1 mrg
367 1.1 mrg if ((cf2 & IOPARM_INQUIRE_HAS_SIGN) != 0)
368 1.1 mrg {
369 1.1 mrg if (u == NULL)
370 1.1 mrg p = undefined;
371 1.1 mrg else
372 1.1 mrg switch (u->flags.sign)
373 1.1 mrg {
374 1.1 mrg case SIGN_PROCDEFINED:
375 1.1 mrg p = "PROCESSOR_DEFINED";
376 1.1 mrg break;
377 1.1 mrg case SIGN_SUPPRESS:
378 1.1 mrg p = "SUPPRESS";
379 1.1 mrg break;
380 1.1 mrg case SIGN_PLUS:
381 1.1 mrg p = "PLUS";
382 1.1 mrg break;
383 1.1 mrg default:
384 1.1 mrg internal_error (&iqp->common, "inquire_via_unit(): Bad sign");
385 1.1 mrg }
386 1.1 mrg
387 1.1 mrg cf_strcpy (iqp->sign, iqp->sign_len, p);
388 1.1 mrg }
389 1.1 mrg
390 1.1 mrg if ((cf2 & IOPARM_INQUIRE_HAS_ROUND) != 0)
391 1.1 mrg {
392 1.1 mrg if (u == NULL)
393 1.1 mrg p = undefined;
394 1.1 mrg else
395 1.1 mrg switch (u->flags.round)
396 1.1 mrg {
397 1.1 mrg case ROUND_UP:
398 1.1 mrg p = "UP";
399 1.1 mrg break;
400 1.1 mrg case ROUND_DOWN:
401 1.1 mrg p = "DOWN";
402 1.1 mrg break;
403 1.1 mrg case ROUND_ZERO:
404 1.1 mrg p = "ZERO";
405 1.1 mrg break;
406 1.1 mrg case ROUND_NEAREST:
407 1.1 mrg p = "NEAREST";
408 1.1 mrg break;
409 1.1 mrg case ROUND_COMPATIBLE:
410 1.1 mrg p = "COMPATIBLE";
411 1.1 mrg break;
412 1.1 mrg case ROUND_PROCDEFINED:
413 1.1 mrg p = "PROCESSOR_DEFINED";
414 1.1 mrg break;
415 1.1 mrg default:
416 1.1 mrg internal_error (&iqp->common, "inquire_via_unit(): Bad round");
417 1.1 mrg }
418 1.1 mrg
419 1.1 mrg cf_strcpy (iqp->round, iqp->round_len, p);
420 1.1 mrg }
421 1.1 mrg
422 1.1 mrg if ((cf2 & IOPARM_INQUIRE_HAS_SIZE) != 0)
423 1.1 mrg {
424 1.1 mrg if (u == NULL)
425 1.1 mrg *iqp->size = -1;
426 1.1 mrg else
427 1.1 mrg {
428 1.1 mrg sflush (u->s);
429 1.1 mrg *iqp->size = ssize (u->s);
430 1.1 mrg }
431 1.1 mrg }
432 1.1 mrg
433 1.1 mrg if ((cf2 & IOPARM_INQUIRE_HAS_IQSTREAM) != 0)
434 1.1 mrg {
435 1.1 mrg if (u == NULL)
436 1.1 mrg p = "UNKNOWN";
437 1.1 mrg else
438 1.1 mrg switch (u->flags.access)
439 1.1 mrg {
440 1.1 mrg case ACCESS_SEQUENTIAL:
441 1.1 mrg case ACCESS_DIRECT:
442 1.1 mrg p = no;
443 1.1 mrg break;
444 1.1 mrg case ACCESS_STREAM:
445 1.1 mrg p = yes;
446 1.1 mrg break;
447 1.1 mrg default:
448 1.1 mrg internal_error (&iqp->common, "inquire_via_unit(): Bad pad");
449 1.1 mrg }
450 1.1 mrg
451 1.1 mrg cf_strcpy (iqp->iqstream, iqp->iqstream_len, p);
452 1.1 mrg }
453 1.1 mrg
454 1.1 mrg if ((cf2 & IOPARM_INQUIRE_HAS_SHARE) != 0)
455 1.1 mrg {
456 1.1 mrg if (u == NULL)
457 1.1 mrg p = "UNKNOWN";
458 1.1 mrg else
459 1.1 mrg switch (u->flags.share)
460 1.1 mrg {
461 1.1 mrg case SHARE_DENYRW:
462 1.1 mrg p = "DENYRW";
463 1.1 mrg break;
464 1.1 mrg case SHARE_DENYNONE:
465 1.1 mrg p = "DENYNONE";
466 1.1 mrg break;
467 1.1 mrg case SHARE_UNSPECIFIED:
468 1.1 mrg p = "NODENY";
469 1.1 mrg break;
470 1.1 mrg default:
471 1.1 mrg internal_error (&iqp->common,
472 1.1 mrg "inquire_via_unit(): Bad share");
473 1.1 mrg break;
474 1.1 mrg }
475 1.1 mrg
476 1.1 mrg cf_strcpy (iqp->share, iqp->share_len, p);
477 1.1 mrg }
478 1.1 mrg
479 1.1 mrg if ((cf2 & IOPARM_INQUIRE_HAS_CC) != 0)
480 1.1 mrg {
481 1.1 mrg if (u == NULL)
482 1.1 mrg p = "UNKNOWN";
483 1.1 mrg else
484 1.1 mrg switch (u->flags.cc)
485 1.1 mrg {
486 1.1 mrg case CC_FORTRAN:
487 1.1 mrg p = "FORTRAN";
488 1.1 mrg break;
489 1.1 mrg case CC_LIST:
490 1.1 mrg p = "LIST";
491 1.1 mrg break;
492 1.1 mrg case CC_NONE:
493 1.1 mrg p = "NONE";
494 1.1 mrg break;
495 1.1 mrg case CC_UNSPECIFIED:
496 1.1 mrg p = "UNKNOWN";
497 1.1 mrg break;
498 1.1 mrg default:
499 1.1 mrg internal_error (&iqp->common, "inquire_via_unit(): Bad cc");
500 1.1 mrg break;
501 1.1 mrg }
502 1.1 mrg
503 1.1 mrg cf_strcpy (iqp->cc, iqp->cc_len, p);
504 1.1 mrg }
505 1.1 mrg }
506 1.1 mrg
507 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_POSITION) != 0)
508 1.1 mrg {
509 1.1 mrg if (u == NULL || u->flags.access == ACCESS_DIRECT)
510 1.1 mrg p = undefined;
511 1.1 mrg else
512 1.1 mrg {
513 1.1 mrg /* If the position is unspecified, check if we can figure
514 1.1 mrg out whether it's at the beginning or end. */
515 1.1 mrg if (u->flags.position == POSITION_UNSPECIFIED)
516 1.1 mrg {
517 1.1 mrg gfc_offset cur = stell (u->s);
518 1.1 mrg if (cur == 0)
519 1.1 mrg u->flags.position = POSITION_REWIND;
520 1.1 mrg else if (cur != -1 && (ssize (u->s) == cur))
521 1.1 mrg u->flags.position = POSITION_APPEND;
522 1.1 mrg }
523 1.1 mrg switch (u->flags.position)
524 1.1 mrg {
525 1.1 mrg case POSITION_REWIND:
526 1.1 mrg p = "REWIND";
527 1.1 mrg break;
528 1.1 mrg case POSITION_APPEND:
529 1.1 mrg p = "APPEND";
530 1.1 mrg break;
531 1.1 mrg case POSITION_ASIS:
532 1.1 mrg p = "ASIS";
533 1.1 mrg break;
534 1.1 mrg default:
535 1.1 mrg /* If the position has changed and is not rewind or
536 1.1 mrg append, it must be set to a processor-dependent
537 1.1 mrg value. */
538 1.1 mrg p = "UNSPECIFIED";
539 1.1 mrg break;
540 1.1 mrg }
541 1.1 mrg }
542 1.1 mrg cf_strcpy (iqp->position, iqp->position_len, p);
543 1.1 mrg }
544 1.1 mrg
545 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_ACTION) != 0)
546 1.1 mrg {
547 1.1 mrg if (u == NULL)
548 1.1 mrg p = undefined;
549 1.1 mrg else
550 1.1 mrg switch (u->flags.action)
551 1.1 mrg {
552 1.1 mrg case ACTION_READ:
553 1.1 mrg p = "READ";
554 1.1 mrg break;
555 1.1 mrg case ACTION_WRITE:
556 1.1 mrg p = "WRITE";
557 1.1 mrg break;
558 1.1 mrg case ACTION_READWRITE:
559 1.1 mrg p = "READWRITE";
560 1.1 mrg break;
561 1.1 mrg default:
562 1.1 mrg internal_error (&iqp->common, "inquire_via_unit(): Bad action");
563 1.1 mrg }
564 1.1 mrg
565 1.1 mrg cf_strcpy (iqp->action, iqp->action_len, p);
566 1.1 mrg }
567 1.1 mrg
568 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_READ) != 0)
569 1.1 mrg {
570 1.1 mrg p = (!u || u->flags.action == ACTION_WRITE) ? no : yes;
571 1.1 mrg cf_strcpy (iqp->read, iqp->read_len, p);
572 1.1 mrg }
573 1.1 mrg
574 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_WRITE) != 0)
575 1.1 mrg {
576 1.1 mrg p = (!u || u->flags.action == ACTION_READ) ? no : yes;
577 1.1 mrg cf_strcpy (iqp->write, iqp->write_len, p);
578 1.1 mrg }
579 1.1 mrg
580 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_READWRITE) != 0)
581 1.1 mrg {
582 1.1 mrg p = (!u || u->flags.action != ACTION_READWRITE) ? no : yes;
583 1.1 mrg cf_strcpy (iqp->readwrite, iqp->readwrite_len, p);
584 1.1 mrg }
585 1.1 mrg
586 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_DELIM) != 0)
587 1.1 mrg {
588 1.1 mrg if (u == NULL || u->flags.form != FORM_FORMATTED)
589 1.1 mrg p = undefined;
590 1.1 mrg else
591 1.1 mrg switch (u->flags.delim)
592 1.1 mrg {
593 1.1 mrg case DELIM_NONE:
594 1.1 mrg case DELIM_UNSPECIFIED:
595 1.1 mrg p = "NONE";
596 1.1 mrg break;
597 1.1 mrg case DELIM_QUOTE:
598 1.1 mrg p = "QUOTE";
599 1.1 mrg break;
600 1.1 mrg case DELIM_APOSTROPHE:
601 1.1 mrg p = "APOSTROPHE";
602 1.1 mrg break;
603 1.1 mrg default:
604 1.1 mrg internal_error (&iqp->common, "inquire_via_unit(): Bad delim");
605 1.1 mrg }
606 1.1 mrg
607 1.1 mrg cf_strcpy (iqp->delim, iqp->delim_len, p);
608 1.1 mrg }
609 1.1 mrg
610 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_PAD) != 0)
611 1.1 mrg {
612 1.1 mrg if (u == NULL || u->flags.form != FORM_FORMATTED)
613 1.1 mrg p = undefined;
614 1.1 mrg else
615 1.1 mrg switch (u->flags.pad)
616 1.1 mrg {
617 1.1 mrg case PAD_NO:
618 1.1 mrg p = no;
619 1.1 mrg break;
620 1.1 mrg case PAD_YES:
621 1.1 mrg p = yes;
622 1.1 mrg break;
623 1.1 mrg default:
624 1.1 mrg internal_error (&iqp->common, "inquire_via_unit(): Bad pad");
625 1.1 mrg }
626 1.1 mrg
627 1.1 mrg cf_strcpy (iqp->pad, iqp->pad_len, p);
628 1.1 mrg }
629 1.1 mrg
630 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_CONVERT) != 0)
631 1.1 mrg {
632 1.1 mrg if (u == NULL)
633 1.1 mrg p = undefined;
634 1.1 mrg else
635 1.1 mrg switch (u->flags.convert)
636 1.1 mrg {
637 1.1 mrg case GFC_CONVERT_NATIVE:
638 1.1 mrg p = __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ? "BIG_ENDIAN" : "LITTLE_ENDIAN";
639 1.1 mrg break;
640 1.1 mrg
641 1.1 mrg case GFC_CONVERT_SWAP:
642 1.1 mrg p = __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ? "LITTLE_ENDIAN" : "BIG_ENDIAN";
643 1.1 mrg break;
644 1.1 mrg
645 1.1.1.3 mrg #ifdef HAVE_GFC_REAL_17
646 1.1.1.3 mrg case GFC_CONVERT_NATIVE | GFC_CONVERT_R16_IEEE:
647 1.1.1.3 mrg p = __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ? "BIG_ENDIAN,R16_IEEE" : "LITTLE_ENDIAN,R16_IEEE";
648 1.1.1.3 mrg break;
649 1.1.1.3 mrg
650 1.1.1.3 mrg case GFC_CONVERT_SWAP | GFC_CONVERT_R16_IEEE:
651 1.1.1.3 mrg p = __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ? "LITTLE_ENDIAN,R16_IEEE" : "BIG_ENDIAN,R16_IEEE";
652 1.1.1.3 mrg break;
653 1.1.1.3 mrg
654 1.1.1.3 mrg case GFC_CONVERT_NATIVE | GFC_CONVERT_R16_IBM:
655 1.1.1.3 mrg p = __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ? "BIG_ENDIAN,R16_IBM" : "LITTLE_ENDIAN,R16_IBM";
656 1.1.1.3 mrg break;
657 1.1.1.3 mrg
658 1.1.1.3 mrg case GFC_CONVERT_SWAP | GFC_CONVERT_R16_IBM:
659 1.1.1.3 mrg p = __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ? "LITTLE_ENDIAN,R16_IBM" : "BIG_ENDIAN,R16_IBM";
660 1.1.1.3 mrg break;
661 1.1.1.3 mrg #endif
662 1.1.1.3 mrg
663 1.1 mrg default:
664 1.1 mrg internal_error (&iqp->common, "inquire_via_unit(): Bad convert");
665 1.1 mrg }
666 1.1 mrg
667 1.1 mrg cf_strcpy (iqp->convert, iqp->convert_len, p);
668 1.1 mrg }
669 1.1 mrg }
670 1.1 mrg
671 1.1 mrg
672 1.1 mrg /* inquire_via_filename()-- Inquiry via filename. This subroutine is
673 1.1 mrg only used if the filename is *not* connected to a unit number. */
674 1.1 mrg
675 1.1 mrg static void
676 1.1 mrg inquire_via_filename (st_parameter_inquire *iqp)
677 1.1 mrg {
678 1.1 mrg const char *p;
679 1.1 mrg GFC_INTEGER_4 cf = iqp->common.flags;
680 1.1 mrg
681 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_EXIST) != 0)
682 1.1 mrg *iqp->exist = file_exists (iqp->file, iqp->file_len);
683 1.1 mrg
684 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_OPENED) != 0)
685 1.1 mrg *iqp->opened = 0;
686 1.1 mrg
687 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_NUMBER) != 0)
688 1.1 mrg *iqp->number = -1;
689 1.1 mrg
690 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_NAMED) != 0)
691 1.1 mrg *iqp->named = 1;
692 1.1 mrg
693 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_NAME) != 0)
694 1.1 mrg fstrcpy (iqp->name, iqp->name_len, iqp->file, iqp->file_len);
695 1.1 mrg
696 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_ACCESS) != 0)
697 1.1 mrg cf_strcpy (iqp->access, iqp->access_len, undefined);
698 1.1 mrg
699 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_SEQUENTIAL) != 0)
700 1.1 mrg {
701 1.1 mrg p = "UNKNOWN";
702 1.1 mrg cf_strcpy (iqp->sequential, iqp->sequential_len, p);
703 1.1 mrg }
704 1.1 mrg
705 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_DIRECT) != 0)
706 1.1 mrg {
707 1.1 mrg p = "UNKNOWN";
708 1.1 mrg cf_strcpy (iqp->direct, iqp->direct_len, p);
709 1.1 mrg }
710 1.1 mrg
711 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_FORM) != 0)
712 1.1 mrg cf_strcpy (iqp->form, iqp->form_len, undefined);
713 1.1 mrg
714 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_FORMATTED) != 0)
715 1.1 mrg {
716 1.1 mrg p = "UNKNOWN";
717 1.1 mrg cf_strcpy (iqp->formatted, iqp->formatted_len, p);
718 1.1 mrg }
719 1.1 mrg
720 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_UNFORMATTED) != 0)
721 1.1 mrg {
722 1.1 mrg p = "UNKNOWN";
723 1.1 mrg cf_strcpy (iqp->unformatted, iqp->unformatted_len, p);
724 1.1 mrg }
725 1.1 mrg
726 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_RECL_OUT) != 0)
727 1.1.1.2 mrg /* F2018 (N2137) 12.10.2.26: If there is no connection, recl is
728 1.1.1.2 mrg assigned the value -1. */
729 1.1.1.2 mrg *iqp->recl_out = -1;
730 1.1 mrg
731 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_NEXTREC) != 0)
732 1.1 mrg *iqp->nextrec = 0;
733 1.1 mrg
734 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_BLANK) != 0)
735 1.1 mrg cf_strcpy (iqp->blank, iqp->blank_len, undefined);
736 1.1 mrg
737 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_PAD) != 0)
738 1.1 mrg cf_strcpy (iqp->pad, iqp->pad_len, undefined);
739 1.1 mrg
740 1.1 mrg if (cf & IOPARM_INQUIRE_HAS_FLAGS2)
741 1.1 mrg {
742 1.1 mrg GFC_INTEGER_4 cf2 = iqp->flags2;
743 1.1 mrg
744 1.1 mrg if ((cf2 & IOPARM_INQUIRE_HAS_ENCODING) != 0)
745 1.1 mrg cf_strcpy (iqp->encoding, iqp->encoding_len, undefined);
746 1.1 mrg
747 1.1 mrg if ((cf2 & IOPARM_INQUIRE_HAS_DELIM) != 0)
748 1.1 mrg cf_strcpy (iqp->delim, iqp->delim_len, undefined);
749 1.1 mrg
750 1.1 mrg if ((cf2 & IOPARM_INQUIRE_HAS_DECIMAL) != 0)
751 1.1 mrg cf_strcpy (iqp->decimal, iqp->decimal_len, undefined);
752 1.1 mrg
753 1.1 mrg if ((cf2 & IOPARM_INQUIRE_HAS_DELIM) != 0)
754 1.1 mrg cf_strcpy (iqp->delim, iqp->delim_len, undefined);
755 1.1 mrg
756 1.1 mrg if ((cf2 & IOPARM_INQUIRE_HAS_PAD) != 0)
757 1.1 mrg cf_strcpy (iqp->pad, iqp->pad_len, undefined);
758 1.1 mrg
759 1.1 mrg if ((cf2 & IOPARM_INQUIRE_HAS_ENCODING) != 0)
760 1.1 mrg cf_strcpy (iqp->encoding, iqp->encoding_len, undefined);
761 1.1 mrg
762 1.1 mrg if ((cf2 & IOPARM_INQUIRE_HAS_SIZE) != 0)
763 1.1 mrg *iqp->size = file_size (iqp->file, iqp->file_len);
764 1.1 mrg
765 1.1 mrg if ((cf2 & IOPARM_INQUIRE_HAS_IQSTREAM) != 0)
766 1.1 mrg cf_strcpy (iqp->iqstream, iqp->iqstream_len, "UNKNOWN");
767 1.1 mrg
768 1.1 mrg if ((cf2 & IOPARM_INQUIRE_HAS_SHARE) != 0)
769 1.1 mrg cf_strcpy (iqp->share, iqp->share_len, "UNKNOWN");
770 1.1 mrg
771 1.1 mrg if ((cf2 & IOPARM_INQUIRE_HAS_CC) != 0)
772 1.1 mrg cf_strcpy (iqp->cc, iqp->cc_len, "UNKNOWN");
773 1.1 mrg }
774 1.1 mrg
775 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_POSITION) != 0)
776 1.1 mrg cf_strcpy (iqp->position, iqp->position_len, undefined);
777 1.1 mrg
778 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_ACCESS) != 0)
779 1.1 mrg cf_strcpy (iqp->access, iqp->access_len, undefined);
780 1.1 mrg
781 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_READ) != 0)
782 1.1 mrg {
783 1.1 mrg p = inquire_read (iqp->file, iqp->file_len);
784 1.1 mrg cf_strcpy (iqp->read, iqp->read_len, p);
785 1.1 mrg }
786 1.1 mrg
787 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_WRITE) != 0)
788 1.1 mrg {
789 1.1 mrg p = inquire_write (iqp->file, iqp->file_len);
790 1.1 mrg cf_strcpy (iqp->write, iqp->write_len, p);
791 1.1 mrg }
792 1.1 mrg
793 1.1 mrg if ((cf & IOPARM_INQUIRE_HAS_READWRITE) != 0)
794 1.1 mrg {
795 1.1 mrg p = inquire_read (iqp->file, iqp->file_len);
796 1.1 mrg cf_strcpy (iqp->readwrite, iqp->readwrite_len, p);
797 1.1 mrg }
798 1.1 mrg }
799 1.1 mrg
800 1.1 mrg
801 1.1 mrg /* Library entry point for the INQUIRE statement (non-IOLENGTH
802 1.1 mrg form). */
803 1.1 mrg
804 1.1 mrg extern void st_inquire (st_parameter_inquire *);
805 1.1 mrg export_proto(st_inquire);
806 1.1 mrg
807 1.1 mrg void
808 1.1 mrg st_inquire (st_parameter_inquire *iqp)
809 1.1 mrg {
810 1.1 mrg gfc_unit *u;
811 1.1 mrg
812 1.1 mrg library_start (&iqp->common);
813 1.1 mrg
814 1.1 mrg if ((iqp->common.flags & IOPARM_INQUIRE_HAS_FILE) == 0)
815 1.1 mrg {
816 1.1 mrg u = find_unit (iqp->common.unit);
817 1.1 mrg inquire_via_unit (iqp, u);
818 1.1 mrg }
819 1.1 mrg else
820 1.1 mrg {
821 1.1 mrg u = find_file (iqp->file, iqp->file_len);
822 1.1 mrg if (u == NULL)
823 1.1 mrg inquire_via_filename (iqp);
824 1.1 mrg else
825 1.1 mrg inquire_via_unit (iqp, u);
826 1.1 mrg }
827 1.1 mrg if (u != NULL)
828 1.1 mrg unlock_unit (u);
829 1.1 mrg
830 1.1 mrg library_end ();
831 1.1 mrg }
832