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/fseek.c 92.1 06/18/99 19:52:04" 00039 00040 /* 00041 * Position a file associated with a fortran logical unit with 00042 * MIPS F77 and MIPS f90. 00043 * 00044 * CALLING SEQUENCE: 00045 * 00046 * INTEGER ierror, ioff, ifrom, lunit 00047 * ierror = fseek(lunit, ioff, ifrom) 00048 * 00049 * INTEGER ierror, ioff, ifrom, lunit 00050 * INTEGER(KIND=8) lioff 00051 * ierror = fseek64(lunit, lioff, ifrom) 00052 * 00053 * WHERE: 00054 * 00055 * lunit = an open logical unit 00056 * 00057 * ioff = an offset in bytes relative to the position 00058 * specified by ifrom 00059 * 00060 * lioff = an offset in bytes relative to the position 00061 * specified by ifrom 00062 * 00063 * ifrom = - 0 means 'beginning of the file' 00064 * = - 1 means 'the current position' 00065 * = - 2 means 'the end of the file' 00066 * 00067 * ierror = 0 if successful. 00068 * .NE. 0 a system error code if unsuccessful. 00069 * 00070 * NOTES: fseek64() only exists in the 64 bit library 00071 * 00072 * __fseek_f90 is called for mips f77 or if there is no 00073 * compatibility mode from mips f90. 00074 * 00075 * fseekf90_ is called for mips f90 if there is a 00076 * compatibility mode. 00077 * 00078 * __fseek64_f90 is called for mips f77 or if there is no 00079 * compatibility mode from mips f90. 00080 * 00081 * fseekf90_8_ is called for mips f90 if there is a 00082 * compatibility mode. 00083 * 00084 * fseekf90_4_8_4_ is called for mips f90 if there is a 00085 * compatibility mode. 00086 * 00087 */ 00088 00089 #include "fio.h" 00090 00091 extern int __fseek_f90(int *u, int *off, int *from); 00092 extern _f_int fseekf90_(_f_int *u, _f_int *off, _f_int *from); 00093 extern _f_int __fseek64_f90(_f_int *u, _f_int8 *off, int *from); 00094 extern _f_int8 fseekf90_8_(_f_int8 *u, _f_int8 *off, int8 *from); 00095 extern _f_int fseekf90_4_8_4_(_f_int *u, _f_int8 *off, int *from); 00096 00097 static _f_int __setpos64( unit *cup, _f_int8 ioff, _f_int whence); 00098 00099 int 00100 __fseek_f90(int *u, int *off, int *from) 00101 { 00102 return fseekf90_(u, off, from); 00103 } 00104 00105 _f_int 00106 fseekf90_(_f_int *u, _f_int *off, _f_int *from) 00107 { 00108 unit *cup; /* Unit table pointer */ 00109 struct fiostate cfs; 00110 _f_int8 ioff; 00111 unum_t unum; 00112 _f_int rtrn; 00113 00114 unum = *u; 00115 ioff = *off; 00116 /* lock the unit */ 00117 STMT_BEGIN( unum, 0, T_SETPOS, NULL, &cfs, cup); 00118 00119 /* If not connected, do an implicit open. Abort if open fails. */ 00120 if (cup == NULL) 00121 cup = _imp_open(&cfs, SEQ, UNF, unum, 0, NULL); 00122 00123 /* if direct access file, error. */ 00124 if (cup->useq == 0) 00125 _ferr(&cfs, FEBIONDA, "SETPOS"); 00126 00127 /* Do the setpos. */ 00128 if (__setpos64(cup, ioff, *from) != 0) 00129 rtrn = errno; 00130 else 00131 rtrn = 0; 00132 00133 /* unlock the unit. */ 00134 STMT_END(cup, T_SETPOS, NULL, &cfs); 00135 return rtrn; 00136 } 00137 00138 _f_int 00139 __fseek64_f90(_f_int *u, _f_int8 *off, int *from) 00140 { 00141 return fseekf90_4_8_4_(u, off, from); 00142 } 00143 00144 _f_int 00145 fseekf90_4_8_4_(_f_int *u, _f_int8 *off, int *from) 00146 { 00147 unit *cup; /* Unit table pointer */ 00148 struct fiostate cfs; 00149 _f_int8 ioff; 00150 unum_t unum; 00151 _f_int rtrn; 00152 00153 unum = *u; 00154 ioff = *off; 00155 00156 /* lock the unit. */ 00157 STMT_BEGIN( unum, 0, T_SETPOS, NULL, &cfs, cup); 00158 00159 /* If not connected, do an implicit open. Abort if open fails. */ 00160 if (cup == NULL) 00161 cup = _imp_open(&cfs, SEQ, UNF, unum, 0, NULL); 00162 00163 if (cup->useq == 0) /* If direct access file */ 00164 _ferr(&cfs, FEBIONDA, "SETPOS"); 00165 00166 /* 00167 * Do the setpos. 00168 */ 00169 if (__setpos64(cup, ioff, *from) != 0) 00170 rtrn=errno; 00171 else 00172 rtrn = 0; 00173 STMT_END(cup, T_SETPOS, NULL, &cfs); /* unlock the unit */ 00174 return rtrn; 00175 } 00176 00177 _f_int8 00178 fseekf90_8_(_f_int8 *u, _f_int8 *off, int8 *from) 00179 { 00180 unit *cup; /* Unit table pointer */ 00181 struct fiostate cfs; 00182 _f_int8 ioff; 00183 unum_t unum; 00184 _f_int rtrn; 00185 _f_int whenc; 00186 00187 unum = *u; 00188 ioff = *off; 00189 whenc = *from; 00190 00191 /* lock the unit. */ 00192 STMT_BEGIN( unum, 0, T_SETPOS, NULL, &cfs, cup); 00193 00194 /* If not connected, do an implicit open. Abort if open fails. */ 00195 if (cup == NULL) 00196 cup = _imp_open(&cfs, SEQ, UNF, unum, 0, NULL); 00197 00198 if (cup->useq == 0) /* If direct access file */ 00199 _ferr(&cfs, FEBIONDA, "SETPOS"); 00200 00201 /* 00202 * Do the setpos. 00203 */ 00204 if (__setpos64(cup, ioff, *from) != 0) 00205 rtrn=errno; 00206 else 00207 rtrn = 0; 00208 STMT_END(cup, T_SETPOS, NULL, &cfs); /* unlock the unit */ 00209 return rtrn; 00210 } 00211 00212 /* 00213 * __setpos64 is a 64-bit version of _setpos where user specifies a 00214 * "whence" parameter like the unix version of fseek(). Note: this 00215 * is NOT a general replacement for _setpos for MIPS. 00216 */ 00217 00218 _f_int 00219 __setpos64( 00220 unit *cup, /* unit pointer */ 00221 _f_int8 ioff, /* offset */ 00222 _f_int whence) /* 0 - from beginning of file 00223 * 1 - from the current position 00224 * 2 - from the end of the file 00225 */ 00226 { 00227 _f_int ret; 00228 _f_int retstat; 00229 struct fdinfo *fio; 00230 int fp_parm[2]; 00231 00232 retstat = 0; 00233 00234 /* Wait for completion of a preceding asynchronous BUFFER IN/OUT. */ 00235 WAITIO(cup, return(cup->uffsw.sw_error)); 00236 00237 cup->urecpos = 0; 00238 if (cup->uwrt) { 00239 if (cup->utrunc) { 00240 ret = _unit_trunc(cup); 00241 if (ret != 0) 00242 return(ret); 00243 } 00244 cup->uwrt = 0; 00245 } 00246 /* 00247 * Make appropriate call to set file position according to the file 00248 * structure. Positioning routines are file-structure dependent. 00249 */ 00250 switch( cup->ufs ) { 00251 00252 case FS_TEXT: 00253 case STD: 00254 /* 00255 * If unformatted file, then positioning is done to a word 00256 * boundary. Converto to bytes 00257 */ 00258 if ( cup->ufmt == NO ) 00259 ioff <<= 3; 00260 00261 ret = fseek64(cup->ufp.std, ioff, whence); 00262 if (ret != 0) 00263 return(errno); 00264 00265 break; 00266 00267 case FS_FDC: 00268 fio = cup->ufp.fdc; 00269 00270 if ((cup->uflagword & FFC_SEEKA) || 00271 (whence==2 && (cup->uflagword & FFC_SEEKE))){ 00272 00273 if (whence==2) { 00274 00275 ret = XRCALL(fio, seekrtn) fio, ioff, 2, 00276 &cup->uffsw); 00277 if (ret < 0) 00278 return(cup->uffsw.sw_error); 00279 00280 /* bit position in file */ 00281 ret <<= 3; 00282 } else { 00283 /* A couple of problems will need to be solved before we can */ 00284 /* use the ffio posrtn on MIPS. That routine is currently */ 00285 /* documented as expecting longs in the 3rd parameter for */ 00286 /* FP_BSEEK . But more importantly, FP_BSEEK isn't supported */ 00287 /* yet for MIPS, because longs are not sufficiently large */ 00288 /* to contain all possible file positions. */ 00289 return(FDC_ERR_NOSUP); 00290 } 00291 } 00292 else { 00293 /* 00294 * Assume that positioning is done via a 'magic cookie'. 00295 * Just pass it through. 00296 */ 00297 ret = XRCALL(fio, posrtn) 00298 fio, FP_SETPOS, &ioff, 1, &cup->uffsw); 00299 } 00300 00301 if (ret < 0) 00302 return(cup->uffsw.sw_error); 00303 ret = 0; 00304 break; 00305 00306 case FS_AUX: 00307 return(FEMIXAUX); 00308 default: 00309 return(FEINTFST); 00310 } 00311 00312 /* Set the end flag if going to EOD, else clear it. */ 00313 if ((ioff==0 && whence==2) ) { 00314 if (cup->ufs != FS_FDC) 00315 cup->uend = LOGICAL_ENDFILE; 00316 else { 00317 /* 00318 * This is after terminal endfile record of the 00319 * file, but we must decide if it's a logical or 00320 * physical endfile record. 00321 */ 00322 if ((cup->uflagword & FFC_WEOF) == 0) 00323 cup->uend = LOGICAL_ENDFILE; 00324 else { 00325 /* byte offset within file */ 00326 int fbytepos; 00327 00328 switch (fio->class) { 00329 00330 case CLASS_COS: 00331 /* 00332 * Since seekrtn for a cos layer 00333 * when called with 0,2 does NOT 00334 * return a resulting byte offset, 00335 * query the position with this 00336 * seekrtn call. The only case 00337 * where 0 might be returned is 00338 * when the file is empty. 00339 */ 00340 fbytepos = XRCALL(fio, seekrtn) fio, 0, 00341 1, &cup->uffsw); 00342 if (fbytepos > 0) 00343 cup->uend = PHYSICAL_ENDFILE; 00344 else 00345 cup->uend = LOGICAL_ENDFILE; 00346 break; 00347 default: 00348 return(FEBIOSNT); 00349 } 00350 } 00351 } 00352 } else 00353 /* 00354 * Sadly, we may be positioned after an endfile record, 00355 * and not know it. This should be fixed. 00356 */ 00357 cup->uend = BEFORE_ENDFILE; 00358 return(OK); 00359 }