/*
 *				T 5
 *
 * Read and reposition the file being printed.  Much magic for RSX modes.
 */

#include <stdio.h>
#ifdef	vms
#include	<ctype.h>
#define FALSE	0
#define	TRUE	1
#endif
#include	"t.h"


int
getbyte()
/*
 * Read a byte from the physical record, return EOS at end of file.
 */
{
	register int	c;

	do {
		if (rec_bor >= rec_eor) {
			if (getrecord())
				return (EOS);
		}
	} while ((c = *rec_bor++ & 0177) == EOS);
	return (c);
}

int
getrecord()		
/*
 * Need a new record.  Return TRUE at end of file.
 */
{
	register char		*rp;		/* Start of record ptr.	*/
	register char		*ep;		/* End of record ptr.	*/
	register int		count;		/* For vms printfile	*/
	int			recsiz;		/* Input rec. size	*/

	if (feof(infd)) {
		return (TRUE);			/* Don't change record	*/
	}
	rec_rfa = ftell(infd);
#ifdef	rsx
	/*
	 * RSX emulated modes
	 */
	recsiz = fget(buff, max_size, infd);
	if (feof(infd)) {
		rec_bor = rec_eor = buff;
		return (TRUE);
	}
#else
	/*
	 * RT11 modes and VMS native compiler
	 */
	if (fgets(buff, max_size, infd) == NULL) {
		rec_bor = rec_eor = buff;
		return (TRUE);
	}
	recsiz = strlen(buff);
#endif
	/*
	 * rp ->  start of the record as read by fget[s]().
	 * ep -> just past the last byte of the record.
	 */
	rp = buff;
	ep = rp + recsiz;
#ifdef	rsx
	if (vms_printfile) {
		if (((count = *fdb_seqn & 0377) & 0200) != 0) {
			*--rp = count & 017;
			if ((count & 0100) != 0)
				*rp |= 0200;
		}
		else while (--count >= 0) {
			*--rp = '\n';
		}
		if (((count = (*fdb_seqn >> 8) & 0377) & 0200) != 0) {
			*ep++ = count & 017;
			if ((count & 0100) != 0)
				ep[-1] |= 0200;
		}
		else while (--count >= 0) {
			*ep++ = '\n';
		}
	}
	else if (implied_cr) {
		*--rp = '\n';
		*ep++ = '\r';
	}
	else if (fortran_cr) {
		/*
		 * The first byte (may be) funny.  Note:
		 * This code is untested.
		 */
		switch (*rp) {
		case '1':			/* Fortran top of page	*/
			*rp = '\f';

		case '\f':			/* Top of page as seen	*/
			/*
			 * Make sure the previous record
			 * has been nicely terminated.  If
			 * this record is longer than one byte,
			 * terminate it, too.
			 */
			*--rp = '\n';
			if (recsiz > 1)
				*ep++ = '\r';
			break;

		case ' ':			/* Normal newline	*/
			*rp = '\n';		/* Linefeed before, and	*/
			*ep++ = '\r';		/* Carriage-return ends	*/
			break;

		case '$':
			*rp = '\n';		/* Newline before,	*/
						/* Nothing follows	*/
			break;

		case '+':
			rp++;			/* Nothing before,	*/
			*ep++ = '\r';		/* Return after		*/
			break;

		case '0':			/* Blank line before	*/
			*rp = '\n';
			*--rp = '\n';		/* Wow, What a hack!	*/
			*ep++ = '\r';		/* Carriage-return ends	*/
			break;

		default:
			*--rp = '\n';		/* Assume it's vanilla	*/
			*ep++ = '\r';		/* 'cause we don't know	*/
		}
	}					
#endif
	rec_bor = rp;				/* Start of record	*/
	rec_eor = ep;				/* End of record	*/
	return (FALSE);
}

	
saveplace()
/*
 * Save the location of the start of the current page.
 */
{
	if (++memptr > LASTMEM)			/* Wrap around		*/
		memptr = memory;		/* Memory if necessary	*/
	memptr->record_rfa = rec_rfa;		/* *memptr identifies	*/
	memptr->buff_offset = rec_bor - buff;	/* top of this page	*/
	memptr->line_offset = rec_txt - textline;
	/*
	 * Remember whether the line wrapped around.
	 */
	if (ff_flag)
		memptr->buff_offset |= MASK;
	if (rec_savec != EOS)
		memptr->line_offset |= MASK;	/* Set top bit if saved	*/
}

backup(page_flag)
int		page_flag;
/*
 * Backup the memory pointer (wrapping it around
 * to the end of the memory as needed).  Note:
 *	memptr[-1]	top of previous page
 *	memptr[0]	top of current  page
 * If page_flag, the backup continues until a form-feed.
 */
{
	do {
		memptr--;		/* To previous page	*/
		if (memptr < memory) {
			memptr = LASTMEM;
			if (memptr->record_rfa == magic_cookie) {
				memptr = memory;
				break;
			}
		}
	} while (page_flag && (memptr->buff_offset >= 0));
}

locate(flag)
int		flag;		/* True if error is non-fatal		*/
/*
 * Locate the proper physical record.
 * Note that breakout is cleared so we can still
 * backup after seeing the last record.
 *
 * The flag is needed on rsx/vms when reading an empty file.
 */
{
	long int	this_rfa;

	this_rfa = memptr->record_rfa;
	breakout = FALSE;
	iseof = 0;
	if (fseek(infd, this_rfa, 0) != 0 || getrecord()) {
		/*
		 * Could not seek.  Allow rewind in some cases
		 */
		if (this_rfa == 0 || flag) {
			rec_eor = rec_bor = buff;
			rec_savec = EOS;
		}
		else {
#ifdef	vms
			fprintf(stderr, "Can't seek to [%08x], memory[%d]\n",
					rec_rfa, memptr - memory);
			error("Can't continue");
#else
			error("Can't seek to [%06o %06o], code %d. %06o\n",
				rec_rfa, $$ferr, $$ferr);
#endif
		}
	}
	else {
		/*
		 * Step on next record start
		 */
		rec_bor = &buff[memptr->buff_offset & ~MASK];
		if (memptr->line_offset & MASK) {
			bigline(1);
			rec_txt = &textline[memptr->line_offset & ~MASK];
			rec_savec = *rec_txt;
		}
		else {
			rec_savec = EOS;
		}
	}
}

#ifdef	rt11
ctrlc()
/*
 * Control C trap routine -- for RSTS/RT11 only
 */
{
	scerpg(0, 0);
	scout(0, 0, NULL);			/* Flush last buffer	*/
	scput(oldbuf);
	exit();
}
#endif
