# /* * T 1 . C * * File typeout utility */ /*)BUILD $(PROGRAM) = T $(INCLUDE) = t.h $(FILES) = { t1.c t2.c t3.c t4.c t5.c t6.c t7.c } $(TKBOPTIONS) = { TASK = ...TXX } */ #ifdef DOCUMENTATION title t Type File on Video Screen index Type File on Video Screen synopsis t [+cols_per_line] [-lines_per_screen] [file_list] description T writes a file, one screen at a time, on the user's terminal. The argument list may contain wildcard file specifiers. The optional lines_per_screen may be given to shorten the screen from its default of 24 lines. The optional cols_per_line parameter may be given to change the screen from its default width of 80 columns. Setting cols__per__line to zero supresses line wrap-around. .s After each screen has been printed, T waits for the user to type a single-letter command: .lm +24 .s.i-24;_ or .i -24;_ To get the next screen. .s.i-24;_ or .i -24;_ or .i -24;'_^' To back up one screen. .s.i-24;'P' To get the next page. .s.i-24;'F' To return to the first screen. .s.i-24;'B' To skip to the last screen. .s.i-24;'S' To search for a regular expression. .s.i-24;'E' or CTRL/Z To exit the program. .s.i-24;'X' To exit the current file. .s.lm -24 If the "next screen," "next page," or "backup" commands are preceeded by a number, T will skip the requested number of screens or pages. Negative skips are allowed: "-P" moves back one page. Note that , 0, and 1 are equivalent. All other characters will be ignored. .s The 'P' command skips to the next page (as delimited by form-feeds). .s The 'B' command is equivalent to 32767. As T must scan the file byte-by-byte, the 'B' command may seem slow. .s Search arguments are regular expressions (as defined in the grep program). If you enter '?' when prompted for a search argument, a help screen will be printed. Backward searching is not possible. .s Note that T works only on video terminals. If no file_list is specified, T prompts for each file. If a file_list argument lacks an explicit extension, ".*" will be used; thus "T#X" is equivalent to .s "T X.*". .s The program will only backup to the built-in maximum of 100 screens. .s T will erase underline and boldface information from the text if it occurs in the following format (where 'X' is any character and '\b' is backspace): .s.nf X\b_ for underline and .br X\bX... for boldface .s.f If an embedded carriage return (for line-overprint) is encountered, all text following the return will be ignored. .s T converts characters in the text file to "". This was done to defend against escape sequences triggering user terminal identification sequences (which could, for example, cause the program to backup one screen). diagnostics .lm +8 .s.i -8;Sorry, t works only on video terminals. .s.i -8;Can't open file "name". .lm -8 author Martin Minow bugs Neither input nor output may be redirected. T cannot be used as a filter. .s If a skip or backup command fails (for example, if the input file is not on a disk), the program will exit with an error message. .s When running T from a remote (DECnet) terminal, you should use to request the next page and or to request the previous page. #endif #include #ifdef vms #include #define FALSE 0 #define TRUE 1 #endif #include "t.h" #ifdef decus int $$narg = 1; /* Don't argv prompt */ #endif long magic_cookie; /* fseek() value to rewind file */ long rec_rfa; /* Current record being read */ char *rec_bor; /* Record start in buff[] */ char *rec_eor; /* Record end in buff[] */ char *rec_txt; /* Line start in textline[] */ char rec_savec; /* Saved byte for line wrap */ #ifdef rsx int max_size; /* Maximum file record size */ extern char *F_SEQN; /* FDB offset to F.SEQN */ int *fdb_seqn; /* infdb @ F.SEQN */ int implied_cr = FALSE; /* TRUE if vanilla file */ int fortran_cr = FALSE; /* TRUE if we hack Fortran VFC */ int vms_printfile = FALSE; /* TRUE if VMS VFC file */ extern int $$vms; /* VMS compatibility signal */ /* * buff -> the current record read by getrecord(). Note that it is * allocated with guard areas before and after for printfile formats. */ char *allobuff; /* from calloc() */ char *buff; /* -> logical record for fget() */ #endif #ifdef rt11 int max_size = 512; /* Maximum record size */ struct rt11record rt11record = { EOS, "" }; #endif #ifdef vms /* * VMS native */ int max_size = 512; /* Maximum record size */ struct vmsrecord vmsrecord = { EOS, "" }; #endif /* * Things for screen handling */ char **oldbuf; /* For screen package */ #ifdef vms char buffer[1000]; /* For screen package */ #else char buffer[800]; /* For screen package */ #endif int linesperscreen = ROWS; /* Maximum lines per screen */ int columnsperline = COLS; /* Maximum columns per line */ int vt100; /* True if vt100 */ int cursrow = 1; /* Home for cursor */ int curscol = 1; /* Home for cursor */ /* * Finis is set when the user types CTRL/C or CTRL/Z in response to * a "next screen" prompt. It forces an exit from the program. * * Breakout is set on end of file or when the user types 'X' in * response to a "next screen" prompt. It exits the current file, * going on to the next (wildcard) file. Note that the and * commands clear breakout. */ char inline[81]; /* Argument line */ FILE *infd; /* Input file descriptor */ char textline[513]; /* Current output text line */ char file_name[81]; /* Input file name */ char pfilename[81]; /* Process file name */ char temptext[81]; /* Text work space */ int iseof = 0; /* switch */ int ff_flag = FALSE; /* Magic form-feed signal */ int finis = FALSE; /* TRUE on CTRL/C or CTRL/Z */ int breakout = FALSE; /* TRUE on eXit */ RFA memory[MAXMEM]; /* Top of page memory */ RFA *memptr = memory; /* Pointer within memory[] */ #define LASTMEM (&memory[MAXMEM - 1]) extern long ftell(); /* Returns file position */ #define HELPROW 3 char *help1 = "T prints files on your terminal, one screenful at a time.\r\n\ When each screen is printed, you may type:\r\n\ or to see the next screen.\r\n\ , , or '^' to see the previous screen.\r\n\ P to go to the next page (form-feed).\r\n\ The above commands may be preceeded by a signed number to skip multiple\r\n\ screens or pages. They stop at the start or end of the file.\r\n\ F to go to the front of the file.\r\n\ B to go to the back end of the file.\r\n\ S to search for a pattern ('?' for help).\r\n\ N or X to exit this file and start the next.\r\n\ E (or CTRL/Z) to terminate processing.\r\n\ ? or H to view this help message.\r\n\ \r\n"; char *help2 = "File names may contain \"wild-card\" arguments. If no \".ext\" is supplied,\r\n\ \".*\" will be used. If run as a command, T accepts two optional arguments:\r\n\ + sets the number of columns per line (+0 supresses line wraparound).\r\n\ - sets the number of lines per screen.\r\n\r\n"; char *help3 = "(Only compatibility-mode wild-cards are allowed.)\r\n"; char *help4 = "Define T as \"T :== $DISK:[ACCOUNT]T\"\r\n\ Execute as \"$ T (options) file1 file2 ...\""; main(argc, argv) register int argc; register char **argv; { if (((vt100 = sctype()) & 64) == 0) error("Sorry, t works only on video terminals"); vt100 = (vt100 == IS_VT100); /* Make it a flag */ scset(buffer, sizeof buffer, &oldbuf); #ifdef rt11 if ($$rsts) setcc(ctrlc); /* Enable CTRL/Z trapping */ #endif while (argc > 1) { switch (argv[1][0]) { case '-': if ((linesperscreen = atoi(&argv[1][1])) < 3) linesperscreen = 3; break; case '+': /* * The "10" in the following line must be * larger than the length of the "blob string" * used by getline. */ if ((columnsperline = atoi(&argv[1][1])) < 10) columnsperline = 0; break; default: goto exit_while; } argc--; argv++; } exit_while: if (argc <= 1) { /* * T was called without file arguments, or just run. * Print a help message, then prompt and command lines. */ helpmessage(); getall(1); } else { while (argc > 1 && !finis) { if (process(argv[1], 1) == 0 && argc == 2) { /* * If "can't" on only or last file, * go forever. Start on line 3 since * process() uses 1+2 for error messages. */ getall(3); } argc--; /* Count the argument */ argv++; /* and step arg. ptr. */ } } scout(0, 0, NULL); /* Flush last buffer */ scput(oldbuf); /* Cleanup screen i/o */ } getall(row) int row; /* * Prompt and read files forever. Row is for the first prompt */ { while (!finis) { scerln(row, 1); if (scget(inline, sizeof inline, "File to print? ") == NULL) { scerpg(1, 1); break; } else if (inline[0] == '?' && inline[1] == EOS) { helpmessage(); } else { process(inline, row + 1); row = 1; } } } helpmessage() /* * Print a help message */ { scerpg(1, 1); scout(HELPROW, 1, help1); scout(0, 0, help2); #ifdef rsx if ($$vms) { scout(0, 0, help3); scout(0, 0, help4); } #endif #ifdef vms scout(0, 0, help4); #endif scout(0, 0, NULL); /* Needed for inquire() call */ }