Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
ru90.c
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001, Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2.1 of the GNU Lesser General Public License 
00007   as published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU Lesser General Public 
00021   License along with this program; if not, write the Free Software 
00022   Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
00023   USA.
00024 
00025   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00026   Mountain View, CA 94043, or:
00027 
00028   http://www.sgi.com
00029 
00030   For further information regarding this notice, see:
00031 
00032   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00033 
00034 */
00035 
00036 
00037 
00038 #pragma ident "@(#) libf/fio/ru90.c     92.1    06/21/99 10:37:55"
00039 
00040 #include <stdio.h>
00041 #include "fio.h"
00042 #include "f90io.h"
00043 
00044 /*
00045  *      _FRU    Called by compiled Fortran programs to process an unformatted
00046  *              read statement.  Each statement is processed by one or more
00047  *              calls to _FRU.
00048  *
00049  *      Synopsis
00050  *
00051  *              int _FRU(       ControlList     *cilist,
00052  *                              iolist_header   *iolist,
00053  *                              void            *stck);
00054  *              
00055  *              Where
00056  *
00057  *                      cilist  Pointer to the control information list 
00058  *                              information.  This describes the specifiers 
00059  *                              for the current I/O statement.  This cilist
00060  *                              is guaranteed by the compiler to reflect
00061  *                              the original values of control information
00062  *                              list variables for the duration of the I/O
00063  *                              statement (ie through multiple calls).
00064  *                      iolist  Pointer to the I/O list information. 
00065  *                      stck    Pointer to stack space which is passed
00066  *                              to each call to _FRU for a particular 
00067  *                              statement.  This space is used by the
00068  *                              library.
00069  *
00070  *      Return value
00071  *
00072  *              IO_OKAY, IO_END, or IO_ERR
00073  */
00074 
00075 int
00076 _FRU(ControlListType *cilist, iolist_header *iolist, void *stck)
00077 {
00078         register int    errf;           /* ERR processing flag  */
00079         register int    errn;           /* Error number         */
00080         register int    endf;           /* END processing flag  */
00081         register int    iost;           /* I/O statement type   */
00082         register int    retval;         /* _FRU Return value    */
00083         register recn_t errarg;         /* Extra _ferr argument */
00084         register unum_t unum;           /* Unit number          */
00085         unit            *cup;           /* Unit table pointer   */
00086         FIOSPTR         css;            /* I/O statement state  */
00087 
00088 /*
00089  *      Assertions
00090  */
00091         /* Validate that the size of *stck is large enough */
00092         assert ( cilist->stksize >= sizeof(struct fiostate)/sizeof(long) );
00093 
00094 
00095         css     = stck;
00096         errn    = 0;
00097         errarg  = 0;
00098         retval  = IO_OKAY;
00099 
00100         if (iolist->iolfirst == 0) {
00101                 cup     = css->f_cu;
00102                 goto data_transfer;
00103         }
00104         
00105 /*******************************************************************************
00106  *
00107  *      Statement Initialization Section
00108  *
00109  ******************************************************************************/
00110 
00111         errf    = (cilist->errflag || cilist->iostatflg);
00112         endf    = (cilist->endflag || cilist->iostatflg);
00113         unum    = *cilist->unit.wa;
00114         iost    = cilist->dflag ? T_RDU : T_RSU;
00115 
00116         STMT_BEGIN(unum, 0, iost, NULL, css, cup);
00117 
00118         if (cup == NULL) {      /* If not connected */
00119                 int     stat;   /* Status */
00120 
00121                 cup     = _imp_open(css, (cilist->dflag ? DIR : SEQ), UNF,
00122                                 unum, errf, &stat);
00123                 /*
00124                  * If the open failed, cup is NULL and stat contains
00125                  * the error number.
00126                  */
00127                 if (cup == NULL) {
00128                         errn    = stat;
00129                         goto handle_exception;
00130                 }
00131         }
00132 
00133         /* Record error processing options in the unit. (used in _rdunf()) */
00134 
00135         cup->uflag      = (cilist->errflag              ?  _UERRF : 0) |
00136                           (cilist->endflag              ?  _UENDF : 0) |
00137                           (cilist->iostat_spec != NULL  ? _UIOSTF : 0);
00138 
00139         /* If sequential and writing, disallow read after write */
00140 
00141         if (cup->useq && cup->uwrt != 0) {
00142                 errn    = FERDAFWR;             /* Read after write */
00143                 goto handle_exception;
00144         }
00145 
00146         /* Preset fields in unit table */
00147 
00148         cup->ueor_found = NO;                   /* Clear EOR */
00149         cup->uwrt       = 0;
00150         cup->ulastyp    = DVTYPE_TYPELESS;
00151 
00152         if (cilist->dflag) {    /* If direct access */
00153 
00154                 if (!cup->ok_rd_dir_unf)
00155                         errn    = _get_mismatch_error(errf, iost, cup, css);
00156                 else {
00157                         register recn_t recn;   /* Record number */
00158 
00159                         recn    = (recn_t) *cilist->rec_spec;
00160                         errarg  = recn;
00161                         errn    = _unit_seek(cup, recn, iost);
00162                 }
00163         }
00164         else                    /* Else sequential access */
00165                 if (!cup->ok_rd_seq_unf)
00166                         errn    = _get_mismatch_error(errf, iost, cup, css);
00167 
00168         if (errn != 0)
00169                 goto handle_exception;
00170 
00171 
00172 /*******************************************************************************
00173  *
00174  *      Data Transfer Section
00175  *
00176  ******************************************************************************/
00177 data_transfer:
00178 
00179         errn    = _xfer_iolist(css, cup, iolist, _rdunf);
00180 
00181         if (errn != 0)
00182                 goto handle_exception;
00183 
00184         if (! iolist->iollast)
00185                 return(IO_OKAY);
00186 
00187 /******************************************************************************
00188  *
00189  *      Statement Finalization Section
00190  *
00191  ******************************************************************************/
00192 finalization:
00193 
00194         if (cup != NULL) {
00195                 cup->ulrecl     = cup->urecpos;
00196                 cup->urecpos    = 0;
00197         }
00198 
00199 #ifdef  _CRAYMPP
00200         if (css->f_shrdput) {
00201                 css->f_shrdput  = 0;
00202                 _remote_write_barrier();
00203         }
00204 #endif
00205 
00206         if (errn == 0 && cup->useq) {
00207 
00208                 if (cup->ufs == FS_FDC) {
00209 
00210                         /*
00211                          * Do a full record read to advance to the
00212                          * end of the record for sequential access.
00213                          */
00214                         if (cup->ublkd && !cup->ueor_found) {
00215                                 char    dummy;          /* Unused data */
00216                                 int     ubc = 0;        /* Unused bit count */
00217                                 struct ffsw     fst;    /* FFIO status block */
00218 
00219                                 (void) XRCALL(cup->ufp.fdc, readrtn) 
00220                                         cup->ufp.fdc,
00221                                         CPTR2BP(&dummy), 0,
00222                                         &fst, FULL, &ubc);
00223 
00224                                 switch (fst.sw_stat) {
00225                                 case FFERR:
00226                                         errn            = fst.sw_error;
00227                                         break;
00228 
00229                                 case FFEOF:
00230                                         cup->uend       = PHYSICAL_ENDFILE;
00231                                         errn            = FERDPEOF;
00232                                         break;
00233 
00234                                 case FFEOD:
00235                                         if (cup->uend == BEFORE_ENDFILE) {
00236                                                 cup->uend       = LOGICAL_ENDFILE;
00237                                                 errn            = FERDPEOF;
00238                                         }
00239                                         else
00240                                                 errn            = FERDENDR;
00241                                         break;
00242                                 } /* switch */
00243                         }
00244                 }
00245 
00246                 if (errn != 0)
00247                         goto handle_exception;
00248         }
00249 
00250 out_a_here:
00251 
00252         /* Set IOSTAT variable to 0 if no error, >0 error code otherwise */
00253  
00254         if (cilist->iostat_spec != NULL)
00255                 *cilist->iostat_spec    = errn;
00256 
00257         STMT_END(cup, TF_READ, NULL, css);      /* Unlock unit */
00258 
00259         return(retval);
00260 
00261 /*
00262  *      We put the error handling stuff here to reduce its impact when
00263  *      no errors are generated.  If we jump here, errn is set to a nonzero
00264  *      error, eor, or endfile status code.
00265  */
00266 handle_exception:
00267  
00268         retval  = (errn < 0) ? IO_END : IO_ERR;
00269  
00270         if (retval == IO_ERR && ! cilist->errflag && ! cilist->iostatflg)
00271                 _ferr(css, errn, errarg);
00272  
00273         if (retval == IO_END && ! cilist->endflag && ! cilist->iostatflg)
00274                 _ferr(css, errn, errarg);
00275  
00276         if (cup == NULL)
00277                 goto out_a_here;
00278  
00279         goto finalization;
00280 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines