Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
fwch.c
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines