:i	static char d_buf_sccs_id[] = "%W% %G%";
#include "V.h"
#include "mem.h"
/*
* Here's a buffer for accumulating a debug message gradually.  The  V_state()
* routine calls this to generate its "Got:" messages, which originally went to
* stderr, and which now goes here and then to Vout when the buffer fills  or
* we get a line terminator.
*/
static char   V_outbuf[BUFSIZ] = {0};
static char * V_buffer = V_outbuf;
static char * V_bufend = 0;
static char * V_bufptr = 0;
global int    V_bufsiz = 0;
global Flag   V_inline = 0;	/* True if chars in V_buffer */

V_initbuf()
{	int  r=0;
	if (!V_bufsiz) V_bufsiz = 1000;
	if (!V_buffer)
		if (!(V_buffer = V_bufptr = (CP)MallocM(V_bufsiz+5,"V_buffer")))
			Fail;
	V_bufend = V_buffer + V_bufsiz;
	r = V_bufsiz;
fail:
	return r;
}
/*
* Accept one char of V_debug output and add it to the buffer.  Note that  we
* actually  add  a  printable  char  string  to show the char.  The standard C
* excapes are recognized and produces; other control chars are handled by  the
* ^A  format.   For chars with the high-order bit set, we generate '~', though
* this is perhaps not really useful.
*/
V_chr(c)
	int c;
{	int r=0;
	if (!V_buffer) if (!V_initbuf()) Fail;;
	if (c > 0x7F) {		/* Is the high-order bit on? */
		*V_bufptr++ = '~';
		c &= 0x7F;
	}
	Switch(c) {		/* Is it a special char? */
	case '\\': *V_bufptr++ = '\\'; *V_bufptr++ ='\\'; Done;
	case '\b': *V_bufptr++ = '\\'; *V_bufptr++ = 'b'; Done;
	case '\f': *V_bufptr++ = '\\'; *V_bufptr++ = 'f'; Done;
	case '\n': *V_bufptr++ = '\\'; *V_bufptr++ = 'n'; Done;
	case '\r': *V_bufptr++ = '\\'; *V_bufptr++ = 'r'; Done;
	case '\t': *V_bufptr++ = '\\'; *V_bufptr++ = 't'; Done;
	case 0x7F: *V_bufptr++ = '\\'; *V_bufptr++ = 'D'; Done;
	}
	if (c < ' ') {		/* Is it an ASCII control char? */
		*V_bufptr++ = '^';
		*V_bufptr++ = 'A' + c - 1;
		Done;
	}
	*V_bufptr++ = c;
done:
	*V_bufptr = 0;
	V_inline = 1;
:8	V8 "Msg: \"%s\"",V_buffer D;
	if (c == '\n' || V_bufptr >= V_bufend)
		V_flush();
fail:
	return r;
}
/*
* Write the buffer to Vout.
*/
V_flush()
{
	if (V_buffer) {
		*V_bufptr = 0;		/* Paranoia */
		fputs(V_buffer,Vout);
		fputc('\n',Vout);
		fflush(Vout);		/* Write it */
		*(V_bufptr = V_buffer) = 0;	/* Prepare for next message */
	}
	V_inline = 0;
}
/*
* Several chars of V_debug output.
*/
V_str(p,n)
	char*p;
	int  n;
{	int  r=0;
	if (!V_buffer) if (!V_initbuf()) Fail;;
	if (n < 0) n = Strlen(p);
	while (n-- > 0) V_chr(*p++);
fail:
	return r;
}
