text: /*
  **  NEED.C -- general buffer allocation routines
  **
  **	allow buffers with LIFO de-allocation
  **
  **	Defines:
  **		need()
  **		initbuf()
  **
  **	History:
  **		10/10/78 -- (marc) modified from need in ovqp.
  **			New are : err_num, err_func stuff, and
  **			seterr().
  */
  
  
  
  
  
  
  /* structure that the routines use to allocate space */
  struct nodbuffer
  {
  	int		nleft;		/* bytes left */
  	int		err_num;	/* error code on overflow */
  	int		(*err_func)();	/* error function on overflow */
  	char		*xfree;		/* next free byte */
  	char		buffer [];	/*beginning of buffer area */
  };
  
  /*
  **  NEED -- allocate space from a buffer
  **
  **	On buffer overflow, calls err_func from that field
  **	in the buffer with the error code err_code from that field
  **	in the buffer, then returns 0.
  **	need() guarantees an even adress on return.
  **
  **	Parameters:
  **		bf -- buffer
  **		nbytes -- number of bytes desired
  **
  **	Returns:
  **		pointer to allocated area
  **		on  buffer overflow returns 0.
  **
  **	Side Effects:
  **		adjusts buffer structure to reflect allocation.
  **
  */
  
  char *
  need(bf, nbytes)
  struct nodbuffer 	*bf;
  int			nbytes;
  {
  	register char			*x;
  	register struct nodbuffer	*buf;
  	register int			i;
  
  	buf = bf;
  	i = nbytes;
  	if (i > buf->nleft)
  	{
  			(*buf->err_func)(buf->err_num);
  			return (0);
  	}
  	i += i & 01;
  	x = buf->xfree;
  	buf->xfree += i;
  	buf->nleft -= i;
  	return(x);
  }
  
  /*
  **  INITBUF -- initialize a buffer
  **
  **	Must be called before the first need() call on the buffer.
  **
  **	Parameters:
  **		bf -- buffer
  **		size -- size fo buffer area
  **		err_num -- error code for overflow
  **		err_func -- function to call with err_code on error
  **
  **	Returns:
  **		none
  **
  **	Side Effects:
  **		initializes buffer structure
  **
  **	Diagnostics:
  **		"initbuf : odd buffer adress 0%o" -- buffers must start
  **			at an even adress.
  */
  
  initbuf(bf, size, err_num, err_func)
  struct nodbuffer	*bf;
  int			size;
  int			err_num;
  int			(*err_func)();
  {
  	register struct nodbuffer	*buf;
  
  	buf = bf;
  	if ((unsigned int) buf & 01)
  		syserr("initbuf : odd buffer adress 0%o", buf);
  	buf->nleft = size - sizeof *buf;
  	buf->xfree = buf->buffer;
  	buf->err_num = err_num;
  	buf->err_func = err_func;
  }
  