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/rf90.c 92.4 06/18/99 15:49:57" 00039 00040 #include <ctype.h> 00041 #include <errno.h> 00042 #include <liberrno.h> 00043 #include <fortran.h> 00044 #include <stdlib.h> 00045 #include <string.h> 00046 #include <unistd.h> 00047 #include <cray/fmtconv.h> 00048 #include <cray/format.h> 00049 #include <cray/nassert.h> 00050 #ifndef _ABSOFT 00051 #include <sys/unistd.h> 00052 #endif 00053 #include "fio.h" 00054 #include "fmt.h" 00055 #include "fstats.h" 00056 #include "f90io.h" 00057 00058 /* 00059 * _FRF Called by compiled Fortran programs to process a formatted 00060 * or list-directed read statement. Each statement is 00061 * processed by one or more calls to _FRF. 00062 * 00063 * Synopsis 00064 * 00065 * int _FRF( ControlList *cilist, 00066 * iolist_header *iolist, 00067 * void *stck); 00068 * 00069 * Where 00070 * 00071 * cilist Pointer to the control information list 00072 * information. This describes the specifiers 00073 * for the current I/O statement. This cilist 00074 * is guaranteed by the compiler to reflect 00075 * the original values of control information 00076 * list variables for the duration of the I/O 00077 * statement (ie through multiple calls). 00078 * iolist Pointer to the I/O list information. 00079 * stck Pointer to stack space which is passed 00080 * to each call to _FRF for a particular 00081 * statement. This space is used by the 00082 * library. 00083 * 00084 * Return value 00085 * 00086 * IO_OKAY, IO_ERR, IO_END, or IO_EOR 00087 */ 00088 int 00089 _FRF(ControlListType *cilist, iolist_header *iolist, void *stck) 00090 { 00091 register int errf; /* ERR processing flag */ 00092 register int errn; /* Error number */ 00093 register int iost; /* I/O statement type */ 00094 register int retval; /* _FRF return value */ 00095 register recn_t errarg; /* Extra _ferr argument */ 00096 register unum_t unum; /* Unit number */ 00097 unit *cup; /* Unit table pointer */ 00098 FIOSPTR css; /* I/O statement state */ 00099 00100 /* 00101 * Assertions 00102 */ 00103 /* Validate that the size of *stck is large enough */ 00104 assert ( cilist->stksize >= sizeof(struct fiostate)/sizeof(long) ); 00105 00106 /* The compiler disallows ADVANCE='YES' w/ SIZE= */ 00107 assert ( ! (cilist->advcode == CI_ADVYES && cilist->size_spec != NULL)); 00108 00109 /* The compiler disallows ADVANCE='YES' w/ EOR= */ 00110 assert ( ! (cilist->advcode == CI_ADVYES && cilist->eorflag)); 00111 00112 /* The compiler disallows ADVANCE= w/ internal files */ 00113 assert( ! (cilist->advcode != CI_ADVYES && cilist->internal != 0)); 00114 00115 /* The compiler disallows ADVANCE= w/ list-directed */ 00116 assert( ! (cilist->advcode != CI_ADVYES && cilist->fmt == CI_LISTDIR)); 00117 00118 css = stck; 00119 errn = 0; 00120 errarg = 0; 00121 retval = IO_OKAY; 00122 00123 if (iolist->iolfirst == 0) { 00124 cup = css->f_cu; 00125 goto data_transfer; 00126 } 00127 00128 /******************************************************************************* 00129 * 00130 * Statement Initialization Section 00131 * 00132 ******************************************************************************/ 00133 00134 /* Establish error processing options */ 00135 00136 errf = (cilist->errflag || cilist->iostatflg); 00137 00138 if (cilist->fmt == CI_LISTDIR) 00139 iost = T_RLIST; 00140 else if (cilist->dflag) 00141 iost = T_RDF; 00142 else 00143 iost = T_RSF; 00144 00145 /* Zero the SIZE= value before any errors are encountered */ 00146 00147 if (iost & TF_FMT) 00148 css->u.fmt.u.fe.charcnt = 0; 00149 00150 css->u.fmt.freefmtbuf = 0; 00151 css->u.fmt.freepfmt = 0; 00152 css->u.fmt.tempicp = NULL; 00153 00154 /* Check if we're doing internal I/O or external I/O */ 00155 00156 if (cilist->internal) { /* If internal I/O */ 00157 STMT_BEGIN(-1, 1, iost, NULL, css, cup); 00158 cup->uft90 = 1; /* set F90 mode for internal file */ 00159 #ifndef __mips 00160 cup->ufcompat = 2; /* set CF90 on internal file */ 00161 cup->ufunilist = 0; 00162 cup->ufcomsep = 0; 00163 cup->ufcomplen = 0; 00164 cup->ufrptcnt = 0; 00165 #elif defined(_LITTLE_ENDIAN) 00166 cup->ufcompat = 0; /* set no f90 on internal file */ 00167 cup->ufunilist = 0; 00168 cup->ufcomsep = 0; 00169 cup->ufcomplen = 0; 00170 cup->ufrptcnt = 0; 00171 #else 00172 cup->ufcompat = 4; /* set IRIXF90 on internal file */ 00173 cup->ufunilist = 0; 00174 cup->ufcomsep = 0; 00175 cup->ufcomplen = 0; 00176 cup->ufrptcnt = 0; 00177 #endif 00178 } 00179 else { /* Else external I/O */ 00180 if (cilist->uflag == CI_UNITASTERK) 00181 unum = STDIN_U; 00182 else 00183 unum = *cilist->unit.wa; 00184 00185 STMT_BEGIN(unum, 0, iost, NULL, css, cup); 00186 00187 if (cup == NULL) { /* If not connected */ 00188 int stat; 00189 00190 cup = _imp_open( css, 00191 (cilist->dflag ? DIR : SEQ), 00192 FMT, 00193 unum, 00194 errf, 00195 &stat); 00196 00197 /* 00198 * If the open failed, cup is NULL and stat contains 00199 * the error number. 00200 */ 00201 if (cup == NULL) { 00202 errn = stat; 00203 goto handle_exception; 00204 } 00205 } 00206 } 00207 00208 /* All paths which lead here have set cup to a non-null value */ 00209 00210 assert (cup != NULL); 00211 00212 /* Copy the user's error processing options into the unit table */ 00213 00214 cup->uflag = (cilist->errflag ? _UERRF : 0) | 00215 (cilist->endflag ? _UENDF : 0) | 00216 (cilist->eorflag ? _UEORF : 0) | 00217 (cilist->iostat_spec != NULL ? _UIOSTF : 0); 00218 00219 /* Initialize fields in the Fortran statement state structure */ 00220 00221 css->u.fmt.icp = NULL; 00222 css->u.fmt.blank0 = cup->ublnk; 00223 css->u.fmt.lcomma = 0; 00224 css->u.fmt.slash = 0; 00225 #ifdef _CRAYMPP 00226 css->f_shrdput = 0; 00227 #endif 00228 00229 /* Process the format and related specifiers */ 00230 00231 if (cilist->fmt != CI_LISTDIR) { /* If formatted input */ 00232 register int stat; 00233 00234 css->u.fmt.u.fe.fmtbuf = NULL; 00235 css->u.fmt.u.fe.fmtnum = 0; 00236 css->u.fmt.u.fe.fmtcol = 0; 00237 css->u.fmt.u.fe.scale = 0; 00238 00239 errn = setup_format(css, cup, cilist); 00240 00241 if (errn > 0) 00242 goto handle_exception; 00243 00244 /* Handle ADVANCE specifier */ 00245 00246 stat = _is_nonadv(cilist); 00247 00248 if (stat < 0) 00249 errn = FEADVSPC; /* Invalid ADVANCE specifier */ 00250 00251 if (cilist->advcode == CI_ADVVAR && stat == 0) { 00252 if (cilist->size_spec != NULL) 00253 errn = FEADVSIZ; /* ADVANCE='YES' w/SIZE= */ 00254 00255 if (cilist->eorflag) 00256 errn = FEADVEOR; /* ADVANCE='YES' w/EOR= */ 00257 } 00258 00259 if (errn != 0) 00260 goto handle_exception; 00261 00262 css->u.fmt.nonadv = stat; 00263 } 00264 else /* Else list-directed input */ 00265 css->u.fmt.nonadv = 0; 00266 00267 /* Set processing functions */ 00268 00269 if (cilist->dflag) { 00270 00271 if (!cup->ok_rd_dir_fmt) 00272 errn = _get_mismatch_error(errf, iost, cup, css); 00273 else { 00274 register recn_t recn; /* Record number */ 00275 00276 recn = (recn_t) *cilist->rec_spec; 00277 errarg = recn; 00278 errn = _unit_seek(cup, recn, iost); 00279 } 00280 00281 css->u.fmt.endrec = _dr_endrec; 00282 } 00283 else { 00284 00285 if (!cup->ok_rd_seq_fmt) { 00286 errn = _get_mismatch_error(errf, iost, cup, css); 00287 goto handle_exception; 00288 } 00289 00290 if (cilist->internal) { 00291 00292 css->u.fmt.endrec = _ir_endrec; 00293 00294 if (cilist->uflag == CI_UNITCHAR) { 00295 css->u.fmt.iiae = 1; 00296 css->u.fmt.icp = _fcdtocp(cilist->unit.fcd); 00297 css->u.fmt.icl = _fcdlen (cilist->unit.fcd); 00298 } 00299 else { 00300 DopeVectorType *dv = cilist->unit.dv; 00301 void *newar; 00302 int nocontig = 0; 00303 long extent = 0; 00304 long nbytes = 0; 00305 00306 css->u.fmt.icp = _fcdtocp(dv->base_addr.charptr); 00307 css->u.fmt.icl = _fcdlen (dv->base_addr.charptr); 00308 00309 newar = (void *) NULL; 00310 00311 if (dv->p_or_a && (dv->assoc == 0)) 00312 errn = FEUNOTAL; /* Not allocated/associated */ 00313 else /* Check for contiguous array */ 00314 errn = _cntig_chk(dv, &newar, &nocontig, 00315 &extent, &nbytes); 00316 00317 if (errn != 0) 00318 goto handle_exception; 00319 00320 /* Number of elements in array */ 00321 00322 css->u.fmt.iiae = extent; 00323 00324 if (nocontig) { 00325 css->u.fmt.icp = newar; 00326 css->u.fmt.tempicp = newar; 00327 } 00328 } 00329 00330 /* 00331 * If the size of the internal record is greater 00332 * than the existing line buffer, then realloc() 00333 * another one; else just decrease urecsize. 00334 */ 00335 00336 if (css->u.fmt.icl > cup->urecsize) { 00337 00338 cup->ulinebuf = (long *) realloc(cup->ulinebuf, 00339 sizeof(long) * 00340 (css->u.fmt.icl + 1)); 00341 00342 if (cup->ulinebuf == NULL) 00343 errn = FENOMEMY; /* No memory */ 00344 } 00345 00346 cup->urecsize = css->u.fmt.icl; 00347 } 00348 else { /* external sequential formatted I/O */ 00349 00350 if (cup->uend != BEFORE_ENDFILE && !cup->umultfil) /* If after endfile */ 00351 errn = FERDENDR; /* Read after endfile */ 00352 00353 if (cup->uwrt) /* If writing */ 00354 errn = FERDAFWR; /* Read after write */ 00355 00356 css->u.fmt.endrec = _sr_endrec; 00357 00358 } 00359 } 00360 00361 if (errn != 0) 00362 goto handle_exception; 00363 00364 if (cup->pnonadv == 0) { /* If previous ADVANCE='YES' */ 00365 errn = (*css->u.fmt.endrec)(css, cup, 1); /* Read a record */ 00366 00367 if (errn != 0) 00368 goto handle_exception; 00369 } 00370 else /* else previous ADVANCE='NO' */ 00371 css->u.fmt.leftablim = cup->ulineptr; /* Set left tab limit */ 00372 00373 cup->pnonadv = css->u.fmt.nonadv; /* Remember previous ADVANCE */ 00374 cup->uwrt = 0; /* Set read status */ 00375 00376 /******************************************************************************* 00377 * 00378 * Data Transfer Section 00379 * 00380 ******************************************************************************/ 00381 data_transfer: 00382 00383 errn = _xfer_iolist(css, cup, iolist, (cilist->fmt == CI_LISTDIR) ? 00384 _ld_read : _rdfmt); 00385 00386 if (errn != 0) 00387 goto handle_exception; 00388 00389 if (! iolist->iollast ) 00390 return (IO_OKAY); 00391 00392 /****************************************************************************** 00393 * 00394 * Statement Finalization Section 00395 * 00396 ******************************************************************************/ 00397 finalization: 00398 00399 #ifdef _CRAYMPP 00400 if (css->f_shrdput) { 00401 css->f_shrdput = 0; 00402 _remote_write_barrier(); 00403 } 00404 #endif 00405 /* If formatted I/O and no error/EOF/EOR, complete processing */ 00406 00407 if (cilist->fmt != CI_LISTDIR) { /* If formatted */ 00408 00409 if (errn == 0) /* Complete format */ 00410 errn = _rdfmt(css, cup, (void *) NULL, &__tip_null, 00411 0); 00412 00413 /* If we allocated memory for a variable format, free it */ 00414 00415 if (css->u.fmt.freepfmt && css->u.fmt.u.fe.pfmt != NULL) 00416 free(css->u.fmt.u.fe.pfmt); 00417 00418 /* If we allocated memory for a noncontiguous format, 00419 * free it. 00420 */ 00421 00422 if (css->u.fmt.freefmtbuf && css->u.fmt.u.fe.fmtbuf != NULL) 00423 free(css->u.fmt.u.fe.fmtbuf); 00424 } 00425 00426 /* 00427 * If we allocated memory for an internal file, move the output 00428 * file from the temporary array to the noncontiguous array and 00429 * free the temporary array. 00430 */ 00431 00432 if (cilist->internal && css->u.fmt.tempicp != NULL) { 00433 (void) _unpack_arry (css->u.fmt.tempicp, 00434 cilist->unit.dv); 00435 free(css->u.fmt.tempicp); 00436 } 00437 00438 out_a_here: 00439 00440 /* Set IOSTAT variable to 0 if no error, >0 error code otherwise */ 00441 00442 if (cilist->iostat_spec != NULL) 00443 *cilist->iostat_spec = errn; 00444 00445 /* Store character count in the SIZE= variable */ 00446 00447 if (cilist->size_spec != NULL) 00448 *cilist->size_spec = css->u.fmt.u.fe.charcnt; 00449 00450 STMT_END(cup, TF_READ, NULL, css); /* Unlock unit */ 00451 00452 /* Return proper status */ 00453 00454 return (retval); 00455 00456 /* 00457 * We put the error handling stuff here to reduce its impact when 00458 * no errors are generated. If we jump here, errn is set to a nonzero 00459 * error, eor, or endfile status code. 00460 */ 00461 handle_exception: 00462 if (errn < 0) { /* If EOF/EOR type error */ 00463 00464 /* No current record if EOF or EOR */ 00465 00466 if (cup != NULL) 00467 cup->pnonadv = 0; 00468 00469 if (errn == FEEORCND) 00470 retval = IO_EOR; 00471 else 00472 retval = IO_END; 00473 } 00474 else 00475 retval = IO_ERR; 00476 00477 if (retval == IO_ERR && ! cilist->errflag && ! cilist->iostatflg) 00478 _ferr(css, errn, errarg); 00479 00480 if (retval == IO_EOR && ! cilist->eorflag && ! cilist->iostatflg) 00481 _ferr(css, errn, errarg); 00482 00483 if (retval == IO_END && ! cilist->endflag && ! cilist->iostatflg) 00484 _ferr(css, errn, errarg); 00485 00486 if (cup == NULL) 00487 goto out_a_here; 00488 00489 goto finalization; 00490 }