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