Home | History | Annotate | Line # | Download | only in io
inquire.c revision 1.1.1.1
      1  1.1  mrg /* Copyright (C) 2002-2019 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  mrg 	  default:
    646  1.1  mrg 	    internal_error (&iqp->common, "inquire_via_unit(): Bad convert");
    647  1.1  mrg 	  }
    648  1.1  mrg 
    649  1.1  mrg       cf_strcpy (iqp->convert, iqp->convert_len, p);
    650  1.1  mrg     }
    651  1.1  mrg }
    652  1.1  mrg 
    653  1.1  mrg 
    654  1.1  mrg /* inquire_via_filename()-- Inquiry via filename.  This subroutine is
    655  1.1  mrg    only used if the filename is *not* connected to a unit number. */
    656  1.1  mrg 
    657  1.1  mrg static void
    658  1.1  mrg inquire_via_filename (st_parameter_inquire *iqp)
    659  1.1  mrg {
    660  1.1  mrg   const char *p;
    661  1.1  mrg   GFC_INTEGER_4 cf = iqp->common.flags;
    662  1.1  mrg 
    663  1.1  mrg   if ((cf & IOPARM_INQUIRE_HAS_EXIST) != 0)
    664  1.1  mrg     *iqp->exist = file_exists (iqp->file, iqp->file_len);
    665  1.1  mrg 
    666  1.1  mrg   if ((cf & IOPARM_INQUIRE_HAS_OPENED) != 0)
    667  1.1  mrg     *iqp->opened = 0;
    668  1.1  mrg 
    669  1.1  mrg   if ((cf & IOPARM_INQUIRE_HAS_NUMBER) != 0)
    670  1.1  mrg     *iqp->number = -1;
    671  1.1  mrg 
    672  1.1  mrg   if ((cf & IOPARM_INQUIRE_HAS_NAMED) != 0)
    673  1.1  mrg     *iqp->named = 1;
    674  1.1  mrg 
    675  1.1  mrg   if ((cf & IOPARM_INQUIRE_HAS_NAME) != 0)
    676  1.1  mrg     fstrcpy (iqp->name, iqp->name_len, iqp->file, iqp->file_len);
    677  1.1  mrg 
    678  1.1  mrg   if ((cf & IOPARM_INQUIRE_HAS_ACCESS) != 0)
    679  1.1  mrg     cf_strcpy (iqp->access, iqp->access_len, undefined);
    680  1.1  mrg 
    681  1.1  mrg   if ((cf & IOPARM_INQUIRE_HAS_SEQUENTIAL) != 0)
    682  1.1  mrg     {
    683  1.1  mrg       p = "UNKNOWN";
    684  1.1  mrg       cf_strcpy (iqp->sequential, iqp->sequential_len, p);
    685  1.1  mrg     }
    686  1.1  mrg 
    687  1.1  mrg   if ((cf & IOPARM_INQUIRE_HAS_DIRECT) != 0)
    688  1.1  mrg     {
    689  1.1  mrg       p = "UNKNOWN";
    690  1.1  mrg       cf_strcpy (iqp->direct, iqp->direct_len, p);
    691  1.1  mrg     }
    692  1.1  mrg 
    693  1.1  mrg   if ((cf & IOPARM_INQUIRE_HAS_FORM) != 0)
    694  1.1  mrg     cf_strcpy (iqp->form, iqp->form_len, undefined);
    695  1.1  mrg 
    696  1.1  mrg   if ((cf & IOPARM_INQUIRE_HAS_FORMATTED) != 0)
    697  1.1  mrg     {
    698  1.1  mrg       p = "UNKNOWN";
    699  1.1  mrg       cf_strcpy (iqp->formatted, iqp->formatted_len, p);
    700  1.1  mrg     }
    701  1.1  mrg 
    702  1.1  mrg   if ((cf & IOPARM_INQUIRE_HAS_UNFORMATTED) != 0)
    703  1.1  mrg     {
    704  1.1  mrg       p = "UNKNOWN";
    705  1.1  mrg       cf_strcpy (iqp->unformatted, iqp->unformatted_len, p);
    706  1.1  mrg     }
    707  1.1  mrg 
    708  1.1  mrg   if ((cf & IOPARM_INQUIRE_HAS_RECL_OUT) != 0)
    709  1.1  mrg     *iqp->recl_out = 0;
    710  1.1  mrg 
    711  1.1  mrg   if ((cf & IOPARM_INQUIRE_HAS_NEXTREC) != 0)
    712  1.1  mrg     *iqp->nextrec = 0;
    713  1.1  mrg 
    714  1.1  mrg   if ((cf & IOPARM_INQUIRE_HAS_BLANK) != 0)
    715  1.1  mrg     cf_strcpy (iqp->blank, iqp->blank_len, undefined);
    716  1.1  mrg 
    717  1.1  mrg   if ((cf & IOPARM_INQUIRE_HAS_PAD) != 0)
    718  1.1  mrg     cf_strcpy (iqp->pad, iqp->pad_len, undefined);
    719  1.1  mrg 
    720  1.1  mrg   if (cf & IOPARM_INQUIRE_HAS_FLAGS2)
    721  1.1  mrg     {
    722  1.1  mrg       GFC_INTEGER_4 cf2 = iqp->flags2;
    723  1.1  mrg 
    724  1.1  mrg       if ((cf2 & IOPARM_INQUIRE_HAS_ENCODING) != 0)
    725  1.1  mrg 	cf_strcpy (iqp->encoding, iqp->encoding_len, undefined);
    726  1.1  mrg 
    727  1.1  mrg       if ((cf2 & IOPARM_INQUIRE_HAS_DELIM) != 0)
    728  1.1  mrg 	cf_strcpy (iqp->delim, iqp->delim_len, undefined);
    729  1.1  mrg 
    730  1.1  mrg       if ((cf2 & IOPARM_INQUIRE_HAS_DECIMAL) != 0)
    731  1.1  mrg 	cf_strcpy (iqp->decimal, iqp->decimal_len, undefined);
    732  1.1  mrg 
    733  1.1  mrg       if ((cf2 & IOPARM_INQUIRE_HAS_DELIM) != 0)
    734  1.1  mrg 	cf_strcpy (iqp->delim, iqp->delim_len, undefined);
    735  1.1  mrg 
    736  1.1  mrg       if ((cf2 & IOPARM_INQUIRE_HAS_PAD) != 0)
    737  1.1  mrg 	cf_strcpy (iqp->pad, iqp->pad_len, undefined);
    738  1.1  mrg 
    739  1.1  mrg       if ((cf2 & IOPARM_INQUIRE_HAS_ENCODING) != 0)
    740  1.1  mrg 	cf_strcpy (iqp->encoding, iqp->encoding_len, undefined);
    741  1.1  mrg 
    742  1.1  mrg       if ((cf2 & IOPARM_INQUIRE_HAS_SIZE) != 0)
    743  1.1  mrg 	*iqp->size = file_size (iqp->file, iqp->file_len);
    744  1.1  mrg 
    745  1.1  mrg       if ((cf2 & IOPARM_INQUIRE_HAS_IQSTREAM) != 0)
    746  1.1  mrg 	cf_strcpy (iqp->iqstream, iqp->iqstream_len, "UNKNOWN");
    747  1.1  mrg 
    748  1.1  mrg       if ((cf2 & IOPARM_INQUIRE_HAS_SHARE) != 0)
    749  1.1  mrg 	cf_strcpy (iqp->share, iqp->share_len, "UNKNOWN");
    750  1.1  mrg 
    751  1.1  mrg       if ((cf2 & IOPARM_INQUIRE_HAS_CC) != 0)
    752  1.1  mrg 	cf_strcpy (iqp->cc, iqp->cc_len, "UNKNOWN");
    753  1.1  mrg     }
    754  1.1  mrg 
    755  1.1  mrg   if ((cf & IOPARM_INQUIRE_HAS_POSITION) != 0)
    756  1.1  mrg     cf_strcpy (iqp->position, iqp->position_len, undefined);
    757  1.1  mrg 
    758  1.1  mrg   if ((cf & IOPARM_INQUIRE_HAS_ACCESS) != 0)
    759  1.1  mrg     cf_strcpy (iqp->access, iqp->access_len, undefined);
    760  1.1  mrg 
    761  1.1  mrg   if ((cf & IOPARM_INQUIRE_HAS_READ) != 0)
    762  1.1  mrg     {
    763  1.1  mrg       p = inquire_read (iqp->file, iqp->file_len);
    764  1.1  mrg       cf_strcpy (iqp->read, iqp->read_len, p);
    765  1.1  mrg     }
    766  1.1  mrg 
    767  1.1  mrg   if ((cf & IOPARM_INQUIRE_HAS_WRITE) != 0)
    768  1.1  mrg     {
    769  1.1  mrg       p = inquire_write (iqp->file, iqp->file_len);
    770  1.1  mrg       cf_strcpy (iqp->write, iqp->write_len, p);
    771  1.1  mrg     }
    772  1.1  mrg 
    773  1.1  mrg   if ((cf & IOPARM_INQUIRE_HAS_READWRITE) != 0)
    774  1.1  mrg     {
    775  1.1  mrg       p = inquire_read (iqp->file, iqp->file_len);
    776  1.1  mrg       cf_strcpy (iqp->readwrite, iqp->readwrite_len, p);
    777  1.1  mrg     }
    778  1.1  mrg }
    779  1.1  mrg 
    780  1.1  mrg 
    781  1.1  mrg /* Library entry point for the INQUIRE statement (non-IOLENGTH
    782  1.1  mrg    form).  */
    783  1.1  mrg 
    784  1.1  mrg extern void st_inquire (st_parameter_inquire *);
    785  1.1  mrg export_proto(st_inquire);
    786  1.1  mrg 
    787  1.1  mrg void
    788  1.1  mrg st_inquire (st_parameter_inquire *iqp)
    789  1.1  mrg {
    790  1.1  mrg   gfc_unit *u;
    791  1.1  mrg 
    792  1.1  mrg   library_start (&iqp->common);
    793  1.1  mrg 
    794  1.1  mrg   if ((iqp->common.flags & IOPARM_INQUIRE_HAS_FILE) == 0)
    795  1.1  mrg     {
    796  1.1  mrg       u = find_unit (iqp->common.unit);
    797  1.1  mrg       inquire_via_unit (iqp, u);
    798  1.1  mrg     }
    799  1.1  mrg   else
    800  1.1  mrg     {
    801  1.1  mrg       u = find_file (iqp->file, iqp->file_len);
    802  1.1  mrg       if (u == NULL)
    803  1.1  mrg 	inquire_via_filename (iqp);
    804  1.1  mrg       else
    805  1.1  mrg 	inquire_via_unit (iqp, u);
    806  1.1  mrg     }
    807  1.1  mrg   if (u != NULL)
    808  1.1  mrg     unlock_unit (u);
    809  1.1  mrg 
    810  1.1  mrg   library_end ();
    811  1.1  mrg }
    812