Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
wu.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/wu.c       92.3    10/29/99 21:39:27"
00039 
00040 #include <errno.h>
00041 #include <liberrno.h>
00042 #include <fortran.h>
00043 #include "fio.h"
00044 #ifdef  _CRAYMPP
00045 #include <stdarg.h>
00046 #endif
00047 /* for malloc and memset prototype */
00048 #ifdef  _LITTLE_ENDIAN
00049 #include <stdlib.h>     
00050 #include <string.h>     
00051 #endif
00052 
00053 #ifdef  _UNICOS
00054 #pragma _CRI duplicate _WUI as $WUI
00055 #pragma _CRI duplicate _WUF as $WUF
00056 #endif
00057 
00058 int     _WUF();
00059 
00060 #define ERROR0(cond, n) {       \
00061         if (!(cond))            \
00062                 _ferr(css, (n));\
00063         else                    \
00064                 goto error;     \
00065 }
00066 
00067 #define ERROR1(cond, n, p) {    \
00068         if (!(cond))            \
00069                 _ferr(css, (n), p);\
00070         else                    \
00071                 goto error;     \
00072 }
00073 
00074 /*
00075  *      $WUI - write unformatted initialization
00076  *
00077  *      CALL    $WUI,(funit, _arg2, err, _arg4, iostat, rec)
00078  *
00079  *              funit   Address of Fortran unit designator (integer unit
00080  *                      number)
00081  *              _arg2   Unused
00082  *              err     Address of error address (ERR=label)
00083  *              _arg4   Unused
00084  *              iostat  Address of I/O status variable (integer variable)
00085  *              rec     Address of integer record number (NULL implies
00086  *                      sequential I/O)
00087  *
00088  *      $WUI calls:
00089  *
00090  *              _imp_open77(), _ferr(), _unit_seek()
00091  */
00092 
00093 #ifdef  _CRAYMPP
00094 int
00095 _WUI(
00096 _fcd            funit,          /* Address of unit number               */
00097 ...)
00098 #else
00099 int
00100 _WUI(
00101 _fcd            funit,          /* Address of unit number               */
00102 _fcd            _arg2,          /* Unused                               */
00103 long            *err,           /* Address of error processing address  */
00104 long            *_arg4,         /* Unused                               */
00105 _f_int          *iostat,        /* Address of IOSTAT variable           */
00106 _f_int          *rec            /* Address of direct access record no.  */
00107 #ifndef _UNICOS
00108 ,FIOSPTR        cssa            /* Statement state structure */
00109 #endif
00110 )
00111 #endif
00112 {
00113         register int    errf;           /* Error processing flag        */
00114         register int    errn;           /* Error number                 */
00115         register int    iost;           /* I/O statement type           */
00116         register int    iotp;           /* I/O type                     */
00117         register recn_t recn;           /* Direct access record number  */
00118         register unum_t unum;           /* Actual unit number           */
00119         unit            *cup;           /* Pointer to unit table entry  */
00120         FIOSPTR         css;            /* Pointer to statement state   */
00121 #ifdef  _CRAYMPP
00122         va_list         args;
00123         _fcd            _arg2;          /* Unused                       */
00124         long            *err;           /* Address of error processing address*/
00125         long            *_arg4;         /* Unused                       */
00126         _f_int          *iostat;        /* Address of IOSTAT variable   */
00127         _f_int          *rec;           /* Address of direct access record no.*/
00128 #endif
00129 
00130 #ifdef  _UNICOS
00131         GET_FIOS_PTR(css);
00132 
00133         /* Check if recursive triple-call I/O */
00134 
00135         if (css->f_iostmt != 0)
00136                 _ferr(css, FEIOACTV);
00137 #else
00138         css     = cssa;
00139 #endif
00140 
00141 #ifdef  _CRAYMPP
00142         va_start(args,funit);
00143         _arg2   = va_arg(args,_fcd);
00144         err     = va_arg(args, long *);
00145         _arg4   = va_arg(args, long *);
00146         iostat  = va_arg(args, _f_int *);
00147         rec     = va_arg(args, _f_int *);
00148         va_end(args);
00149 #endif
00150 
00151         errn    = 0;
00152         unum    = **(_f_int **)&funit;
00153 
00154         /* Establish error processing options */
00155 
00156         if (iostat != NULL)
00157                 *iostat = 0;            /* Clear IOSTAT variable, if extant */
00158 
00159         errf    = ((err != NULL) || (iostat != NULL));
00160         iost    = T_WSU;
00161         iotp    = SEQ;                  /* Assume sequential */
00162 
00163         if (rec != NULL) {      /* If direct access */
00164                 iost    = T_WDU;        /* Set direct unformatted write */
00165                 iotp    = DIR;
00166                 recn    = *rec;
00167         }
00168 
00169         STMT_BEGIN(unum, 0, iost, NULL, css, cup);
00170 
00171         if (cup == NULL) {              /* If not connected */
00172                 int     stat;
00173 
00174                 cup     = _imp_open77(css, iotp, UNF, unum, errf, &stat);
00175 
00176                 if (cup == NULL) {
00177                         errn    = stat;
00178                         goto error;
00179                 }
00180         }
00181 
00182         /* Record error processing options in the unit */
00183 
00184         cup->uiostat    = iostat;
00185         cup->uflag      = (iostat != NULL ? _UIOSTF : 0) |
00186                           (   err != NULL ?  _UERRF : 0);
00187 
00188         /* Perform error checking */
00189 
00190         if (cup->ufs == FS_AUX) {
00191                 errn    = FEMIXAUX;     /* Can't mix auxiliary and Fortran I/O */
00192                 ERROR0(errf, errn);
00193         }
00194 
00195         if ((cup->uaction & OS_WRITE) == 0) {
00196                 errn    = FENOWRIT;     /* No write permission */
00197                 ERROR0(errf, errn);
00198         }
00199 
00200         if (cup->ufmt) {        /* If unformatted attempted on formatted file */
00201                 errn    = FEUNFMIV;             /* Unformatted not allowed */
00202                 ERROR0(errf, errn);
00203         }
00204 
00205         /* Preset fields in unit table */
00206 
00207         cup->uwrt       = 1;
00208         cup->ulastyp    = DVTYPE_TYPELESS;
00209 
00210         if (iotp == DIR) {      /* If direct access */
00211 
00212                 if (cup->useq)          /* If direct attempted on seq. file */
00213                         errn    = FEDIRTIV;     /* Direct access not allowed */
00214                 else
00215                         errn    = _unit_seek(cup, recn, iost);
00216 
00217                 if (errn != 0)
00218                         ERROR1(errf, errn, recn);
00219 
00220                 if (cup->udalast > cup->udamax) /* If new highwater mark */
00221                         cup->udamax     = cup->udalast;
00222 
00223                 cup->uend       = BEFORE_ENDFILE;
00224         }
00225         else {          /* Else sequential access */
00226 
00227                 if (cup->useq == 0) {   /* If seq. attempted on direct file */
00228                         errn    = FESEQTIV;     /* Sequential not allowed */
00229                         ERROR0(errf, errn);
00230                 }
00231 
00232                 if (cup->uend != BEFORE_ENDFILE) {
00233                         struct ffsw     fst;    /* FFIO status block */
00234                         /*
00235                          * If positioned after an endfile, and the file does not
00236                          * support multiple endfiles, a write is invalid.
00237                          */
00238                         if (!cup->umultfil && !cup->uspcproc) {
00239                                 errn    = FEWRAFEN;     /* Write after endfile */
00240                                 ERROR0(errf, errn);
00241                         }
00242                         /*
00243                          * If a logical endfile record had just been read,
00244                          * replace it with a physical endfile record before
00245                          * starting the current data record.
00246                          */
00247                         if ((cup->uend == LOGICAL_ENDFILE) && !(cup->uspcproc)) {
00248                                 if (XRCALL(cup->ufp.fdc, weofrtn)cup->ufp.fdc, &fst) < 0) {
00249                                         errn    = fst.sw_error;
00250                                         ERROR0(errf, errn);
00251                                 }
00252                         }
00253 
00254                         cup->uend       = BEFORE_ENDFILE;
00255                 }
00256 
00257 #if     PURE_ENABLED
00258                 if (cup->upure && cup->upuretype != P_RDWR) {
00259                         /*
00260                          * Set the upuretype field to P_RDWR mode unless it has
00261                          * previously been set to P_BUFIO by a BUFFER IN/OUT
00262                          * statement.  This check prevents the intermixing of
00263                          * READ/WRITE I/O with BUFFER IN/BUFFER OUT I/O when
00264                          * '-s pure' is assigned.
00265                          */
00266                         if (cup->upuretype == P_BUFIO)
00267                                 errn    = FEMIXBUF;
00268                         else
00269                                 cup->upuretype  = P_RDWR;
00270                 }
00271 #endif
00272 
00273         }
00274 
00275         if (errn != 0)
00276                 ERROR0(errf, errn);
00277 
00278         return(CFT77_RETVAL(IO_OKAY));
00279 
00280 error:
00281         if (iostat != NULL)
00282                 *iostat = errn;         /* Set IOSTAT variable to error */
00283 
00284         if (cup != NULL)                /* If we have a unit */
00285                 cup->uflag      = cup->uflag | _UERRC;  /* Indicate error */
00286 
00287 #ifdef  _UNICOS
00288         return(CFT77_RETVAL(_WUF()));
00289 #else
00290         return(CFT77_RETVAL(_WUF(css)));
00291 #endif
00292 }
00293 
00294 #ifdef  _UNICOS
00295 /*
00296  *      Definition of inlined function _inline_wrunf()
00297  */
00298 #define INLINE
00299 #include "wrunf.c"
00300 
00301 /*
00302  *      $WUA$ - write unformatted transfer
00303  *
00304  *      CALL    $WUA$,(fwa, count, inc, type)
00305  *
00306  *              fwa     First word address of datum (may be a Fortran
00307  *                      character descriptor)
00308  *              count   Pointer to number of data items
00309  *              stride  Pointer to stride between data items
00310  *              type    Pointer to type of data
00311  *
00312  *      $WUA$ calls:
00313  *
00314  *              _ferr(), _wrunf(), _WUF()
00315  */
00316 
00317 int
00318 $WUA$(
00319         _fcd    fwa,            /* Address of first word of data        */
00320         long    *count,         /* Address of count of data items       */
00321         long    *stride,        /* Address of stride between data items */
00322         long    *type           /* Address of data type                 */
00323 )
00324 {
00325         register short  type77;         /* Fortran 77 data type */
00326         register int    errn;           /* Error number */
00327         type_packet     tip;            /* Type information packet */
00328         struct f90_type ts;             /* F90 type structure */
00329         void            *dptr;
00330         unit            *cup;           /* Pointer to unit table entry  */
00331         FIOSPTR         css;            /* Pointer to statement state   */
00332 
00333         GET_FIOS_PTR(css);
00334 
00335         cup     = css->f_cu;
00336         type77  = *type & 017;
00337 
00338         CREATE_F90_INFO(ts, tip, type77);
00339 
00340         tip.count       = *count;
00341         tip.stride      = *stride;
00342 
00343         if (type77 == DT_CHAR) {
00344                 dptr            = (void *) _fcdtocp(fwa);
00345                 tip.elsize      = tip.elsize * _fcdlen(fwa);
00346         }
00347         else
00348                 dptr            = *(void **)&fwa;
00349 
00350 #if     NUMERIC_DATA_CONVERSION_ENABLED
00351 
00352         if (cup->unumcvrt || cup->ucharset) {
00353 
00354                 errn    = _get_dc_param(css, cup, ts, &tip);
00355 
00356                 if (errn != 0)
00357                         goto error;
00358         }
00359 #endif
00360 
00361 #pragma _CRI inline _inline_wrunf
00362         errn    = _inline_wrunf(css, cup, dptr, &tip, PARTIAL);
00363 
00364         if (errn == 0)
00365                 return(CFT77_RETVAL(IO_OKAY));
00366 
00367 error:
00368         if (cup->uiostat != NULL)
00369                 *(cup->uiostat) = errn;
00370 
00371         cup->uflag      = cup->uflag | _UERRC;          /* Indicate error */
00372 
00373         if ((cup->uflag & (_UIOSTF | _UERRF)) != 0) 
00374                 return(CFT77_RETVAL(_WUF()));
00375 
00376         _ferr(css, FEINTUNK);           /* Deep weeds */
00377 }
00378 
00379 #endif  /* _UNICOS */
00380 
00381 /*
00382  *      _WUF - write unformatted finalization
00383  *
00384  *      CALL    _WUF,()
00385  *
00386  *      _WUF calls:
00387  *
00388  *              _ferr(), _fwwd(), fwrite()
00389  */
00390 
00391 int
00392 _WUF(
00393 #ifndef _UNICOS
00394 FIOSPTR         cssa            /* Statement state structure */
00395 #endif
00396 )
00397 {
00398         register int    errn;           /* Error number                 */
00399         register long   flag;           /* Error flag                   */
00400         unit            *cup;           /* Pointer to unit table entry  */
00401         FIOSPTR         css;            /* Pointer to statement state   */
00402 
00403 #ifdef  _UNICOS
00404         GET_FIOS_PTR(css);
00405 #else
00406         css     = cssa;
00407 #endif
00408 
00409         errn    = 0;
00410         cup     = css->f_cu;
00411 
00412         if (cup == NULL) {              /* If unit not opened */
00413                 /*
00414                  * If unit not connected, assume we are catching errors with
00415                  * ERR= or IOSTAT= and that _WUF is being called from $WUI or
00416                  * $WUA$.
00417                  */
00418                 flag    = _UERRC | _UERRF;
00419                 goto finished;
00420         }
00421 
00422         cup->ulrecl     = cup->urecpos;
00423         cup->urecpos    = 0;
00424 
00425         if ((cup->uflag & _UERRC) == 0) {       /* If no error */
00426                 register int    ret;            /* Return value */
00427                 long            zero = 0;       /* Zero word */
00428 
00429                 if (cup->useq) {        /* Sequential Access */
00430                         if (cup->ublkd) {
00431                                 int     status; /* Unused status */
00432 
00433                                 /* Terminate the record */
00434 
00435                                 ret     = _fwwd(cup, &zero, &__tip_null, FULL,
00436                                                 (int *)NULL, &zero, &status); 
00437 
00438                                 if (ret == IOERR)
00439                                         errn    = errno;
00440                         }
00441                 }
00442                 else {                  /* Direct Access */
00443                         register long   bleft;  /* Unwritten bytes in record */
00444 
00445                         bleft   = cup->urecl - (cup->ulrecl >> 3);
00446 
00447                         if (bleft > 0 && cup->udalast == cup->udamax) {
00448                                 register int    ret;    /* Return value */
00449                                 long            *zbuf;  /* Buffer pointer */
00450                                 struct ffsw     fst;    /* FFIO status block */
00451 
00452                                 /*
00453                                  * If this is the last direct access record in
00454                                  * the file and a short record was written, be
00455                                  * sure it is padded out to its full width as
00456                                  * required by the Fortran standard.
00457                                  */
00458 
00459                                 zbuf    = &zero;        /* Assume short pad */
00460 
00461                                 if (bleft > sizeof(long)) {
00462 
00463                                         zbuf    = (long *) malloc(bleft);
00464 
00465                                         if (zbuf == NULL) {
00466                                                 errn    = FENOMEMY; /* No memory */
00467                                                 goto error;
00468                                         }
00469                                         else    /* Clear record */
00470                                                 (void) memset((void *) zbuf, 0, bleft);
00471                                 }
00472 
00473                                 switch (cup->ufs) {     /* File structure */
00474 
00475                                 case FS_FDC:
00476                                         ret     = XRCALL(cup->ufp.fdc, writertn)
00477                                                         cup->ufp.fdc,
00478                                                         WPTR2BP(zbuf), bleft, &fst,
00479                                                         FULL, (int *)&zero);
00480 
00481                                         if (ret != bleft)
00482                                                 errn    = fst.sw_error;
00483 
00484                                         break;
00485 
00486                                 case STD:
00487                                         ret     = fwrite((void *) zbuf, 1, bleft,
00488                                                          cup->ufp.std);
00489 
00490                                         if (ret != bleft)
00491                                                 errn    = errno;
00492 
00493                                         break;
00494 
00495                                 default:
00496                                         errn    = FEINTUNK;     /* Deep weeds */
00497                                         break;
00498 
00499                                 } /* switch */
00500 
00501                                 /* Free any allocated space */
00502 
00503                                 if (zbuf != &zero)
00504                                         free(zbuf);
00505                         }
00506 
00507                 }
00508 
00509 error:
00510                 if (errn != 0) {
00511                         if (cup->uiostat != NULL)
00512                                 *(cup->uiostat) = errn;
00513 
00514                         if ((cup->uflag & (_UIOSTF | _UERRF)) == 0)
00515                                 _ferr(css, errn);
00516                         else    /* Set status */
00517                                 cup->uflag      = cup->uflag | _UERRC;
00518                 }
00519         }
00520 
00521         flag    = cup->uflag;   /* Save status */
00522 
00523 finished:
00524         STMT_END(cup, TF_WRITE, NULL, css);     /* Unlock unit */
00525 
00526         if ((flag & _UERRC) == 0)       /* If no error */
00527                 return(CFT77_RETVAL(IO_OKAY));
00528         else
00529                 if ((flag & (_UIOSTF | _UERRF)) != 0)
00530                         return(CFT77_RETVAL(IO_ERR));
00531 
00532         _ferr(css, FEINTUNK);           /* Deep weeds */
00533 
00534         return(CFT77_RETVAL(IO_ERR));   /* MIPS compiler requires this return */
00535 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines