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/fwch.c 92.2 06/22/99 11:11:33" 00039 00040 #include <errno.h> 00041 #include <liberrno.h> 00042 #include <stdlib.h> 00043 #include "fio.h" 00044 #ifdef _ABSOFT 00045 #include "ac_sysdep.h" 00046 #else /* NOT _ABSOFT */ 00047 00048 #if defined(_LITTLE_ENDIAN) && !defined(__sv2) 00049 #ifndef FILE_CNT 00050 #define FILE_CNT(__f) (__f)->_IO_write_end - (__f)->_IO_write_ptr 00051 #endif 00052 00053 #ifndef FILE_PTR 00054 #define FILE_PTR(__f) (__f)->_IO_write_ptr 00055 #endif 00056 00057 #ifndef FILE_FLAG 00058 #define FILE_FLAG(__f) (__f)->_flags 00059 #endif 00060 00061 #ifndef IOWRT 00062 #define IOWRT = _IO_CURRENTLY_PUTTING 00063 #endif 00064 #ifndef IOREAD 00065 #define IOREAD = _IO_CURRENTLY_APPENDING 00066 #endif 00067 #ifndef IORW 00068 #define IORW = _IO_TIED_PUTGET 00069 #endif 00070 00071 #else /* LITTLE_ENDIAN and not sv2 */ 00072 #ifndef FILE_CNT 00073 #define FILE_CNT(__f) (__f)->_cnt 00074 #endif 00075 00076 #ifndef FILE_PTR 00077 #define FILE_PTR(__f) (__f)->_ptr 00078 #endif 00079 00080 #ifndef FILE_FLAG 00081 #define FILE_FLAG(__f) (__f)->_flag 00082 #endif 00083 00084 #endif /* LITTLE_ENDIAN and not sv2 */ 00085 00086 #endif /* _ABSOFT */ 00087 00088 #ifdef _SOLARIS 00089 #undef putc 00090 #endif 00091 00092 /* 00093 * _fwch 00094 * 00095 * Pack and then write an array of unpacked characters to the 00096 * current record of a file. 00097 * 00098 * Arguments 00099 * cup - unit pointer 00100 * uda - array of characters, one character per word 00101 * chars - number of characters in uda to write 00102 * mode - PARTIAL or FULL record mode 00103 * 00104 * Return value 00105 * chars on successful completion, and -1 on error, with errno set 00106 * to the error code. 00107 * 00108 * Side effects 00109 * Clears cup->uend if the file supports multiple endfile 00110 * records. 00111 */ 00112 00113 long 00114 _fwch( 00115 unit *cup, 00116 long *uda, 00117 long chars, 00118 int mode) 00119 { 00120 register int bytsiz; 00121 register long nchr; 00122 unsigned char tbuf[TBUFSZB]; /* Line packing buffer */ 00123 FILE *fptr; 00124 00125 /* 00126 * If positioned after an endfile, and the file does not 00127 * support multiple endfiles, a write is invalid. 00128 */ 00129 if (cup->uend && !cup->umultfil && !cup->uspcproc) { 00130 errno = FEWRAFEN; 00131 return(IOERR); 00132 } 00133 00134 nchr = 0; 00135 00136 switch (cup->ufs) { 00137 00138 case FS_TEXT: 00139 case STD: 00140 fptr = cup->ufp.std; 00141 00142 /* switch the FILE structure into write mode */ 00143 00144 #if !defined(_LITTLE_ENDIAN) || (defined(_LITTLE_ENDIAN) && defined(__sv2)) 00145 if ((FILE_FLAG(fptr) & (_IOWRT | _IORW)) == _IORW) { 00146 if (FILE_FLAG(fptr) & _IOREAD) 00147 (void) fseek(fptr, 0, SEEK_CUR); 00148 00149 FILE_FLAG(fptr) |= _IOWRT; 00150 } 00151 #endif 00152 00153 #if defined(_SOLARIS) || (defined(_LITTLE_ENDIAN) && !defined(__sv2)) 00154 while (nchr < chars) { 00155 register long count; 00156 register int ret; 00157 /* Pack chars into temp buffer and write them */ 00158 count = chars - nchr; 00159 if (count > TBUFSZB) 00160 count = TBUFSZB; 00161 _pack(&uda[nchr], (char *)tbuf, count, -1); 00162 ret = fwrite(tbuf, 1, count, fptr); 00163 if ( ret != count || ferror(fptr) ) { 00164 if ( ret != count || errno == 0) 00165 errno = FESTIOER; 00166 return(IOERR); 00167 } 00168 nchr += count; 00169 } 00170 #else 00171 00172 /* If the stream is unbuffered... */ 00173 00174 if (FILE_FLAG(fptr) & (_IONBF | _IOLBF)) { 00175 while (nchr < chars) { 00176 register long count; 00177 register long ret; 00178 00179 /* Pack chars into temp buffer and write them */ 00180 00181 count = chars - nchr; 00182 00183 if (count > TBUFSZB) 00184 count = TBUFSZB; 00185 00186 _pack(&uda[nchr], (char *)tbuf, count, -1); 00187 00188 ret = fwrite(tbuf, 1, count, fptr); 00189 00190 if ( ret != count || ferror(fptr) ) { 00191 if ( ret != count || errno == 0) 00192 errno = FESTIOER; 00193 return(IOERR); 00194 } 00195 00196 nchr += count; 00197 } 00198 } 00199 else { /* for a buffered stream... */ 00200 00201 while (FILE_CNT(fptr) < chars - nchr) { 00202 register long count; 00203 register int ret; 00204 00205 count = FILE_CNT(fptr); /* space left in buffer */ 00206 if (count > 0) { 00207 /* pack data into the buffer */ 00208 _pack(&uda[nchr], (char *)FILE_PTR(fptr), 00209 count, -1); 00210 FILE_PTR(fptr) += count; 00211 FILE_CNT(fptr) = 0; 00212 } 00213 00214 /* 00215 * We set errno to 0 here in case the following 00216 * buffer flush fails. UNICOS 8.2 fputc (and 00217 * previous) was not X/Open compliant and did 00218 * not always set errno when a buffer flush 00219 * completed partially due to a disk full 00220 * conditon. The zeroing of errno may be 00221 * removed when we can assume that the fputc() 00222 * from UNICOS and Solaris are X/Open compliant. 00223 */ 00224 00225 errno = 0; 00226 00227 /* 00228 * This fputc() will either trigger a buffer 00229 * flush or cause the buffer to be allocated 00230 * for the first time. 00231 */ 00232 00233 ret = fputc(uda[nchr + count], fptr); 00234 00235 if (ret == EOF && ferror(fptr)) { 00236 if (errno == 0) 00237 errno = FESTIOER; 00238 return(IOERR); 00239 } 00240 00241 nchr += count + 1; 00242 } 00243 00244 if (nchr < chars) { /* Put data in buffer */ 00245 _pack(&uda[nchr], (char *)FILE_PTR(fptr), 00246 chars - nchr, -1); 00247 00248 FILE_CNT(fptr) -= chars - nchr; 00249 FILE_PTR(fptr) += chars - nchr; 00250 } 00251 } 00252 #endif 00253 00254 if (mode == FULL) { 00255 register int ret; 00256 00257 ret = putc('\n', fptr);; 00258 00259 if (ret == EOF && ferror(fptr)) { 00260 if (errno == 0) 00261 errno = FESTIOER; 00262 return(IOERR); 00263 } 00264 chars++; 00265 } 00266 00267 return(chars); 00268 00269 case FS_FDC: 00270 00271 /* 00272 * If a logical endfile record had just been read, 00273 * replace it with a physical endfile record before 00274 * starting the current data record. 00275 */ 00276 if ((cup->uend == LOGICAL_ENDFILE) && !(cup->uspcproc)) { 00277 if (XRCALL(cup->ufp.fdc, weofrtn)cup->ufp.fdc, 00278 &cup->uffsw) < 0){ 00279 errno = cup->uffsw.sw_error; 00280 return(IOERR); 00281 } 00282 } 00283 00284 cup->uend = BEFORE_ENDFILE; 00285 00286 if (cup->ucharset == 0) { 00287 register long ret; 00288 00289 ret = XRCALL(cup->ufp.fdc, writecrtn) cup->ufp.fdc, 00290 WPTR2BP(uda), 00291 chars, &cup->uffsw, mode); 00292 00293 if (ret < 0) { 00294 errno = cup->uffsw.sw_error; 00295 return(IOERR); 00296 } 00297 00298 return(chars); 00299 } 00300 00301 /* 00302 * Get proper byte size (might not be 8-bits if doing conversion). 00303 */ 00304 00305 #if NUMERIC_DATA_CONVERSION_ENABLED 00306 bytsiz = __fndc_charsz[cup->ucharset]; 00307 #else 00308 bytsiz = 8; 00309 #endif 00310 00311 do { 00312 register long breq; 00313 register int fulp; 00314 register long ncnt; 00315 register long ret; 00316 int ubc; 00317 00318 ncnt = TBUFSZB; 00319 breq = 0; 00320 ubc = 0; 00321 00322 if ((chars - nchr) > 0) { 00323 register long totbits; 00324 00325 if (ncnt > (chars - nchr)) 00326 ncnt = chars - nchr; 00327 00328 if (_fdc_packc(tbuf, &uda[nchr], ncnt, 00329 cup->ucharset) < 0) { 00330 return(IOERR); 00331 } 00332 00333 00334 totbits = bytsiz * ncnt; /* bit count */ 00335 breq = (totbits + 7) >> 3; /* 8-bit bytes */ 00336 ubc = (breq << 3) - totbits; 00337 } 00338 00339 nchr += ncnt; 00340 00341 if ((nchr >= chars) && ( mode == FULL )) 00342 fulp = FULL; 00343 else 00344 fulp = PARTIAL; 00345 00346 ret = XRCALL(cup->ufp.fdc, writertn) cup->ufp.fdc, 00347 CPTR2BP(tbuf), 00348 breq, &cup->uffsw, fulp, &ubc); 00349 00350 if (ret != breq) { /* if an error */ 00351 errno = cup->uffsw.sw_error; 00352 return(IOERR); 00353 } 00354 00355 } while (nchr < chars); 00356 00357 return(chars); 00358 /* 00359 * unsupported structure if not TEXT/STD, or FDC 00360 */ 00361 default: 00362 errno = FEINTFST; 00363 return(IOERR); 00364 } 00365 }