/****************************************************************************
*
*			_ f i l b u f   F u n c t i o n
*			-------------------------------
*	Copyright 1982 by Digital Research Inc.  All rights reserved.
*
*	"_filbuf" function is called by getc to fill the buffer.
*	It performs any initialization of the buffered on the first
*	call.
*
*	Calling sequence:
*		char = _filbuf(stream)
*	Where:
*		stream -> file info
*		char   = the first character returned, or FAILURE (-1)
*			on error or EOF
*
*****************************************************************************/

#include "stdio.h"
#define CMASK 0xFF

WORD _filbuf(sp)				/* fill buffer		    */
REG	FILE *sp;				/* from this stream	    */
{						/****************************/
	static BYTE onebuf[MAXFILES];		/* a place if no mem avail. */
						/* small buf for ungetc	    */
	EXTERN BYTE *malloc();			/* someplace to get mem	    */
						/****************************/
	if((sp->_flag & _IOREAD) == 0)		/* is readable file?	    */
		return(FAILURE);		/*    no		    */
	if( sp->_flag & _IOSTRI )		/* is this stream a string? */
	{					/*    yes: handle EOS as EOF*/
		sp->_flag |= _IOEOF;		/*			    */
		return(FAILURE);		/*			    */
	}					/****************************/
	if( sp->_base == NULL )			/* has this been done?	    */
	{					/* no...*********************/
	    if( sp->_flag & _IONBUF  ||		/* is the No Buf flag set?  */
		(sp->_base=malloc(BUFSIZ))==NULL) /* can't we get buffer?   */
		    sp->_flag |= _IONBUF;	/*   set No Buf flag	    */
	    else    sp->_flag |= _IOABUF;	/* we're all set	    */
	}					/****************************/
	if( sp->_flag & _IONBUF )		/* insure this set right    */
		sp->_base = &onebuf[sp->_fd];	/*   set 'buf' to small buf */
	if( sp==stdin  &&  (stdout->_flag&_IOLBUF))/* console i/o?	    */
		fflush(stdout);			/* output whatever to con   */
	sp->_cnt = read(sp->_fd, sp->_base,	/* read to our buffer	    */
	    sp->_flag & _IONBUF ? 1 : BUFSIZ);	/*   the right # of bytes   */
	if( sp->_cnt <= 0 )			/* did read screw up?	    */
	{					/* yup...********************/
	    if( sp->_cnt == FAILURE )		/*  really bad?		    */
		    sp->_flag |= _IOERR|_IOEOF;	/*    say so		    */
	    else    sp->_flag |= _IOEOF;	/* or just say we can't read*/
	    return(FAILURE);			/*			    */
	}					/****************************/
	sp->_cnt--;				/* take the 1st item	    */
	sp->_ptr=sp->_base;			/* set up stream	    */
	return(((WORD)(*sp->_ptr++) & CMASK));	/* and return the char	    */
}						/****************************/
