Home | History | Annotate | Line # | Download | only in io
      1      1.1  mrg /* Implementation of the FGET, FGETC, FPUT, FPUTC, FLUSH
      2      1.1  mrg    FTELL, TTYNAM and ISATTY intrinsics.
      3  1.1.1.3  mrg    Copyright (C) 2005-2022 Free Software Foundation, Inc.
      4      1.1  mrg 
      5      1.1  mrg This file is part of the GNU Fortran runtime library (libgfortran).
      6      1.1  mrg 
      7      1.1  mrg Libgfortran is free software; you can redistribute it and/or
      8      1.1  mrg modify it under the terms of the GNU General Public
      9      1.1  mrg License as published by the Free Software Foundation; either
     10      1.1  mrg version 3 of the License, or (at your option) any later version.
     11      1.1  mrg 
     12      1.1  mrg Libgfortran is distributed in the hope that it will be useful,
     13      1.1  mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
     14      1.1  mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15      1.1  mrg GNU General Public License for more details.
     16      1.1  mrg 
     17      1.1  mrg Under Section 7 of GPL version 3, you are granted additional
     18      1.1  mrg permissions described in the GCC Runtime Library Exception, version
     19      1.1  mrg 3.1, as published by the Free Software Foundation.
     20      1.1  mrg 
     21      1.1  mrg You should have received a copy of the GNU General Public License and
     22      1.1  mrg a copy of the GCC Runtime Library Exception along with this program;
     23      1.1  mrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     24      1.1  mrg <http://www.gnu.org/licenses/>.  */
     25      1.1  mrg 
     26      1.1  mrg #include "io.h"
     27      1.1  mrg #include "fbuf.h"
     28      1.1  mrg #include "unix.h"
     29      1.1  mrg #include <string.h>
     30      1.1  mrg 
     31      1.1  mrg 
     32      1.1  mrg static const int five = 5;
     33      1.1  mrg static const int six = 6;
     34      1.1  mrg 
     35      1.1  mrg extern int PREFIX(fgetc) (const int *, char *, gfc_charlen_type);
     36      1.1  mrg export_proto_np(PREFIX(fgetc));
     37      1.1  mrg 
     38      1.1  mrg int
     39      1.1  mrg PREFIX(fgetc) (const int *unit, char *c, gfc_charlen_type c_len)
     40      1.1  mrg {
     41      1.1  mrg   int ret;
     42      1.1  mrg   gfc_unit *u = find_unit (*unit);
     43      1.1  mrg 
     44      1.1  mrg   if (u == NULL)
     45      1.1  mrg     return -1;
     46      1.1  mrg 
     47      1.1  mrg   fbuf_reset (u);
     48      1.1  mrg   if (u->mode == WRITING)
     49      1.1  mrg     {
     50      1.1  mrg       sflush (u->s);
     51      1.1  mrg       u->mode = READING;
     52      1.1  mrg     }
     53      1.1  mrg 
     54      1.1  mrg   memset (c, ' ', c_len);
     55      1.1  mrg   ret = sread (u->s, c, 1);
     56      1.1  mrg   unlock_unit (u);
     57      1.1  mrg 
     58      1.1  mrg   if (ret < 0)
     59      1.1  mrg     return ret;
     60      1.1  mrg 
     61      1.1  mrg   if (ret != 1)
     62      1.1  mrg     return -1;
     63      1.1  mrg   else
     64      1.1  mrg     return 0;
     65      1.1  mrg }
     66      1.1  mrg 
     67      1.1  mrg 
     68      1.1  mrg #define FGETC_SUB(kind) \
     69      1.1  mrg   extern void fgetc_i ## kind ## _sub \
     70      1.1  mrg     (const int *, char *, GFC_INTEGER_ ## kind *, gfc_charlen_type); \
     71      1.1  mrg   export_proto(fgetc_i ## kind ## _sub); \
     72      1.1  mrg   void fgetc_i ## kind ## _sub \
     73      1.1  mrg   (const int *unit, char *c, GFC_INTEGER_ ## kind *st, gfc_charlen_type c_len) \
     74      1.1  mrg     { if (st != NULL) \
     75      1.1  mrg         *st = PREFIX(fgetc) (unit, c, c_len); \
     76      1.1  mrg       else \
     77      1.1  mrg         PREFIX(fgetc) (unit, c, c_len); }
     78      1.1  mrg 
     79      1.1  mrg FGETC_SUB(1)
     80      1.1  mrg FGETC_SUB(2)
     81      1.1  mrg FGETC_SUB(4)
     82      1.1  mrg FGETC_SUB(8)
     83      1.1  mrg 
     84      1.1  mrg 
     85      1.1  mrg extern int PREFIX(fget) (char *, gfc_charlen_type);
     86      1.1  mrg export_proto_np(PREFIX(fget));
     87      1.1  mrg 
     88      1.1  mrg int
     89      1.1  mrg PREFIX(fget) (char *c, gfc_charlen_type c_len)
     90      1.1  mrg {
     91      1.1  mrg   return PREFIX(fgetc) (&five, c, c_len);
     92      1.1  mrg }
     93      1.1  mrg 
     94      1.1  mrg 
     95      1.1  mrg #define FGET_SUB(kind) \
     96      1.1  mrg   extern void fget_i ## kind ## _sub \
     97      1.1  mrg     (char *, GFC_INTEGER_ ## kind *, gfc_charlen_type); \
     98      1.1  mrg   export_proto(fget_i ## kind ## _sub); \
     99      1.1  mrg   void fget_i ## kind ## _sub \
    100      1.1  mrg   (char *c, GFC_INTEGER_ ## kind *st, gfc_charlen_type c_len) \
    101      1.1  mrg     { if (st != NULL) \
    102      1.1  mrg         *st = PREFIX(fgetc) (&five, c, c_len); \
    103      1.1  mrg       else \
    104      1.1  mrg         PREFIX(fgetc) (&five, c, c_len); }
    105      1.1  mrg 
    106      1.1  mrg FGET_SUB(1)
    107      1.1  mrg FGET_SUB(2)
    108      1.1  mrg FGET_SUB(4)
    109      1.1  mrg FGET_SUB(8)
    110      1.1  mrg 
    111      1.1  mrg 
    112      1.1  mrg 
    113      1.1  mrg extern int PREFIX(fputc) (const int *, char *, gfc_charlen_type);
    114      1.1  mrg export_proto_np(PREFIX(fputc));
    115      1.1  mrg 
    116      1.1  mrg int
    117      1.1  mrg PREFIX(fputc) (const int *unit, char *c,
    118      1.1  mrg 	       gfc_charlen_type c_len __attribute__((unused)))
    119      1.1  mrg {
    120      1.1  mrg   ssize_t s;
    121      1.1  mrg   gfc_unit *u = find_unit (*unit);
    122      1.1  mrg 
    123      1.1  mrg   if (u == NULL)
    124      1.1  mrg     return -1;
    125      1.1  mrg 
    126      1.1  mrg   fbuf_reset (u);
    127      1.1  mrg   if (u->mode == READING)
    128      1.1  mrg     {
    129      1.1  mrg       sflush (u->s);
    130      1.1  mrg       u->mode = WRITING;
    131      1.1  mrg     }
    132      1.1  mrg 
    133      1.1  mrg   s = swrite (u->s, c, 1);
    134      1.1  mrg   unlock_unit (u);
    135      1.1  mrg   if (s < 0)
    136      1.1  mrg     return -1;
    137      1.1  mrg   return 0;
    138      1.1  mrg }
    139      1.1  mrg 
    140      1.1  mrg 
    141      1.1  mrg #define FPUTC_SUB(kind) \
    142      1.1  mrg   extern void fputc_i ## kind ## _sub \
    143      1.1  mrg     (const int *, char *, GFC_INTEGER_ ## kind *, gfc_charlen_type); \
    144      1.1  mrg   export_proto(fputc_i ## kind ## _sub); \
    145      1.1  mrg   void fputc_i ## kind ## _sub \
    146      1.1  mrg   (const int *unit, char *c, GFC_INTEGER_ ## kind *st, gfc_charlen_type c_len) \
    147      1.1  mrg     { if (st != NULL) \
    148      1.1  mrg         *st = PREFIX(fputc) (unit, c, c_len); \
    149      1.1  mrg       else \
    150      1.1  mrg         PREFIX(fputc) (unit, c, c_len); }
    151      1.1  mrg 
    152      1.1  mrg FPUTC_SUB(1)
    153      1.1  mrg FPUTC_SUB(2)
    154      1.1  mrg FPUTC_SUB(4)
    155      1.1  mrg FPUTC_SUB(8)
    156      1.1  mrg 
    157      1.1  mrg 
    158      1.1  mrg extern int PREFIX(fput) (char *, gfc_charlen_type);
    159      1.1  mrg export_proto_np(PREFIX(fput));
    160      1.1  mrg 
    161      1.1  mrg int
    162      1.1  mrg PREFIX(fput) (char *c, gfc_charlen_type c_len)
    163      1.1  mrg {
    164      1.1  mrg   return PREFIX(fputc) (&six, c, c_len);
    165      1.1  mrg }
    166      1.1  mrg 
    167      1.1  mrg 
    168      1.1  mrg #define FPUT_SUB(kind) \
    169      1.1  mrg   extern void fput_i ## kind ## _sub \
    170      1.1  mrg     (char *, GFC_INTEGER_ ## kind *, gfc_charlen_type); \
    171      1.1  mrg   export_proto(fput_i ## kind ## _sub); \
    172      1.1  mrg   void fput_i ## kind ## _sub \
    173      1.1  mrg   (char *c, GFC_INTEGER_ ## kind *st, gfc_charlen_type c_len) \
    174      1.1  mrg     { if (st != NULL) \
    175      1.1  mrg         *st = PREFIX(fputc) (&six, c, c_len); \
    176      1.1  mrg       else \
    177      1.1  mrg         PREFIX(fputc) (&six, c, c_len); }
    178      1.1  mrg 
    179      1.1  mrg FPUT_SUB(1)
    180      1.1  mrg FPUT_SUB(2)
    181      1.1  mrg FPUT_SUB(4)
    182      1.1  mrg FPUT_SUB(8)
    183      1.1  mrg 
    184      1.1  mrg 
    185      1.1  mrg /* SUBROUTINE FLUSH(UNIT)
    186      1.1  mrg    INTEGER, INTENT(IN), OPTIONAL :: UNIT  */
    187      1.1  mrg 
    188      1.1  mrg extern void flush_i4 (GFC_INTEGER_4 *);
    189      1.1  mrg export_proto(flush_i4);
    190      1.1  mrg 
    191      1.1  mrg void
    192      1.1  mrg flush_i4 (GFC_INTEGER_4 *unit)
    193      1.1  mrg {
    194      1.1  mrg   gfc_unit *us;
    195      1.1  mrg 
    196      1.1  mrg   /* flush all streams */
    197      1.1  mrg   if (unit == NULL)
    198      1.1  mrg     flush_all_units ();
    199      1.1  mrg   else
    200      1.1  mrg     {
    201      1.1  mrg       us = find_unit (*unit);
    202      1.1  mrg       if (us != NULL)
    203      1.1  mrg 	{
    204      1.1  mrg 	  sflush (us->s);
    205      1.1  mrg 	  unlock_unit (us);
    206      1.1  mrg 	}
    207      1.1  mrg     }
    208      1.1  mrg }
    209      1.1  mrg 
    210      1.1  mrg 
    211      1.1  mrg extern void flush_i8 (GFC_INTEGER_8 *);
    212      1.1  mrg export_proto(flush_i8);
    213      1.1  mrg 
    214      1.1  mrg void
    215      1.1  mrg flush_i8 (GFC_INTEGER_8 *unit)
    216      1.1  mrg {
    217      1.1  mrg   gfc_unit *us;
    218      1.1  mrg 
    219      1.1  mrg   /* flush all streams */
    220      1.1  mrg   if (unit == NULL)
    221      1.1  mrg     flush_all_units ();
    222      1.1  mrg   else
    223      1.1  mrg     {
    224      1.1  mrg       us = find_unit (*unit);
    225      1.1  mrg       if (us != NULL)
    226      1.1  mrg 	{
    227      1.1  mrg 	  sflush (us->s);
    228      1.1  mrg 	  unlock_unit (us);
    229      1.1  mrg 	}
    230      1.1  mrg     }
    231      1.1  mrg }
    232      1.1  mrg 
    233      1.1  mrg /* FSEEK intrinsic */
    234      1.1  mrg 
    235      1.1  mrg extern void fseek_sub (int *, GFC_IO_INT *, int *, int *);
    236      1.1  mrg export_proto(fseek_sub);
    237      1.1  mrg 
    238      1.1  mrg void
    239      1.1  mrg fseek_sub (int *unit, GFC_IO_INT *offset, int *whence, int *status)
    240      1.1  mrg {
    241      1.1  mrg   gfc_unit *u = find_unit (*unit);
    242      1.1  mrg   ssize_t result = -1;
    243      1.1  mrg 
    244      1.1  mrg   if (u != NULL)
    245      1.1  mrg     {
    246      1.1  mrg       result = sseek(u->s, *offset, *whence);
    247      1.1  mrg 
    248      1.1  mrg       unlock_unit (u);
    249      1.1  mrg     }
    250      1.1  mrg 
    251      1.1  mrg   if (status)
    252      1.1  mrg     *status = (result < 0 ? -1 : 0);
    253      1.1  mrg }
    254      1.1  mrg 
    255      1.1  mrg 
    256      1.1  mrg 
    257      1.1  mrg /* FTELL intrinsic */
    258      1.1  mrg 
    259      1.1  mrg static gfc_offset
    260      1.1  mrg gf_ftell (int unit)
    261      1.1  mrg {
    262      1.1  mrg   gfc_unit *u = find_unit (unit);
    263      1.1  mrg   if (u == NULL)
    264      1.1  mrg     return -1;
    265      1.1  mrg   int pos = fbuf_reset (u);
    266      1.1  mrg   if (pos != 0)
    267      1.1  mrg     sseek (u->s, pos, SEEK_CUR);
    268      1.1  mrg   gfc_offset ret = stell (u->s);
    269      1.1  mrg   unlock_unit (u);
    270      1.1  mrg   return ret;
    271      1.1  mrg }
    272      1.1  mrg 
    273      1.1  mrg 
    274      1.1  mrg extern GFC_IO_INT PREFIX(ftell) (int *);
    275      1.1  mrg export_proto_np(PREFIX(ftell));
    276      1.1  mrg 
    277      1.1  mrg GFC_IO_INT
    278      1.1  mrg PREFIX(ftell) (int *unit)
    279      1.1  mrg {
    280      1.1  mrg   return gf_ftell (*unit);
    281      1.1  mrg }
    282      1.1  mrg 
    283      1.1  mrg 
    284      1.1  mrg #define FTELL_SUB(kind) \
    285      1.1  mrg   extern void ftell_i ## kind ## _sub (int *, GFC_INTEGER_ ## kind *); \
    286      1.1  mrg   export_proto(ftell_i ## kind ## _sub); \
    287      1.1  mrg   void \
    288      1.1  mrg   ftell_i ## kind ## _sub (int *unit, GFC_INTEGER_ ## kind *offset) \
    289      1.1  mrg   { \
    290      1.1  mrg     *offset = gf_ftell (*unit);			\
    291      1.1  mrg   }
    292      1.1  mrg 
    293      1.1  mrg FTELL_SUB(1)
    294      1.1  mrg FTELL_SUB(2)
    295      1.1  mrg FTELL_SUB(4)
    296      1.1  mrg FTELL_SUB(8)
    297      1.1  mrg 
    298      1.1  mrg 
    299      1.1  mrg 
    300      1.1  mrg /* LOGICAL FUNCTION ISATTY(UNIT)
    301      1.1  mrg    INTEGER, INTENT(IN) :: UNIT */
    302      1.1  mrg 
    303      1.1  mrg extern GFC_LOGICAL_4 isatty_l4 (int *);
    304      1.1  mrg export_proto(isatty_l4);
    305      1.1  mrg 
    306      1.1  mrg GFC_LOGICAL_4
    307      1.1  mrg isatty_l4 (int *unit)
    308      1.1  mrg {
    309      1.1  mrg   gfc_unit *u;
    310      1.1  mrg   GFC_LOGICAL_4 ret = 0;
    311      1.1  mrg 
    312      1.1  mrg   u = find_unit (*unit);
    313      1.1  mrg   if (u != NULL)
    314      1.1  mrg     {
    315      1.1  mrg       ret = (GFC_LOGICAL_4) stream_isatty (u->s);
    316      1.1  mrg       unlock_unit (u);
    317      1.1  mrg     }
    318      1.1  mrg   return ret;
    319      1.1  mrg }
    320      1.1  mrg 
    321      1.1  mrg 
    322      1.1  mrg extern GFC_LOGICAL_8 isatty_l8 (int *);
    323      1.1  mrg export_proto(isatty_l8);
    324      1.1  mrg 
    325      1.1  mrg GFC_LOGICAL_8
    326      1.1  mrg isatty_l8 (int *unit)
    327      1.1  mrg {
    328      1.1  mrg   gfc_unit *u;
    329      1.1  mrg   GFC_LOGICAL_8 ret = 0;
    330      1.1  mrg 
    331      1.1  mrg   u = find_unit (*unit);
    332      1.1  mrg   if (u != NULL)
    333      1.1  mrg     {
    334      1.1  mrg       ret = (GFC_LOGICAL_8) stream_isatty (u->s);
    335      1.1  mrg       unlock_unit (u);
    336      1.1  mrg     }
    337      1.1  mrg   return ret;
    338      1.1  mrg }
    339      1.1  mrg 
    340      1.1  mrg 
    341      1.1  mrg /* SUBROUTINE TTYNAM(UNIT,NAME)
    342      1.1  mrg    INTEGER,SCALAR,INTENT(IN) :: UNIT
    343      1.1  mrg    CHARACTER,SCALAR,INTENT(OUT) :: NAME */
    344      1.1  mrg 
    345      1.1  mrg extern void ttynam_sub (int *, char *, gfc_charlen_type);
    346      1.1  mrg export_proto(ttynam_sub);
    347      1.1  mrg 
    348      1.1  mrg void
    349      1.1  mrg ttynam_sub (int *unit, char *name, gfc_charlen_type name_len)
    350      1.1  mrg {
    351      1.1  mrg   gfc_unit *u;
    352      1.1  mrg   int nlen;
    353      1.1  mrg   int err = 1;
    354      1.1  mrg 
    355      1.1  mrg   u = find_unit (*unit);
    356      1.1  mrg   if (u != NULL)
    357      1.1  mrg     {
    358      1.1  mrg       err = stream_ttyname (u->s, name, name_len);
    359      1.1  mrg       if (err == 0)
    360      1.1  mrg 	{
    361      1.1  mrg 	  nlen = strlen (name);
    362      1.1  mrg 	  memset (&name[nlen], ' ', name_len - nlen);
    363      1.1  mrg 	}
    364      1.1  mrg 
    365      1.1  mrg       unlock_unit (u);
    366      1.1  mrg     }
    367      1.1  mrg   if (err != 0)
    368      1.1  mrg     memset (name, ' ', name_len);
    369      1.1  mrg }
    370      1.1  mrg 
    371      1.1  mrg 
    372      1.1  mrg extern void ttynam (char **, gfc_charlen_type *, int);
    373      1.1  mrg export_proto(ttynam);
    374      1.1  mrg 
    375      1.1  mrg void
    376      1.1  mrg ttynam (char **name, gfc_charlen_type *name_len, int unit)
    377      1.1  mrg {
    378      1.1  mrg   gfc_unit *u;
    379      1.1  mrg 
    380      1.1  mrg   u = find_unit (unit);
    381      1.1  mrg   if (u != NULL)
    382      1.1  mrg     {
    383      1.1  mrg       *name = xmalloc (TTY_NAME_MAX);
    384      1.1  mrg       int err = stream_ttyname (u->s, *name, TTY_NAME_MAX);
    385      1.1  mrg       if (err == 0)
    386      1.1  mrg 	{
    387      1.1  mrg 	  *name_len = strlen (*name);
    388      1.1  mrg 	  unlock_unit (u);
    389      1.1  mrg 	  return;
    390      1.1  mrg 	}
    391      1.1  mrg       free (*name);
    392      1.1  mrg       unlock_unit (u);
    393      1.1  mrg     }
    394      1.1  mrg 
    395      1.1  mrg   *name_len = 0;
    396      1.1  mrg   *name = NULL;
    397      1.1  mrg }
    398