Home | History | Annotate | Line # | Download | only in io
      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