/* * T 2 * * Processing for each file (and each page output). * */ #include #ifdef vms #include #endif #include "t.h" #define FALSE 0 #define TRUE 1 #ifdef rsx extern int $$rsts; /* TRUE if on RSTS/E */ #endif int process(fname, row) char *fname; /* File argument (with wildcards) */ int row; /* row for file error message if needed */ /* * Display this file. Return number of files found. */ { register int nfiles; /* Number of wildcard files found */ register int ratt; /* FDB @ F.RATT */ register int temp; /* FDB @ F.RTYP plus junk */ RFA *mp; /* Memory pointer */ extern FILETYPE *FWILD(); extern FILE *FNEXT(); fixfilename(fname); /* * Open the file "unformatted" and deblock records locally. * This is because (on RSX) ftell() returns a record pointer * while T needs a line pointer. Unfortunately, several * record formats on RSX pack multiple lines in one record * and/or multiple records per line. We don't really have * to do this in RT11, but we do it anyways. */ nfiles = 0; if ((infd = FWILD(pfilename, FWILDMODE)) == NULL) { cant("open", pfilename, row, TRUE); return (nfiles); } /* * For each file (matched by the wildcard argument) */ for (nfiles = 0; FNEXT(infd) != NULL && !finis; nfiles++) { #ifdef rsx /* * fdb_seqn -> the sequence number word in the file fdb. * This is needed for vms printfile processing. */ fdb_seqn = (int *) &infd->io_fdb[(int) &F_SEQN]; #endif eofseen = FALSE; FGETNAME(infd, file_name); #ifdef rsx /* * Determine how records are to be deblocked. * The FDB is organized such that * F.RTYP is at offset 0 and * F.RATT is at offset 1. * implied_cr is TRUE if FD.CR is set in the fdb * or we are running under RSTS/E and the file * is native RSTS stream (zero attributes) or * RSX stream (RTYP == 4 and RATT == 0). * fortran_cr is TRUE if FD.FTN is set. * vms_printfile is TRUE if FDB@F.RTYP == R.SEQ and * FDB@F.RATT == FD.VFC. This is the * way RSX (compatibility mode) handles vms * print file format. (Files transferred to * native RSX or RSX/RSTS via DECnet may also * get this attribute. */ temp = infd->io_fdb[(int) &F_RTYP] & 0377; ratt = infd->io_fdb[(int) &F_RATT] & 0377; implied_cr = (((ratt & ((int) &FD_CR)) != 0) || (ratt == ((int) &R_STM)) || ($$rsts != 0 && ratt == 0 && temp == 0)); fortran_cr = ((ratt & ((int) &FD_FTN)) != 0); vms_printfile = ((temp == ((int) &R_SEQ)) /* || (ratt == ((int) &FD_VFC))); */ || (ratt == FD_VFC)); /* * Use information in the IOV to allocate a * record buffer (freeing any current one). * Note that the allocated buffer is two bytes * longer than the longest logical record. * One of these is needed for the trailing EOS * (null) byte, and the other is prepended for * carriage-control formatting. If the file is * in vms_printfile, the record size is increased so * that the maximum number of leading/trailing line * separators may be appended. * * buff -> where the read will start at. */ if (allobuff != NULL) free(allobuff); max_size = temp = infd->io_rbsz; if (vms_printfile) temp += 256; /* Add in guard space */ if ((allobuff = calloc(temp + 2, sizeof (char))) == NULL) error("Can't get %d byte buffer\n", temp); buff = &allobuff[ (vms_printfile) ? 128 : 1 ]; #endif #ifdef DEBUG if (debug) { _tracef("file %s", file_name); } #endif scerpg(1, 1); /* * Put a message on the first page. */ concat(temptext, "File \"", file_name, "\"", NULL); midmsg(); scout(0, 0, textline); row = 3; /* * Initialize the top of page memory buffer, set * current record to "beginning of the file", and * clear eof and breakout flags. */ for (mp = memory; mp <= LASTMEM; mp++) { mp->record_rfa = magic_cookie; mp->buff_offset = 0; mp->line_offset = 0; } memptr = &memory[-1]; rec_rfa = magic_cookie; rec_bor = rec_eor = buff; rec_txt = textline; rec_savec = EOS; iseof = 0; breakout = FALSE; while (!finis && !breakout) { /* * New page -- moving forward in the file, * save the position of the top of the page. */ saveplace(); do { /* * Print the page, and loop while * inquire() has us moving backward * in the file. */ dopage(row); row = 1; } while (inquire()); } } /* * All wildcard matches done */ if (nfiles == 0) { cant("locate", pfilename, row, TRUE); } else { /* * Successful ending */ scerpg(1, 1); } return (nfiles); } fixfilename(fname) char *fname; /* * Copy the argument to global pfilename[], appending ".*" if no * '.' was seen. */ { register char *ep; extern char *cpystr(); for (ep = cpystr(pfilename, fname); ep >= pfilename && *ep != ']' && *ep != '.' && *ep != ';'; ep--) ; if (pfilename[0] != EOS && *ep != ';' && *ep != '.') { concat(pfilename, pfilename, ".*", NULL); } } dopage(startrow) int startrow; /* * Do one page of the file, return TRUE if at end of file. */ { register char *tp; register int row; extern char *getline(); #ifdef DEBUG #ifdef vms if (debug) { _tracef("dopage: page %d, rec_rfa = %d %d %d, bor %d, txt %d", (memptr - memory), rec_rfa.word[0], rec_rfa.word[1], rec_rfa.word[2], rec_bor - buff, rec_txt - textline); if (memptr >= memory) { _tracef(" prev. rfa %d %d %d, buff_offset %d, line_offset %d", memptr[-1].record_rfa.word[0], memptr[-1].record_rfa.word[1], memptr[-1].record_rfa.word[2], memptr[-1].buff_offset, memptr[-1].line_offset); } } #endif #endif for (row = startrow; row <= linesperscreen; row++) { if ((tp = getline(row)) == NULL) { /* * End of file */ if (row == startrow) { /* * EOF at top of page -- finis */ return (TRUE); } else { /* * Wait till prompt and then * it's finis for the file. */ scerpg(row, 1); break; } } /* * Note that getline() has normalized formfeeds * so that they always are by themselves. */ if (row == startrow) { /* * Skip blank lines at the top of a screen. */ switch (*tp) { case '\f': case EOS: row--; continue; } scerpg(row, 1); } else if (*tp == '\f') { /* * Page break */ break; } else { /* * Not at the top of the page, * go to the next line. */ scout(0, 0, "\r\n"); /* Quick move */ } /* * Output the current line */ scout(0, 0, tp); } /* * This page is complete. */ scout(cursrow, curscol, ""); /* Home cursor */ cursrow = curscol = 1; /* Reset to standard home */ scout(0, 0, NULL); /* Flush buffers */ } cant(why, filename, row, flag) char *why; char *filename; int row; /* Error msg on row and row+1 */ int flag; /* True to print perror msg. */ /* * Can't open file message */ { sprintf(textline, "Can't %s \"%s\"", why, filename); scerpg(row, 1); if (flag) { scout(0, 0, NULL); perror(textline); } else { scout(0, 0, textline); } scout(0, 0, NULL); return (TRUE); }