1 1.1.1.3 mrg /* Copyright (C) 2002-2022 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