# /* * 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 [options] [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 following options may be given: .lm +24 .s.i-24;-e Pass escape sequences and control characters through to the terminal. This is useful if you are viewing a file with embedded graphics codes, but it can cause trouble if your terminal doesn't understand the data in the file. "-e" disables the "columns_per_line" and long line wrap-around features. .s.i-24;+columns_per_line Define the number of print positions on each line of the display. This is useful if you have a VT100 set to 132 columns. The '+' sign must be present. "+0" disables line wrap-around. This parameter is ignored if you have specified "-e". .s.i-24;-lines_per_screen Define the number of lines to be displayed on each screen. This is useful if you are scanning a file from a dial-up (low data rate) terminal. .s.lm -24 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;'B' or 'b' To skip to the last screen. .s.i-24;'E', 'e', or CTRL/Z To exit the program. .s.i-24;'F' or 'f' To return to the first screen. .s.i-24;'P' or 'p' To get the next page. .s.i-24;'Q' or 'q' To exit (quit) the program. .s.i-24;'S' or 's' To search for a regular expression. .s.i-24;'X' or '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. .s All unlisted 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 "" (unless the -e option was specified). 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 #ifndef decus #include #endif #ifdef vms #include #include #define FALSE 0 #define TRUE 1 #endif #include "t.h" #ifdef decus int $$narg = 1; /* Don't argv prompt */ #endif #ifdef vms RFAVALUE magic_cookie = { 0,0,0 }; /* Rewind on rmsio */ #else RFAVALUE magic_cookie = 0L; /* fseek() value to rewind file */ #endif RFAVALUE 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 = 1024; /* 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 seeall = FALSE; /* If -e specified */ 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 */ FILETYPE *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 eofseen = FALSE; /* TRUE on input eof */ 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 */ #ifdef DEBUG int debug = FALSE; #endif #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, Q or CTRL/Z to terminate processing.\r\n\ ? or H to view this help message.\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 three options:\r\n\ -e displays escape sequences, (supressing line wraparound).\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; { #ifndef decus extern ctrlc_trap(); signal(SIGINT, ctrlc_trap); #endif 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 '-': switch (tolower(argv[1][1])) { #ifdef DEBUG case 'd': traceon(); debug++; break; #endif case 'e': seeall++; break; default: if (isdigit(argv[1][1])) { if ((linesperscreen = atoi(&argv[1][1])) < 3) linesperscreen = 3; } else { scerpg(2,1); scout(0, 0, "Illegal option (ignored). "); scout(0, 0, "Run T without arguments for help."); scout(0, 0, NULL); sleep(2); } break; } 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 (seeall) columnsperline = 0; 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 */ } #ifndef decus ctrlc_trap() /* * Entered by signal on CTRL/C */ { #ifdef vms exit(SS$_NORMAL); #else exit(0); #endif } #endif