/* * T 5 * * Read and reposition the file being printed. Much magic for RSX modes. */ #include #ifdef vms #include #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 (eofseen) { return (TRUE); /* Don't change record */ } #ifdef vms if (rms_get(buff, max_size, infd) == NULL) { rec_bor = rec_eor = buff; eofseen = TRUE; return (TRUE); } rms_tell(infd, &rec_rfa); recsiz = rms_lrecl(infd); #ifdef DEBUG if (debug) { _tracef("getrecord: rfa %d %d %d, record size %d", rec_rfa.word[0], rec_rfa.word[1], rec_rfa.word[2], recsiz); } #endif #else rec_rfa = ftell(infd); #ifdef rsx /* * RSX emulated modes */ recsiz = fget(buff, max_size, infd); if (feof(infd)) { rec_bor = rec_eor = buff; eofseen = TRUE; return (TRUE); } #else /* * RT11 modes and Unix */ if (fgets(buff, max_size, infd) == NULL) { rec_bor = rec_eor = buff; eofseen = TRUE; return (TRUE); } recsiz = strlen(buff); #endif #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 */ #ifdef DEBUG #ifdef vms if (debug) { _tracef("saveplace mem[%d], rfa %d %d %d, buff %d line %d", memptr - memory, rec_rfa.word[0], rec_rfa.word[1], rec_rfa.word[2], memptr->buff_offset, memptr->line_offset); } #endif #endif } 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. */ { #ifdef DEBUG if (debug) { _tracef("backup from mem[%d]", memptr - memory); } #endif do { memptr--; /* To previous page */ if (memptr < memory) { memptr = LASTMEM; if (rewound(&memptr->record_rfa)) { memptr = memory; break; } } } while (page_flag && (memptr->buff_offset >= 0)); #ifdef DEBUG #ifdef vms if (debug) { _tracef("backup to mem[%d], rfa %d %d %d, buff %d line %d", memptr - memory, rec_rfa.word[0], rec_rfa.word[1], rec_rfa.word[2], memptr->buff_offset, memptr->line_offset); } #endif #endif } 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. */ { RFAVALUE this_rfa; register short loffset; this_rfa = memptr->record_rfa; breakout = FALSE; iseof = 0; eofseen = FALSE; #ifdef vms if (rms_seek(infd, &this_rfa) != 0 || getrecord()) { /* * Could not seek. Maybe rewind */ if (rewound(&this_rfa) || flag) { rec_eor = rec_bor = buff; rec_savec = EOS; } else { scerpg(0, 0); scout(0, 0, NULL); fprintf(stderr, "can't seek to %X %X %X\n", this_rfa.word[0], this_rfa.word[1], this_rfa.word[2]); rms_message(infd, ""); error("Program bug; can't continue"); } } #else 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 { scout(0, 0, NULL); scerpg(0, 0, NULL); fprintf(stderr, "\nCan't seek to %ld\n", rec_rfa); perror(""); error("Program bug; can't continue"); } } #endif else { /* * Step on next record start */ rec_bor = &buff[memptr->buff_offset & ~MASK]; if ((memptr->line_offset & MASK) != 0) { loffset = memptr->line_offset & ~MASK; bigline(1); /* * Note, there is a very strange program bug * that has been seen while wandering around * files containing teco macros. This error * printout should be removed when the bug * is found and fixed. */ if (loffset < 0 || loffset >= sizeof textline) { fprintf(stderr, "\nmemptr (%d) bug, line offset = %d,", memptr - memory, loffset); fprintf(stderr, " range is 0..%d \n", sizeof textline); sleep(4); } rec_txt = &textline[loffset]; 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 static int rewound(rp) RFAVALUE *rp; /* * TRUE if at the magic cookie */ { #ifdef vms return (rp->word[0] == 0 && rp->word[1] == 0 && rp->word[2] == 0); #else return (*rp == magic_cookie); #endif }