Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
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/wu90.c 92.3 08/02/99 10:38:48" 00039 00040 #include <stdio.h> 00041 #include "fio.h" 00042 #include "f90io.h" 00043 00044 /* 00045 * _FWU Called by compiled Fortran programs to process an unformatted 00046 * write statement. Each statement is processed by one or more 00047 * calls to _FWU. If any of the calls to _FWU for a particular 00048 * write statement result in an error return code, the compiler 00049 * ensures that subsequent calls to _FWU are suppressed. 00050 * 00051 * Synopsis 00052 * 00053 * int _FWU( ControlList *cilist, 00054 * iolist_header *iolist, 00055 * void *stck); 00056 * 00057 * Where 00058 * 00059 * cilist Pointer to the control information list 00060 * information. This describes the specifiers 00061 * for the current I/O statement. This cilist 00062 * is guaranteed by the compiler to reflect 00063 * the original values of control information 00064 * list variables for the duration of the I/O 00065 * statement (ie through multiple calls). 00066 * iolist Pointer to the I/O list information. 00067 * stck Pointer to stack space which is passed 00068 * to each call to _FWU for a particular 00069 * statement. This space is used by the 00070 * library. 00071 * 00072 * Return value 00073 * 00074 * IO_OKAY or IO_ERR 00075 */ 00076 00077 int 00078 _FWU(ControlListType *cilist, iolist_header *iolist, void *stck) 00079 { 00080 register int errf; /* ERR processing flag */ 00081 register int errn; /* Error number */ 00082 register int iost; /* I/O statement type */ 00083 register int retval; /* _FWU return value */ 00084 register recn_t errarg; /* Extra _ferr argument */ 00085 register unum_t unum; /* Unit number */ 00086 unit *cup; /* Unit table pointer */ 00087 FIOSPTR css; /* I/O statement state */ 00088 00089 /* 00090 * Assertions 00091 */ 00092 /* Validate that the size of *stck is large enough */ 00093 00094 assert ( cilist->stksize >= sizeof(struct fiostate)/sizeof(long) ); 00095 00096 /* Validate correct unformatted I/O info from compiler */ 00097 00098 assert ( cilist->uflag == CI_UNITNUM ); 00099 assert ( cilist->eorflag == 0 ); 00100 assert ( cilist->endflag == 0 ); 00101 00102 00103 css = stck; 00104 errn = 0; 00105 errarg = 0; 00106 retval = IO_OKAY; 00107 00108 if (iolist->iolfirst == 0) { 00109 cup = css->f_cu; 00110 goto data_transfer; 00111 } 00112 00113 /******************************************************************************* 00114 * 00115 * Statement Initialization Section 00116 * 00117 ******************************************************************************/ 00118 00119 errf = (cilist->errflag || cilist->iostatflg); 00120 unum = *cilist->unit.wa; 00121 iost = cilist->dflag ? T_WDU : T_WSU; 00122 00123 STMT_BEGIN(unum, 0, iost, NULL, css, cup); 00124 00125 if (cup == NULL) { /* If not connected */ 00126 int stat; /* Status */ 00127 00128 cup = _imp_open(css, (cilist->dflag ? DIR : SEQ), UNF, 00129 unum, errf, &stat); 00130 /* 00131 * If the open failed, cup is NULL and stat contains 00132 * the error number. 00133 */ 00134 00135 if (cup == NULL) { 00136 errn = stat; 00137 goto handle_exception; 00138 } 00139 } 00140 00141 cup->f_lastiolist = NULL; /* Indicates whether we are on the last item */ 00142 00143 /* 00144 * Record error processing options in the unit. The _wrunf() etc. 00145 * routines will still use cup->uflag. 00146 */ 00147 cup->uflag = (cilist->errflag ? _UIOSTF : 0) | 00148 (cilist->iostat_spec != NULL ? _UERRF : 0); 00149 00150 cup->uwrt = 1; 00151 cup->ulastyp = DVTYPE_TYPELESS; 00152 00153 if (cilist->dflag) { /* If direct access */ 00154 00155 if (!cup->ok_wr_dir_unf) 00156 errn = _get_mismatch_error(errf, iost, cup, css); 00157 else { 00158 recn_t recn; /* Record number */ 00159 00160 recn = (recn_t) *cilist->rec_spec; 00161 errarg = recn; 00162 errn = _unit_seek(cup, recn, iost); 00163 } 00164 00165 if (cup->udalast > cup->udamax) /* If new highwater mark */ 00166 cup->udamax = cup->udalast; 00167 00168 cup->uend = BEFORE_ENDFILE; 00169 } 00170 else { /* Else sequential access */ 00171 00172 if (!cup->ok_wr_seq_unf) { 00173 errn = _get_mismatch_error(errf, iost, cup, css); 00174 goto handle_exception; 00175 } 00176 00177 if (cup->uend != BEFORE_ENDFILE) { 00178 struct ffsw fst; /* FFIO status block */ 00179 /* 00180 * If positioned after an endfile, and the file does not 00181 * support multiple endfiles, a write is invalid. 00182 */ 00183 if (!cup->umultfil && !cup->uspcproc) { 00184 errn = FEWRAFEN; /* Write after endfile */ 00185 goto handle_exception; 00186 } 00187 /* 00188 * If a logical endfile record had just been read, 00189 * replace it with a physical endfile record before 00190 * starting the current data record. 00191 */ 00192 if ((cup->uend == LOGICAL_ENDFILE) && !(cup->uspcproc)) { 00193 if (XRCALL(cup->ufp.fdc, weofrtn)cup->ufp.fdc, &fst) < 0) 00194 errn = fst.sw_error; 00195 } 00196 00197 cup->uend = BEFORE_ENDFILE; 00198 } 00199 } 00200 00201 if (errn != 0) 00202 goto handle_exception; 00203 00204 /******************************************************************************* 00205 * 00206 * Data Transfer Section 00207 * 00208 ******************************************************************************/ 00209 data_transfer: 00210 00211 cup->f_lastwritten = 0; 00212 if (iolist->iollast && !cilist->dflag && cup->ublkd) { 00213 cup->f_lastiolist = (long *)iolist + iolist->ioetsize; 00214 } 00215 errn = _xfer_iolist(css, cup, iolist, _wrunf); 00216 00217 if (errn != 0) 00218 goto handle_exception; 00219 00220 if (! iolist->iollast) 00221 return(IO_OKAY); 00222 00223 00224 /******************************************************************************* 00225 * 00226 * Finalization 00227 * 00228 ******************************************************************************/ 00229 finalization: 00230 00231 if (cup != NULL) { 00232 cup->ulrecl = cup->urecpos; 00233 cup->urecpos = 0; 00234 cup->f_lastiolist = NULL; /* reset */ 00235 } 00236 00237 if (errn != 0) 00238 goto out_a_here; 00239 00240 if (!cilist->dflag) { /* Sequential Access */ 00241 if (cup->ublkd && cup->f_lastwritten == 0) { 00242 register int ret; /* Return value */ 00243 int dummy; /* Unused word */ 00244 00245 /* Terminate the record */ 00246 00247 ret = _fwwd(cup, &dummy, &__tip_null, FULL, 00248 (int *) NULL, (long *) NULL, &dummy); 00249 00250 if (ret == IOERR) 00251 errn = errno; 00252 } 00253 } 00254 else { /* Direct Access */ 00255 register long bleft; /* bytes unwritten in record */ 00256 00257 bleft = cup->urecl - (cup->ulrecl >> 3); 00258 00259 if (bleft > 0 && cup->udalast == cup->udamax) { 00260 ssize_t ret; /* Return value */ 00261 long zero = 0; /* Zero word */ 00262 long *zbuf; /* Buffer pointer */ 00263 struct ffsw fst; /* FFIO status block */ 00264 00265 /* 00266 * If this is the last direct access record in 00267 * the file and a short record was written, be 00268 * sure it is padded out to its full width as 00269 * required by the Fortran standard. 00270 */ 00271 00272 zbuf = &zero; /* Assume short pad */ 00273 00274 if (bleft > sizeof(long)) { 00275 00276 zbuf = (long *) malloc(bleft); 00277 00278 if (zbuf == NULL) { 00279 errn = FENOMEMY; /* No memory */ 00280 goto handle_exception; 00281 } 00282 else /* Clear record */ 00283 (void) memset((void *) zbuf, 0, (size_t)bleft); 00284 } 00285 00286 switch (cup->ufs) { /* File structure */ 00287 00288 case FS_FDC: 00289 ret = XRCALL(cup->ufp.fdc, writertn) 00290 cup->ufp.fdc, WPTR2BP(zbuf), 00291 bleft, &fst, FULL, (int *)&zero); 00292 00293 if (ret != bleft) 00294 errn = fst.sw_error; 00295 00296 break; 00297 00298 case STD: 00299 ret = fwrite((void *) zbuf, 1, bleft, 00300 cup->ufp.std); 00301 00302 if (ret != bleft) 00303 errn = errno; 00304 00305 break; 00306 00307 default: 00308 errn = FEINTUNK; /* Deep weeds */ 00309 break; 00310 00311 } /* switch */ 00312 00313 /* Free any allocated space */ 00314 00315 if (zbuf != &zero) 00316 free(zbuf); 00317 } 00318 } 00319 00320 if (errn != 0) 00321 goto handle_exception; 00322 00323 out_a_here: 00324 00325 /* Set IOSTAT variable to 0 if no error, >0 error code otherwise */ 00326 00327 if (cilist->iostat_spec != NULL) 00328 *(cilist->iostat_spec) = errn; 00329 00330 STMT_END(cup, TF_WRITE, NULL, css); /* Unlock unit */ 00331 00332 /* Return proper status */ 00333 00334 return (retval); 00335 00336 /* 00337 * We put the error handling stuff here to reduce its impact when 00338 * no errors are generated. If we jump here, errn is set to a nonzero 00339 * error, eor, or endfile status code. 00340 */ 00341 handle_exception: 00342 00343 retval = IO_ERR; 00344 00345 if (! cilist->errflag && ! cilist->iostatflg) 00346 _ferr(css, errn, errarg); 00347 00348 if (cup == NULL) 00349 goto out_a_here; 00350 00351 goto finalization; 00352 }