Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!bloom-beacon!gatech!purdue!i.cc.purdue.edu!j.cc.purdue.edu!pur-ee!iuvax!bsu-cs!lcuxa!mike2 From: lcuxa!mike2@mrnet.mr.net (M S Slomin) Newsgroups: comp.binaries.ibm.pc Subject: Less for DOS (source part3a) Summary: Repost after splitting into two parts Keywords: less, TurboC 1.5 Message-ID: <3036@bsu-cs.UUCP> Date: 13 May 88 20:44:11 GMT Sender: ibmbin@bsu-cs.UUCP Followup-To: comp.binaries.ibm.pc.d Lines: 843 Approved: dhesi@bsu-cs.UUCP [I don't think all sites received this before moderation, so here it is. This is a repost as described below for less; the other parts were posted before moderation and won't be repeated here. -- R.D.] I don't know why, but my 49K posting of part 3 of the less sources was apparently truncated at the majority of sites. (I did limit it to < 50K, which I thought was the limit for most mailers, but who knows?) Rather than continuing to mail it to those who request it, I've split the original posting in two, and am reposting it as part3a and part3b. Hope this solves the problem. -- No warranties whatsoever. Mike Slomin bellcore!lcuxa!mike2 ---------------------CUT HERE (less source, part 3a)------------------- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file # 3. Execute the file with /bin/sh (not csh) to create the files: # # readme # scrn.c # scrn.h # signal.c # # Created on May 1, 1988 # if test -f 'readme' then echo shar: will not over-write existing file "'readme'" else echo extracting "'readme'" sed 's/^X//' >readme <<'SHAR_EOF' XPort of less to msdos: X XLess is a program similar to the Unix more command but is much more Xuseful. Read less.man for a good description of less and what it can Xdo for you. X XA. Dick Keily's original porting information for MSC 4.0: X XThe files included here will result in a full version of less Xfor use on msdos. This version of less has been tested on all the pc Xsystems that I could get my hands on. This includes monochrome, graphics, X(that includes systems with graphics cards and mono monitors), and color Xgraphics. X XThe following must be done to have less.exe work in its full glory: X X 1. Nothing if you don't want color when using a color monitor. X To get the color use the set command such as: X X set less=C (Case sensitive; c is another option) X X Do this prior to calling less. A command line option X less -C will also get you color. X X NOTE: Only use the color option when using a color monitor. X All other configurations need no special action. X X There are other less settings that can be used using the X set command. Read less.man. The one I use is less=mC on X an AT with enhanced monitor and ega card. X X 2. Less also has a v command that lets you can an editor from X within less to edit the file that you are viewing at the X time. The default is memacs which was taken from the Unix X mod.sources. If you don't have it use the dos set command X as follows to let less know which it is: X X set editor=your_editor X X 4. It is best to include the set commands in your autoexec.bat X which will be executed when you boot up your system. X X 5. Less is a very useful utility. Read less.man and when in X less the h command will put a description of the commands X on the screen for you. X X 6. This version of less is named less13.exe for distribution. X It replaces and other version that you have obtained from X my posting of the executable. Accept no substitutes. When X I get the time I will incorporate the changes to get up X the distributed Unix version 61. If you post this to any X bulletin board name any files associated with it with the X version 13.(referring to the MSDOS control). X X [N.B. No longer correct. This version is X somewhere between version 61 and 73 in its X capabilities.] X X 7. Less version 1.3 uses the system function but looks to see X if you are using the swchar program that allows you to use X the / rather than the \ character. The swchar state is changed X before the system call if you are and then resets it so that X it all becomes transparent to the user. X X [N.B. This is still correct.] X X 8. The source code for less is being posted to Net.sources. X It is all ifdef'd so that it should compile on Unix systems X also as is. X X [N.B. Probably not anymore. The ctrlbrk() X function will fail on Unix.] X X 9. Version 1.3 corrects the following: X The latest known to me fixes have been incorporated X in the regexpression routines written by Henry X Spencer and posted on the Unix news net. X X Dick Keily X Eastman Kodak Company X work: (716)477-1001 X unix: ...!seismo!rochester!kodak!keily X--------------------------------------------------------------------------- X--------------------------------------------------------------------------- X XB. Revised port to TurboC: X X 1. The port now incorporates boldface and underline (useful X for viewing documents created with nroff -man). I've X chosen the monochrome attributes for these, 0x01 and 0xf0, X and for CGA color, 0x06 (yellow) and 0xf0 (bright white). X If you wish to use others, revise the SCRN.H and/or SCRN.C X file(s) appropriately. X X 2. This will compile in the "tiny" model, and the resulting X file can be converted to a '.com' file for loading and X execution speed. An appropriate 'LESS.PRJ' file is X included; be certain to define DOSPORT in 'Options/Compiler' X (interactive mode). X X 3. A bug was fixed in the 'v' command (escape X to the editor): on return to less, the original unmodified X file in memory was displayed, not the edited one. This X is worked around in command.c by causing an 'E\n' command X to be executed on return. 'E' (Examine) loads in a new X file, and if no filename is given it loads in the previous X file. (Indeed, this is useful if 'E' is used normally. X After examining a different file, you can return to the X previous one by invoking 'E' with no file name.) X X 4. A new command, 'L', is implemented. 'L' gives X all of the information that '^G' and '=' give (i.e., X file name, number of bytes, approximate percentage into X the file) and in addition gives the number of the first X line appearing on the screen. This information is useful X if you wish to edit the file subsequently with a line- X oriented editor (e.g., vi, EDLIN, etc.); you know what X line to jump to. Unfortunately, it is a bit slow because X long ints are used in the calculation -- but a file might X exceed 65,000 lines!. X X 5. Sorry, I've not bothered to maintain downward compatibility X with Mr. Keily's MSC 4.0 port. I tried it both ways, and the X TurboC one is smaller and faster. If you want to do it with X MSC 4.0: (1) replace the ctrlbrk() command with an appropriate X signal() and interrupt handler; (2) compile it in the small X model; and (3) link with a /stack:4096 flag, linking in the X ssetargv.obj (small model) object file supplied by Microsoft X instead of the included setargv.c file. X X 6. If you haven't updated to TurboC 1.5, read the comments in X SETARGV.C. The variables _argc and _argv must be changed X throughout that file to __argc and __argv to work properly X in version 1.0. In any event, the SETARGV function is X needed only for DOS wildcard expansion, which is useful if X you want to specify multiple files for viewing with wildcards X and flip back and forth among them with 'N' and 'P'. If X you don't need the wildcard capability, omit SETARGV. X X 7. The public-domain REGEXP.C file supplied by Dick Keily X implements full regular expression matching a la X 'egrep' (i.e., using the '+' for one or more matches and X the '|' for disjunctive matches) in addition to the more X limited 'ed'/'sed' pattern match metacharacters. This is X useful, and better than classical Unix REGEXP. X X Mike Slomin X !bellcore!lcuxa!mike2 X X X SHAR_EOF if test 6263 -ne "`wc -c < 'readme'`" then echo shar: error transmitting "'readme'" '(should have been 6263 characters)' fi fi if test -f 'scrn.c' then echo shar: will not over-write existing file "'scrn.c'" else echo extracting "'scrn.c'" sed 's/^X//' >scrn.c <<'SHAR_EOF' X/* Scrn.c replaces screen.c that was in the net distribution. Module contains X * PC screen routines plus whatever was in screen.c that had to be kept for X * linking with the other modules at link time. X */ X X#include X#include X#include X#include "scrn.h" X X#define CNTL_H 0x08 X#define CNTL_U 0x15 X#define NL 0x0a X#define CR 0x0d X#define TAB 0x09 X#define BELL 0x07 X#define ROWS 25 X#define COLUMS 80 X X#define NOT_QUIET 0 /* Ring bell at eof and for errors */ X#define LITTLE_QUIET 1 /* Ring bell only for errors */ X#define VERY_QUIET 2 /* Never ring bell */ X Xextern int quiet; /* If VERY_QUIET, use visual bell for bell */ Xextern int scrn_in_color; /* When using color monitor */ Xint erase_char, kill_char; /* The user's erase and line-kill chars */ Xint sc_height, sc_width, se_width, ue_width, ul_width, bo_width, be_width, so_width; Xint auto_wrap, ignaw; Xvoid init(), dinit(), get_term(), home(), bell(), vbell(), add_line(); Xvoid lower_left(), clear(), clear_eol(), so_enter(), so_exit(), ul_enter(); Xvoid ul_exit(), bo_enter(), bo_exit(), backspace(), putbs(), raw_mode(); Xint ulflag = 0, boflag = 0; X Xcls() /* move cursor home and clear the screen */ X{ X union REGS REG; X int mode; X X gotoxy(0, 0); X REG.x.ax = 0x0600; X if (scrn_in_color == 1) X REG.h.bh = WHITE_ON_BLUE; X else X REG.h.bh = BW; X REG.x.cx = 0x0000; X REG.x.dx = 0x184f; X int86(0x10, ®, ®); X} X Xera_eol() X{ X union REGS REG; X int hold[4]; X int column; X X getxy(hold); X column = hold[1]; X if (scrn_in_color == 1) X REG.x.bx = WHITE_ON_BLUE; X else X REG.x.bx = BW; X REG.x.ax = 0x0900; /* ah = 10; al = null char to write */ X REG.x.cx = 80 - column; /* cx = no. of nulls to write */ X int86(0x10, ®, ®); X restorxy(hold); /* retore cursor to original position */ X return; X} X Xgotoxy(row, col) /* Position cursor at x,y on screen */ Xint row, col; X{ X union REGS REG; X X REG.h.ah = 02; X REG.h.bh = 00; X REG.h.dh = row; X REG.h.dl = col; X int86(0x10, ®, ®); X} X Xgetxy(hold) /* Get cursor coordinates */ Xint *hold; X{ X union REGS REG; X X REG.h.ah = 03; X REG.h.bh = 00; X int86(0x10, ®, ®); X hold[0] = REG.h.dh; X hold[1] = REG.h.dl; X hold[2] = REG.h.ch; X hold[3] = REG.h.cl; X} X X Xrestorxy(hold) /* Restore cursor gotten above */ Xint *hold; X{ X union REGS REG; X X gotoxy(hold[0], hold[1]); X REG.h.ah = 01; X REG.h.bh = 00; X REG.h.ch = hold[2]; X REG.h.cl = hold[3]; X int86(0x10, ®, ®); X} X Xcurs_r(n) /* move cursor right n places */ Xint n; X{ X int hold[4]; X int row, column; X X getxy(hold); X row = hold[0]; X column = hold[1]; X if (column < 0) X if (n < 0) X return(0); X if (column > 79) X if (n > 0) X return(0); X column = column + n; X gotoxy(row, column); X} X Xcurs_l(n) /* move cursor left n places */ Xint n; X{ X curs_r(-n); X} X Xscroll_up(n) Xint n; X{ X union REGS REG; X X REG.h.ah = 0x06; X if (scrn_in_color == 1) X REG.h.bh = WHITE_ON_BLUE; X else X REG.h.bh = BW; X REG.h.al = n; X REG.x.cx = 0x0000; X REG.x.dx = 256 * 24 + 79; X int86(0x10, ®, ®); X return(1); X} X Xget_mode() /* Check for Monochrome mode 7 */ X{ X union REGS REG; X X REG.h.ah = 15; X int86(0x10, ®, ®); X return(REG.h.al); X} X X X/* X * Set cursor checking for current cursor size parameters. X */ X Xset_cur() X{ X union REGS INREG, OUTREG; X X if (get_mode() == 7) X { X INREG.h.ah = 1; X INREG.h.bh = 0x00; X INREG.h.ch = 12; X INREG.h.cl = 13; X int86(0x10, &INREG, &OUTREG); X } X else X { X INREG.h.ah = 0x03; X INREG.h.bh = 0x00; X int86(0x10, &INREG, &OUTREG); X INREG.h.ah = 0x01; X INREG.h.bh = 0x00; X INREG.h.ch = OUTREG.h.ch; X INREG.h.cl = OUTREG.h.cl; X int86(0x10, &INREG, &OUTREG); X } X} X Xchr_put(c, attribute) Xint c; Xint attribute; X{ X union REGS REG; X int hold[4]; X int i, row, column; X X if (c == CR) X { X getxy(hold); X row = hold[0]; X column = 0; X gotoxy(row, column); X return(1); X } X if (c == TAB) X { X for (i = 0;i <= 7;++i) X chr_put(' ', attribute); X return(1); X } X if (c == BELL) X { X putch(7); X return(1); X } X if (c == NL) X { X getxy(hold); X row = hold[0]; X if (row >= 24) X scroll_up(1); X else X ++row; X column = 0; X gotoxy(row, column); X return(1); X } X REG.h.ah = 0x9; X REG.h.al = c; X if (ulflag || boflag) X REG.h.bl = (ulflag | boflag); X else X REG.h.bl = attribute; X REG.h.bh = 00; X REG.x.cx = 1; X int86(0x10, ®, ®); X curs_r(1); X return(REG.x.ax); X} X Xstr_put(str, attribute) Xchar *str; Xint attribute; X{ X int i; X X if (scrn_in_color == 1) X attribute = WHITE_ON_RED; X else X attribute = REV_VID; X for (i = 0;i < strlen(str);++i) X chr_put(*(str + i), attribute); X} X X X/* X * Add a blank line (called with cursor at home). X * Should scroll the display down. X */ X Xvoid Xadd_line() X{ X union REGS REG; X int hold[4]; X int row, column; X X REG.h.ah = 0x07; X if (scrn_in_color == 1) X REG.h.bh = WHITE_ON_BLUE; X else X REG.h.bh = BW; X REG.h.al = 1; X getxy(hold); X row = hold[0]; X column = hold[1]; X REG.h.ch = row; X REG.h.cl = 0; X REG.h.dh = 24; X REG.h.dl = 79; X int86(0x10, ®, ®); X} X X/* X * Below are the functions which perform all the "less terminal-specific" X * screen manipulation functions. They are taken from screen.c that was X * in the distribution of less on the news. X */ X X/* X * Initialize terminal X */ Xvoid Xinit() X{ X set_cur(); X} X X/* X * Deinitialize terminal X */ Xvoid Xdeinit() X{ X} X Xvoid Xget_term() X{ X sc_height = ROWS; X sc_width = COLUMS; X se_width = 0; X ue_width = 0; X ul_width = 0; X be_width = 0; X bo_width = 0; X so_width = 0; X auto_wrap = 0; /* chr_put doesn't autowrap */ X ignaw = 0; X /* sneak in kill and erase characters for command line editing */ X kill_char = CNTL_U; /* use ctrl-u as kill chararcter */ X erase_char = CNTL_H; /* use ctrl-h as erase character */ X} X Xvoid Xraw_mode(on) Xint on; X{ X /* left here in case there is a desire */ X /* to put terminal in raw_mode vs cooked */ X} X X/* X * Home cursor (move to upper left corner of screen). X */ X Xvoid Xhome() X{ X gotoxy(0, 0); X} X X/* X * Move cursor to lower left corner of screen. X */ Xvoid Xlower_left() X{ X gotoxy(24, 0); X} X X/* X * Ring the terminal bell. X */ Xvoid Xbell() X{ X if (quiet == VERY_QUIET) X vbell(); X else X putch(BELL); X} X X/* X * Output the "visual bell", if there is one. X */ Xvoid Xvbell() X{ X /* there is no visual bell at this time */ X return; X} X X/* X * Clear the screen. X */ Xvoid Xclear() X{ X cls(); X} X X/* X * Clear from the cursor to the end of the cursor's line. X * {{ This must not move the cursor. }} X */ Xvoid Xclear_eol() X{ X era_eol(); X} X X/* X * Begin "standout" (bold, underline, or whatever). X */ Xvoid Xso_enter() X{ X} X X/* X * End "standout". X */ Xvoid Xso_exit() X{ X} X/* X * Begin bold X*/ Xvoid Xbo_enter() X{ X boflag = BOLDFACE; X} X/* X * End bold X */ Xvoid Xbo_exit() X{ X boflag = 0; X} X X/* X * Begin "underline" (hopefully real underlining, X * otherwise whatever the terminal provides). X */ Xvoid Xul_enter() X{ X if (scrn_in_color == 1) X ulflag = COLOR_UL; X else X ulflag = UNDERLINE; X} X X/* X * End "underline". X */ Xvoid Xul_exit() X{ X ulflag = 0; X} X X/* X * Erase the character to the left of the cursor X * and move the cursor left. X */ Xvoid Xbackspace() X{ X /* X * Try to erase the previous character by overstriking with a space. X */ X curs_l(1); X putc(' '); X curs_l(1); X} X X/* X * Output a plain backspace, without erasing the previous char. X */ Xvoid Xputbs() X{ X curs_l(1); X} X SHAR_EOF if test 7306 -ne "`wc -c < 'scrn.c'`" then echo shar: error transmitting "'scrn.c'" '(should have been 7306 characters)' fi fi if test -f 'scrn.h' then echo shar: will not over-write existing file "'scrn.h'" else echo extracting "'scrn.h'" sed 's/^X//' >scrn.h <<'SHAR_EOF' X#define WHITE_ON_RED 0x47 X#define WHITE_ON_BLUE 0x17 X#define BW 0x07 X#define REV_VID 0x70 X#define BOLDFACE 0x0f X#define UNDERLINE 0x01 X#define COLOR_UL 0x06 X SHAR_EOF if test 160 -ne "`wc -c < 'scrn.h'`" then echo shar: error transmitting "'scrn.h'" '(should have been 160 characters)' fi fi if test -f 'signal.c' then echo shar: will not over-write existing file "'signal.c'" else echo extracting "'signal.c'" sed 's/^X//' >signal.c <<'SHAR_EOF' X/* X * Routines dealing with signals. X * X * A signal usually merely causes a bit to be set in the "signals" word. X * At some convenient time, the mainline code checks to see if any X * signals need processing by calling psignal(). X * An exception is made if we are reading from the keyboard when the X * signal is received. Some operating systems will simply call the X * signal handler and NOT return from the read (with EINTR). X * To handle this case, we service the interrupt directly from X * the handler if we are reading from the keyboard. X */ X X#include "less.h" X#ifdef MSDOS Xchar get_swchar(); Xvoid swchar_to_dos(); Xvoid swchar_to_unix(); X#include X#include X#endif X Xextern char *first_cmd; Xint result; Xchar sw_char; Xpublic int sigs; X X/* X * Pass the specified command to a shell to be executed. X * Like plain "system()", but handles resetting terminal modes, etc. X */ Xvoid lsystem(cmd) X char *cmd; X{ X int inp; X X /* X * Print the command which is to be executed. X */ X lower_left(); X clear_eol(); X puts("!"); X puts(cmd); X puts("\n"); X X /* X * De-initialize the terminal and take out of raw mode. X */ X#ifndef MSDOS X deinit(); X flush(); X raw_mode(0); X#endif X /* X * Pass the command to the system to be executed. X */ X#ifndef MSDOS X inp = dup(0); X close(0); X open("/dev/tty", 0); X#endif X#ifdef MSDOS X sw_char = get_swchar(); X swchar_to_dos(); X result = system(cmd); X if (result != 0) X perror("Less"); X if (sw_char == '-') X swchar_to_unix(); X#else X system(cmd); X#endif X#ifndef MSDOS X close(0); X dup(inp); X close(inp); X#endif X /* X * Reset signals, raw mode, etc. X */ X#ifndef MSDOS X init_signals(); X raw_mode(1); X init(); X#endif X} X X#ifdef MSDOS Xchar Xget_swchar() X{ X union REGS inregs; X union REGS outregs; X X inregs.h.ah = 0x37; X inregs.h.al = 0; X intdos(&inregs, &outregs); X return(outregs.h.dl); X} X X Xvoid Xswchar_to_dos() X{ X union REGS inregs; X union REGS outregs; X X inregs.h.ah = 0x37; X inregs.h.al = 0x01; X inregs.h.dl = '/'; X intdos(&inregs, &outregs); X return; X} X Xvoid Xswchar_to_unix() X{ X union REGS inregs; X union REGS outregs; X X inregs.h.ah = 0x37; X inregs.h.al = 0x01; X inregs.h.dl = '-'; X intdos(&inregs, &outregs); X return; X} X X#endif X X SHAR_EOF if test 2167 -ne "`wc -c < 'signal.c'`" then echo shar: error transmitting "'signal.c'" '(should have been 2167 characters)' fi fi # end of shell archive exit 0 -----