home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_144 / 2.ddi / CLIBSRC3.ZIP / PUTC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-10  |  7.2 KB  |  275 lines

  1. /*-----------------------------------------------------------------------*
  2.  * filename - putc.c
  3.  *
  4.  * function(s)
  5.  *      fputc    - puts a character on a stream
  6.  *      _fputc   - puts a character on a stream
  7.  *      fputchar - puts a character to stdout
  8.  *      __fputn  - writes bytes on a stream
  9.  *-----------------------------------------------------------------------*/
  10.  
  11. /*
  12.  *      C/C++ Run Time Library - Version 5.0
  13.  *
  14.  *      Copyright (c) 1987, 1992 by Borland International
  15.  *      All Rights Reserved.
  16.  *
  17.  */
  18.  
  19.  
  20. #include <stdio.h>
  21. #include <_stdio.h>
  22. #include <_io.h>
  23. #include <io.h>
  24. #include <mem.h>
  25. #include <fcntl.h>
  26.  
  27. /*---------------------------------------------------------------------*
  28.  
  29. Name            _fputc - puts a character on a stream
  30.  
  31. Usage           int _fputc(int ch, FILE *stream);
  32.  
  33. Prototype in    stdio.h
  34.  
  35. Description     this function is only called by the putc() macro. The
  36.                 only purpose for this is to decrement the level
  37.                 indicator before calling fputc().
  38.  
  39. Return value    On success it returns the character ch
  40.  
  41.                 On error, it returns EOF.
  42.  
  43. *---------------------------------------------------------------------*/
  44.  
  45.  
  46. int _FARFUNC _fputc( char ch,  FILE *fp )
  47.   {
  48.   --fp->level;
  49.  
  50.   return( fputc( ch, fp ) );
  51.   }
  52.  
  53.  
  54. /*---------------------------------------------------------------------*
  55.  
  56. Name            fputc - puts a character on a stream
  57.  
  58. Usage           #include <stdio.h>
  59.                 int fputc(int ch, FILE *stream);
  60.  
  61. Related
  62. functions usage int fputc(int ch, FILE *stream);
  63.                 int fputchar(int ch);
  64.                 int putch(int ch);
  65.  
  66.                 int putchar(int ch);
  67.                 int putw(int w, FILE *stream);
  68.  
  69. Prototype in    stdio.h
  70.  
  71. Description     fputc is like putc but it is a true function that outputs ch to
  72.                 the named stream.
  73.  
  74. Return value    On success putc, fputc, fputchar, and putchar return the
  75.                 character ch, while putw returns the word w, and putch returns
  76.                 nothing.
  77.  
  78.                 On error, all the functions except putch return EOF.
  79.  
  80. *---------------------------------------------------------------------*/
  81.  
  82. int _FARFUNC fputc( int ch,  register FILE *fp )
  83.   {
  84.   static char cr = '\r';
  85.   static unsigned char c;             /*--- SS!=DS ---*/
  86.  
  87.   c = ch;  /* this assignment *MUST* be done *AFTER* the semaphore lock */
  88.  
  89.   if( fp->level < -1 )
  90.     {
  91.     ++fp->level;
  92.  
  93.     *fp->curp++ = c;
  94.  
  95.     if( (fp->flags & _F_LBUF) && ((c == '\n') || (c == '\r')) )
  96.       {
  97.       if( fflush( fp ) )  return( EOF );
  98.       }
  99.  
  100.     return( c );
  101.     }
  102.  
  103.   if( fp->flags & (_F_IN | _F_ERR) || !(fp->flags & _F_WRIT) )
  104.     {
  105.     fp->flags |= _F_ERR;
  106.     return( EOF );
  107.     }
  108.  
  109.   fp->flags |= _F_OUT;
  110.  
  111.   if( fp->bsize != 0 )     /* is the stream buffered ? */
  112.     {
  113.     /*  The level is zero only at initialization or after a rewind
  114.         or seek, when _F_OUT is not yet decided and the buffer empty.
  115.     */
  116.     if( fp->level )
  117.       {
  118.       if( fflush( fp ) )  return( EOF );
  119.       }
  120.  
  121.     fp->level = -fp->bsize;
  122.  
  123.     *fp->curp++ = c;
  124.  
  125.     if( (fp->flags & _F_LBUF) && ((c == '\n') || (c == '\r')) )
  126.       {
  127.       if( fflush( fp ) )  return( EOF );
  128.       }
  129.  
  130.     return( c );
  131.     }
  132.   else                     /* the stream is not buffered */
  133.     {
  134.     if (_openfd[fp->fd] & O_APPEND)
  135.       lseek (fp->fd, 0L, SEEK_END);
  136.  
  137.     if( (('\n' == c) && ! (fp->flags & _F_BIN) &&
  138.         (_write( fp->fd, & cr, 1 ) != 1) )  ||
  139.         (_write( fp->fd, & c , 1 ) != 1) )
  140.       {
  141.       if( (fp->flags & _F_TERM) == 0 )
  142.         {
  143.         fp->flags |= _F_ERR;
  144.         return( EOF );
  145.         }
  146.       }
  147.  
  148.     return( c );
  149.     }
  150.   }
  151.  
  152.  
  153. /*---------------------------------------------------------------------*
  154.  
  155. Name            fputchar - puts a character to stdout
  156.  
  157.  
  158. Usage           int fputchar (register int c);
  159.  
  160. Prototype in    stdio.h
  161.  
  162. Description     fputchar simply calls fputc to output its argument to
  163.                 stdout.
  164.  
  165. Return value    see fgetc.
  166.  
  167. *---------------------------------------------------------------------*/
  168.  
  169. int _FARFUNC fputchar( register int c )
  170.   {
  171.   return( fputc( c, stdout ) );
  172.   }
  173.  
  174.  
  175. /*---------------------------------------------------------------------*
  176.  
  177. Name            __fputn - writes bytes on a stream
  178.  
  179. Usage           size_t  pascal __fputn (const void *ptr, register size_t n, FILE *fp)
  180.  
  181. Prototype in    stdio.h
  182.  
  183. Description     __fputn writes n bytes whose address is referenced by ptr to
  184.                 an open stream fp.
  185.  
  186. Return value    The number of bytes written is returned on success;
  187.                 zero is returned on failure.
  188.  
  189. *---------------------------------------------------------------------*/
  190. size_t pascal near __fputn( const void *ptr, size_t n, register FILE *fp )
  191.   {
  192.   int len = n;
  193.  
  194.   if( fp->flags & _F_LBUF )         /* if it's line buffered, */
  195.     {                               /* handle it in the traditional way */
  196.     while( n-- )
  197.       {
  198.       if( fputc( *((char *)ptr)++, fp ) == EOF )  return( 0 );
  199.       }
  200.  
  201.     return( len );
  202.     }
  203.   else                              /* yipee, it isn't line buffered */
  204.     {
  205.     if( fp->flags & _F_BIN )        /* binary mode? */
  206.       {
  207.  
  208.       if( fp->bsize )               /* is it buffered? */
  209.         {
  210.         if( n > fp->bsize )         /* too big to fit in buffer? */
  211.           {
  212.           if( fp->level )
  213.             {
  214.             if( fflush( fp ) )  return( 0 );
  215.             }
  216.  
  217.           if (_openfd[fp->fd] & O_APPEND)
  218.             lseek (fp->fd, 0L, SEEK_END);
  219.           if( _write( fp->fd, (void *)ptr, n ) != n )  return( 0 );
  220.           else                                return( len );
  221.           }
  222.         else                        /* it is small enough to fit */
  223.           {
  224.           if( fp->level + (int)n >= 0 )  /* must we flush it to make room? */
  225.             {
  226.             if( fp->level == 0 )
  227.               {
  228.               fp->level = -1 - fp->bsize;
  229.               }
  230.             else
  231.               {
  232.               if( fflush( fp ) )  return( 0 );
  233.               }
  234.             }
  235.  
  236.           /* stuff it into the file buffer all at once! */
  237.           memcpy( fp->curp, ptr, n );
  238.           fp->level += n;
  239.           fp->curp += n;
  240.  
  241.           return( len );
  242.           }
  243.         }
  244.       else                          /* it is unbuffered */
  245.         {
  246.         /* write it all at once! */
  247.         if (_openfd[fp->fd] & O_APPEND)
  248.           lseek (fp->fd, 0L, SEEK_END);
  249.         if( _write( fp->fd, (void *)ptr, n ) != n )  return( 0 );
  250.         else                                return( len );
  251.         }
  252.       }
  253.     else                            /* oh no, the cursed text mode! */
  254.       {
  255.       if( fp->bsize )               /* is it buffered? */
  256.         {
  257.         while( n-- )
  258.           {
  259.           if( putc( *((char *)ptr)++, fp ) == EOF )  return( 0 );
  260.           }
  261.  
  262.         return( len );
  263.         }
  264.       else                          /* it is unbuffered */
  265.         {
  266.         /* write it all at once! */
  267.         if( __write( fp->fd, (void *)ptr, n ) != n )  return( 0 );
  268.         else                               return( len );
  269.         }
  270.       }
  271.     }
  272.   }
  273.  
  274.  
  275.