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/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 }