home *** CD-ROM | disk | FTP | other *** search
- From: ihnp4!nsc!nsc-pdc!rgb (Robert Bond)
- Subject: less part 1 of 2
- Newsgroups: mod.sources
- Approved: jpn@panda.UUCP
-
- Mod.sources: Volume 3, Issue 120
- Submitted by: ihnp4!nsc!nsc-pdc!rgb (Robert Bond)
-
-
-
- Here is the last distribution of less made by Mark Nudelman to net.sources
- before he left National Semiconductor. Since it is taking so long for him
- to get back on the net, and because lots of folks did not get part 2
- of the last distribution, we have decided to submit less to mod.sources.
- Mark is still promising to return to the net Real Soon Now.
-
- #!/bin/sh-----cut here-----cut here-----cut here-----cut here-----
- # shar: Shell Archiver
- # Run the following text with /bin/sh to create:
- # INSTALLATION
- # less.l
- # makefile.bsd41
- # makefile.bsd42
- # makefile.sys5
- # makefile.xen
- # funcs.h
- # less.h
- # position.h
- # mkfuncs.awk
- # main.c
- # option.c
- # prim.c
- echo shar: extracting INSTALLATION
- cat - << \SHAR_EOF > INSTALLATION
- This is the distribution of "less", a paginator similar to "more" or "pg".
- The manual page is in less.l.
-
- INSTALLATION:
-
- 1. Move the distributed source to its own directory and
- unpack it by running "sh" on the distribution file,
- if you have not already done so.
-
- 2. If your system is System V:
- cp makefile.sys5 makefile
- If your system is Berkeley 4.2bsd:
- cp makefile.bsd42 makefile
- If your system is Berkeley 4.1bsd:
- cp makefile.bsd41 makefile
- If your system is Xenix 3.0:
- cp makefile.xen makefile
- Otherwise, edit the makefile to make the
- system parameters match your system.
-
- These features are selectable at compile time:
- shell escapes (SHELL_ESCAPE)
- editor invocation (EDITOR)
- alternate error message handling (ONLY_RETURN)
- If you want to have any of these features,
- edit the makefile appropriately.
- (If you do not include either SHELL_ESCAPE or EDITOR,
- you may wish to edit the manual page "less.l" to remove
- the references to the "!" and/or "v" commands.)
-
- 3. Type "make" and watch the fun.
-
- 4. If the make succeeds, it will generate a program "less"
- in your current directory. Test the generated program.
-
- 5. When satisfied that it works, if you wish to install it
- in a public place, edit the makefile so that INSTALL_LESS
- and INSTALL_MAN are the proper filenames.
- Then type "make install".
-
- If you have any problems building or running "less",
- you may mail to the author via USENET at:
- ...!tektronix!reed!nsc-pdc!mark
- or ...!ihnp4!nsc!nsc-pdc!mark
-
- Note to hackers: comments noting possible improvements are enclosed
- in double curly brackets {{ like this }}.
- SHAR_EOF
- echo shar: extracting less.l
- cat - << \SHAR_EOF > less.l
- .TH LESS l
- .SH NAME
- less \- opposite of more
- .SH SYNOPSIS
- .B "less [-cdepstwmMqQuU] [-h\fIn\fB] [-b[fp]\fIn\fB] [-x\fIn\fB] [+\fIcmd\fB] [\fIname\fB] ..."
- .SH DESCRIPTION
- .I Less
- is a program similar to
- .I more
- (1), but which allows backwards movement
- in the file as well as forward movement.
- Also,
- .I less
- does not have to read the entire input file before starting,
- so with large input files it starts up faster than text editors like
- .I vi
- (1).
- .I Less
- uses termcap, so it can run on a variety of terminals.
- There is even limited support for hardcopy terminals.
- (On a hardcopy terminal, lines which should be printed at the top
- of the screen are prefixed with an up-arrow.)
- .PP
- Commands are based on both
- .I more
- and
- .I vi.
- Commands may be preceeded by a decimal number,
- called N in the descriptions below.
- The number is used by some commands, as indicated.
-
- .SH COMMANDS
- .IP h
- Help: display a summary of these commands.
- If you forget all the other commands, remember this one.
- .PP
- .IP SPACE
- Scroll forward N lines, default one screen.
- If N is more than the screen size, only one screenful is displayed.
- .PP
- .IP f
- Same as SPACE.
- .PP
- .IP b
- Scroll backward N lines, default one screen.
- If N is more than the screen size, only one screenful is displayed.
- .PP
- .IP RETURN
- Scroll forward N lines, default 1.
- If N is more than the screen size, the entire N lines are displayed.
- .PP
- .IP e
- Same as RETURN.
- .PP
- .IP j
- Also the same as RETURN.
- .PP
- .IP y
- Scroll backward N lines, default 1.
- If N is more than the screen size, the entire N lines are displayed.
- .IP k
- Same as y.
- .PP
- .IP d
- Scroll forward N lines, default 10.
- If N is specified, it becomes the new default for all d and u commands.
- .PP
- .IP u
- Scroll backward N lines, default 10.
- If N is specified, it becomes the new default for all d and u commands.
- .PP
- .IP r
- Repaint the screen.
- .PP
- .IP R
- Repaint the screen, discarding any buffered input.
- Useful if the file is changing while it is being viewed.
- .PP
- .IP g
- Go to line N in the file, default 1 (beginning of file).
- (Warning: this may be slow if N is large.)
- .PP
- .IP G
- Go to line N in the file, default the end of the file.
- (Warning: this may be slow if standard input,
- rather than a file, is being read.)
- .PP
- .IP p
- Go to a position N percent into the file.
- N should be between 0 and 100.
- (This is possible if standard input is being read,
- but only if
- .I less
- has already read to the end of the file.
- It is always fast, but not always useful.)
- .PP
- .IP %
- Same as p.
- .PP
- .IP m
- Followed by any lowercase letter, marks the current position with that letter.
- .PP
- .IP "'"
- Followed by any lowercase letter, returns to the position which
- was previously marked with that letter.
- All marks are lost when a new file is examined.
- .PP
- .IP /pattern
- Search forward in the file for the N-th occurence of the pattern.
- N defaults to 1.
- The pattern is a regular expression, as recognized by
- .I ed.
- The search starts at the second line displayed
- (but see the -t option, which changes this).
- .PP
- .IP ?pattern
- Search backward in the file for the N-th occurence of the pattern.
- The search starts at the line immediately before the top line displayed.
- .PP
- .IP n
- Repeat previous search, for N-th occurence of the last pattern.
- .PP
- .IP E [filename]
- Examine a new file.
- If the filename is missing, the "current" file (see the N and P commands
- below) from the list of files in the command line is re-examined.
- .PP
- .IP N
- Examine the next file (from the list of files given in the command line).
- If a number N is specified (not to be confused with the command N),
- the N-th next file is examined.
- .PP
- .IP P
- Examine the previous file.
- If a number N is specified, the N-th previous file is examined.
- .PP
- .IP =
- Prints the name of the file being viewed
- and the byte offset of the bottom line being displayed.
- If possible, it also prints the length of the file
- and the percent of the file above the last displayed line.
- .PP
- .IP \-
- Followed by one of the command line option letters (see below),
- this will toggle the setting of that option
- and print a message describing the new setting.
- .PP
- .IP V
- Prints the version number of
- .I less
- being run.
- .PP
- .IP q
- Exits
- .I less.
- .PP
- The following
- two
- commands may or may not be valid, depending on your particular installation.
- .PP
- .IP v
- Invokes an editor to edit the current file being viewed.
- The editor is taken from the environment variable EDITOR,
- or defaults to "vi".
- .PP
- .IP "! shell-command"
- Invokes a shell to run the shell-command given.
- .PP
- .SH OPTIONS
- Command line options are described below.
- Options are also taken from the environment variable "LESS".
- (The environment variable is parsed before the command line,
- so command line options override the LESS environment variable.
- Options may be changed while
- .I less
- is running via the "\-" command.)
- For example, if you like
- more-style prompting, to avoid typing "less -m ..." each time
- .I less
- is invoked, you might tell
- .I csh:
- .sp
- setenv LESS m
- .sp
- or if you use
- .I sh:
- .sp
- LESS=m; export LESS
- .IP -s
- The -s flag causes
- consecutive blank lines to be squeezed into a single blank line.
- This is useful when viewing
- .I nroff
- output.
- .IP -t
- Normally, forward searches start just after
- the top displayed line (that is, at the second displayed line).
- Thus forward searches include the currently displayed screen.
- The -t command line option causes forward searches to start
- just after the bottom line displayed,
- thus skipping the currently displayed screen.
- .IP -m
- Normally,
- .I less
- prompts with a colon.
- The -m command line option causes
- .I less
- to prompt verbosely like
- .I more,
- printing the file name and percent into the file.
- .IP -M
- The -M command line option causes
- .I less
- to prompt even more verbosely than
- .I more.
- .IP -q
- Normally, if an attempt is made to scroll past the end of the file
- or before the beginning of the file, the terminal bell is rung to
- indicate this fact.
- The -q command line option tells
- .I less
- not to ring the bell at such times.
- If the terminal has a "visual bell", it is used instead.
- .IP -Q
- Even if -q is given,
- .I less
- will ring the bell on certain other errors,
- such as typing an invalid character.
- The -Q command line option tells
- .I less
- to be quiet all the time; that is, never ring the terminal bell.
- If the terminal has a "visual bell", it is used instead.
- .IP -e
- Normally the only way to exit less is via the "q" command.
- The -e command line option tells less to automatically exit
- the second time it reaches end-of-file.
- .IP -u
- If the -u command line option is given,
- backspaces are treated as printable characters;
- that is, they are sent to the terminal when they appear in the input.
- .IP -U
- If the -U command line option is given,
- backspaces are printed as the two character sequence "^H".
- If neither -u nor -U is given,
- backspaces which appear adjacent to an underscore character
- are treated specially:
- the underlined text is displayed
- using the terminal's hardware underlining capability.
- .IP -w
- Normally,
- .I less
- uses a tilde character to represent lines past the end of the file.
- The -w option causes blank lines to be used instead.
- .IP -d
- Normally,
- .I less
- will complain if the terminal is dumb; that is, lacks some important capability,
- such as the ability to clear the screen or scroll backwards.
- The -d flag suppresses this complaint
- (but does not otherwise change the behavior of the program on a dumb terminal).
- .IP -p
- Normally,
- .I less
- will repaint the screen by scrolling from the bottom of the screen.
- If the -p flag is set, when
- .I less
- needs to change the entire display, it will clear the screen
- and paint from the top line down.
- .IP -h
- Normally,
- .I less
- will scroll backwards when backwards movement is necessary.
- The -h option specifies a maximum number of lines to scroll backwards.
- If it is necessary to move backwards more than this many lines,
- the screen is repainted in a forward direction.
- (If the terminal does not have the ability to scroll
- backwards, -h0 is implied.)
- .IP -x
- The -x\fIn\fR command line option sets tab stops every \fIn\fR positions.
- The default for \fIn\fR is 8.
- .IP -b
- The -b\fIn\fR command line option tells
- .I less
- to use a non-standard buffer size.
- There are two standard (default) buffer sizes,
- one is used when a file is being read and the other
- when a pipe (standard input) is being read.
- The current defaults are 5 buffers for files and 12 for pipes.
- (Buffers are 1024 bytes.)
- The number \fIn\fR specifies a different number of buffers to use.
- The -b may be followed by "f", in which case only
- the file default is changed, or by "p" in which case only the
- pipe default is changed. Otherwise, both are changed.
- .IP -c
- Normally, when data is read by
- .I less,
- it is scanned to ensure that bit 7 (the high order bit) is turned off in
- each byte read, and to ensure that there are no null (zero) bytes in
- the data (null bytes are turned into "@" characters).
- If the data is known to be "clean",
- the -c command line option will tell
- .I less
- to skip this checking, causing an imperceptible speed improvement.
- (However, if the data is not "clean", unpredicatable results may occur.)
- .IP +
- If a command line option begins with \fB+\fR,
- the remainder of that option is taken to be an initial command to
- .I less.
- For example, +G tells
- .I less
- to start at the end of the file rather than the beginning,
- and +/xyz tells it to start at the first occurence of "xyz" in the file.
- As a special case, +<number> acts like +<number>g;
- that is, it starts the display at the specified line number
- (however, see the caveat under the "g" command above).
- If the option starts with \fB++\fR, the initial command applies to
- every file being viewed, not just the first one.
-
- .SH BUGS
- When used on standard input (rather than a file), you can move
- backwards only a finite amount, corresponding to that portion
- of the file which is still buffered.
- SHAR_EOF
- echo shar: extracting makefile.bsd41
- cat - << \SHAR_EOF > makefile.bsd41
- # Makefile for "less"
- #
- # Invoked as:
- # make all
- # or make install
- # Plain "make" is equivalent to "make all".
- #
- # If you add or delete functions, remake funcs.h by doing:
- # make newfuncs
- # This depends on the coding convention of function headers looking like:
- # " \t public <function-type> \n <function-name> ( ... ) "
- #
- # Also provided:
- # make lint # Runs "lint" on all the sources.
- # make clean # Removes "less" and the .o files.
- # make clobber # Pretty much the same as make "clean".
-
-
- ##########################################################################
- # System-specific parameters
- ##########################################################################
-
- # Define XENIX if running under XENIX 3.0
- XENIX = 0
-
- # VOID is 1 if your C compiler supports the "void" type,
- # 0 if it does not.
- VOID = 1
-
- # off_t is the type which lseek() returns.
- # It is also the type of lseek()'s second argument.
- off_t = long
-
- # TERMIO is 1 if your system has /usr/include/termio.h.
- # This is normally the case for System 5.
- # If TERMIO is 0 your system must have /usr/include/sgtty.h.
- # This is normally the case for BSD.
- TERMIO = 0
-
- # SIGSETMASK is 1 if your system has the sigsetmask() call.
- # This is normally the case only for BSD 4.2,
- # not for BSD 4.1 or System 5.
- SIGSETMASK = 0
-
-
- ##########################################################################
- # Optional and semi-optional features
- ##########################################################################
-
- # REGCMP is 1 if your system has the regcmp() function.
- # This is normally the case for System 5.
- # RECOMP is 1 if your system has the re_comp() function.
- # This is normally the case for BSD.
- # If neither is 1, pattern matching is supported, but without metacharacters.
- REGCMP = 0
- RECOMP = 1
-
- # SHELL_ESCAPE is 1 if you wish to allow shell escapes.
- # (This is possible only if your system supplies the system() function.)
- SHELL_ESCAPE = 0
-
- # EDITOR is 1 if you wish to allow editor invocation (the "v" command).
- # (This is possible only if your system supplies the system() function.)
- # EDIT_PGM is the name of the (default) editor to be invoked.
- EDITOR = 0
- EDIT_PGM = /usr/ucb/vi
-
- # ONLY_RETURN is 1 if you want RETURN to be the only input which
- # will continue past an error message.
- # Otherwise, any key will continue past an error message.
- ONLY_RETURN = 0
-
-
- ##########################################################################
- # Compilation environment.
- ##########################################################################
-
- # LIBS is the list of libraries needed.
- LIBS = -ltermcap
-
- # INSTALL_LESS is a list of the public versions of less.
- # INSTALL_MAN is a list of the public versions of the manual page.
- INSTALL_LESS = /usr/local/less
- INSTALL_MAN = /usr/man/manl/less.l
-
- # OPTIM is passed to the compiler and the loader.
- # It is normally "-O" but may be, for example, "-g".
- OPTIM = -O
-
-
- ##########################################################################
- # Files
- ##########################################################################
-
- SRC1 = main.c option.c prim.c
- SRC2 = ch.c position.c input.c output.c screen.c \
- prompt.c line.c signal.c help.c ttyin.c command.c version.c
- SRC = $(SRC1) $(SRC2)
- OBJ = main.o option.o prim.o ch.o position.o input.o output.o screen.o \
- prompt.o line.o signal.o help.o ttyin.o command.o version.o
-
-
- ##########################################################################
- # Rules
- ##########################################################################
-
- DEFS = "-DTERMIO=$(TERMIO)" \
- "-DSIGSETMASK=$(SIGSETMASK)" \
- "-Doff_t=$(off_t)" "-DVOID=$(VOID)" \
- "-DREGCMP=$(REGCMP)" "-DRECOMP=$(RECOMP)" \
- "-DSHELL_ESCAPE=$(SHELL_ESCAPE)" \
- "-DEDITOR=$(EDITOR)" "-DEDIT_PGM=\"$(EDIT_PGM)\"" \
- "-DONLY_RETURN=$(ONLY_RETURN)" \
- "-DXENIX=$(XENIX)"
-
- CFLAGS = $(OPTIM) $(DEFS)
-
-
- all: less
-
- less: $(OBJ)
- cc $(OPTIM) -o less $(OBJ) $(LIBS)
-
- install: install_man install_less
-
- install_man: less.l
- for f in $(INSTALL_MAN); do rm -f $$f; cp less.l $$f; done
- touch install_man
-
- install_less: less
- for f in $(INSTALL_LESS); do rm -f $$f; cp less $$f; done
- touch install_less
-
- $(OBJ): less.h funcs.h
-
- lint:
- lint -hp $(DEFS) $(SRC)
-
- newfuncs:
- mv funcs.h funcs.h.OLD
- awk -f mkfuncs.awk $(SRC) >funcs.h
-
- clean:
- rm -f $(OBJ) less
-
- clobber:
- rm -f *.o less install_less install_man
-
- shar:
- shar -v INSTALLATION less.l makefile.* *.h *.awk $(SRC1) > less.shar.a
- shar -v $(SRC2) > less.shar.b
- SHAR_EOF
- echo shar: extracting makefile.bsd42
- cat - << \SHAR_EOF > makefile.bsd42
- # Makefile for "less"
- #
- # Invoked as:
- # make all
- # or make install
- # Plain "make" is equivalent to "make all".
- #
- # If you add or delete functions, remake funcs.h by doing:
- # make newfuncs
- # This depends on the coding convention of function headers looking like:
- # " \t public <function-type> \n <function-name> ( ... ) "
- #
- # Also provided:
- # make lint # Runs "lint" on all the sources.
- # make clean # Removes "less" and the .o files.
- # make clobber # Pretty much the same as make "clean".
-
-
- ##########################################################################
- # System-specific parameters
- ##########################################################################
-
- # Define XENIX if running under XENIX 3.0
- XENIX = 0
-
- # VOID is 1 if your C compiler supports the "void" type,
- # 0 if it does not.
- VOID = 1
-
- # off_t is the type which lseek() returns.
- # It is also the type of lseek()'s second argument.
- off_t = long
-
- # TERMIO is 1 if your system has /usr/include/termio.h.
- # This is normally the case for System 5.
- # If TERMIO is 0 your system must have /usr/include/sgtty.h.
- # This is normally the case for BSD.
- TERMIO = 0
-
- # SIGSETMASK is 1 if your system has the sigsetmask() call.
- # This is normally the case only for BSD 4.2,
- # not for BSD 4.1 or System 5.
- SIGSETMASK = 1
-
-
- ##########################################################################
- # Optional and semi-optional features
- ##########################################################################
-
- # REGCMP is 1 if your system has the regcmp() function.
- # This is normally the case for System 5.
- # RECOMP is 1 if your system has the re_comp() function.
- # This is normally the case for BSD.
- # If neither is 1, pattern matching is supported, but without metacharacters.
- REGCMP = 0
- RECOMP = 1
-
- # SHELL_ESCAPE is 1 if you wish to allow shell escapes.
- # (This is possible only if your system supplies the system() function.)
- SHELL_ESCAPE = 0
-
- # EDITOR is 1 if you wish to allow editor invocation (the "v" command).
- # (This is possible only if your system supplies the system() function.)
- # EDIT_PGM is the name of the (default) editor to be invoked.
- EDITOR = 0
- EDIT_PGM = /usr/ucb/vi
-
- # ONLY_RETURN is 1 if you want RETURN to be the only input which
- # will continue past an error message.
- # Otherwise, any key will continue past an error message.
- ONLY_RETURN = 0
-
-
- ##########################################################################
- # Compilation environment.
- ##########################################################################
-
- # LIBS is the list of libraries needed.
- LIBS = -ltermcap
-
- # INSTALL_LESS is a list of the public versions of less.
- # INSTALL_MAN is a list of the public versions of the manual page.
- INSTALL_LESS = /usr/local/less
- INSTALL_MAN = /usr/man/manl/less.l
-
- # OPTIM is passed to the compiler and the loader.
- # It is normally "-O" but may be, for example, "-g".
- OPTIM = -O
-
-
- ##########################################################################
- # Files
- ##########################################################################
-
- SRC1 = main.c option.c prim.c
- SRC2 = ch.c position.c input.c output.c screen.c \
- prompt.c line.c signal.c help.c ttyin.c command.c version.c
- SRC = $(SRC1) $(SRC2)
- OBJ = main.o option.o prim.o ch.o position.o input.o output.o screen.o \
- prompt.o line.o signal.o help.o ttyin.o command.o version.o
-
-
- ##########################################################################
- # Rules
- ##########################################################################
-
- DEFS = "-DTERMIO=$(TERMIO)" \
- "-DSIGSETMASK=$(SIGSETMASK)" \
- "-Doff_t=$(off_t)" "-DVOID=$(VOID)" \
- "-DREGCMP=$(REGCMP)" "-DRECOMP=$(RECOMP)" \
- "-DSHELL_ESCAPE=$(SHELL_ESCAPE)" \
- "-DEDITOR=$(EDITOR)" "-DEDIT_PGM=\"$(EDIT_PGM)\"" \
- "-DONLY_RETURN=$(ONLY_RETURN)" \
- "-DXENIX=$(XENIX)"
-
- CFLAGS = $(OPTIM) $(DEFS)
-
-
- all: less
-
- less: $(OBJ)
- cc $(OPTIM) -o less $(OBJ) $(LIBS)
-
- install: install_man install_less
-
- install_man: less.l
- for f in $(INSTALL_MAN); do rm -f $$f; cp less.l $$f; done
- touch install_man
-
- install_less: less
- for f in $(INSTALL_LESS); do rm -f $$f; cp less $$f; done
- touch install_less
-
- $(OBJ): less.h funcs.h
-
- lint:
- lint -hp $(DEFS) $(SRC)
-
- newfuncs:
- mv funcs.h funcs.h.OLD
- awk -f mkfuncs.awk $(SRC) >funcs.h
-
- clean:
- rm -f $(OBJ) less
-
- clobber:
- rm -f *.o less install_less install_man
-
- shar:
- shar -v INSTALLATION less.l makefile.* *.h *.awk $(SRC1) > less.shar.a
- shar -v $(SRC2) > less.shar.b
- SHAR_EOF
- echo shar: extracting makefile.sys5
- cat - << \SHAR_EOF > makefile.sys5
- # Makefile for "less"
- #
- # Invoked as:
- # make all
- # or make install
- # Plain "make" is equivalent to "make all".
- #
- # If you add or delete functions, remake funcs.h by doing:
- # make newfuncs
- # This depends on the coding convention of function headers looking like:
- # " \t public <function-type> \n <function-name> ( ... ) "
- #
- # Also provided:
- # make lint # Runs "lint" on all the sources.
- # make clean # Removes "less" and the .o files.
- # make clobber # Pretty much the same as make "clean".
-
-
- ##########################################################################
- # System-specific parameters
- ##########################################################################
-
- # Define XENIX if running under XENIX 3.0
- XENIX = 0
-
- # VOID is 1 if your C compiler supports the "void" type,
- # 0 if it does not.
- VOID = 1
-
- # off_t is the type which lseek() returns.
- # It is also the type of lseek()'s second argument.
- off_t = long
-
- # TERMIO is 1 if your system has /usr/include/termio.h.
- # This is normally the case for System 5.
- # If TERMIO is 0 your system must have /usr/include/sgtty.h.
- # This is normally the case for BSD.
- TERMIO = 1
-
- # SIGSETMASK is 1 if your system has the sigsetmask() call.
- # This is normally the case only for BSD 4.2,
- # not for BSD 4.1 or System 5.
- SIGSETMASK = 0
-
-
- ##########################################################################
- # Optional and semi-optional features
- ##########################################################################
-
- # REGCMP is 1 if your system has the regcmp() function.
- # This is normally the case for System 5.
- # RECOMP is 1 if your system has the re_comp() function.
- # This is normally the case for BSD.
- # If neither is 1, pattern matching is supported, but without metacharacters.
- REGCMP = 1
- RECOMP = 0
-
- # SHELL_ESCAPE is 1 if you wish to allow shell escapes.
- # (This is possible only if your system supplies the system() function.)
- SHELL_ESCAPE = 0
-
- # EDITOR is 1 if you wish to allow editor invocation (the "v" command).
- # (This is possible only if your system supplies the system() function.)
- # EDIT_PGM is the name of the (default) editor to be invoked.
- EDITOR = 0
- EDIT_PGM = /usr/ucb/vi
-
- # ONLY_RETURN is 1 if you want RETURN to be the only input which
- # will continue past an error message.
- # Otherwise, any key will continue past an error message.
- ONLY_RETURN = 0
-
-
- ##########################################################################
- # Compilation environment.
- ##########################################################################
-
- # LIBS is the list of libraries needed.
- LIBS = -lcurses -lPW
-
- # INSTALL_LESS is a list of the public versions of less.
- # INSTALL_MAN is a list of the public versions of the manual page.
- INSTALL_LESS = /usr/lbin/less
- INSTALL_MAN = /usr/man/manl/less.l
-
- # OPTIM is passed to the compiler and the loader.
- # It is normally "-O" but may be, for example, "-g".
- OPTIM = -O
-
-
- ##########################################################################
- # Files
- ##########################################################################
-
- SRC1 = main.c option.c prim.c
- SRC2 = ch.c position.c input.c output.c screen.c \
- prompt.c line.c signal.c help.c ttyin.c command.c version.c
- SRC = $(SRC1) $(SRC2)
- OBJ = main.o option.o prim.o ch.o position.o input.o output.o screen.o \
- prompt.o line.o signal.o help.o ttyin.o command.o version.o
-
-
- ##########################################################################
- # Rules
- ##########################################################################
-
- DEFS = "-DTERMIO=$(TERMIO)" \
- "-DSIGSETMASK=$(SIGSETMASK)" \
- "-Doff_t=$(off_t)" "-DVOID=$(VOID)" \
- "-DREGCMP=$(REGCMP)" "-DRECOMP=$(RECOMP)" \
- "-DSHELL_ESCAPE=$(SHELL_ESCAPE)" \
- "-DEDITOR=$(EDITOR)" "-DEDIT_PGM=\"$(EDIT_PGM)\"" \
- "-DONLY_RETURN=$(ONLY_RETURN)" \
- "-DXENIX=$(XENIX)"
-
- CFLAGS = $(OPTIM) $(DEFS)
-
-
- all: less
-
- less: $(OBJ)
- cc $(OPTIM) -o less $(OBJ) $(LIBS)
-
- install: install_man install_less
-
- install_man: less.l
- for f in $(INSTALL_MAN); do rm -f $$f; cp less.l $$f; done
- touch install_man
-
- install_less: less
- for f in $(INSTALL_LESS); do rm -f $$f; cp less $$f; done
- touch install_less
-
- $(OBJ): less.h funcs.h
-
- lint:
- lint -hp $(DEFS) $(SRC)
-
- newfuncs:
- mv funcs.h funcs.h.OLD
- awk -f mkfuncs.awk $(SRC) >funcs.h
-
- clean:
- rm -f $(OBJ) less
-
- clobber:
- rm -f *.o less install_less install_man
-
- shar:
- shar -v INSTALLATION less.l makefile.* *.h *.awk $(SRC1) > less.shar.a
- shar -v $(SRC2) > less.shar.b
- SHAR_EOF
- echo shar: extracting makefile.xen
- cat - << \SHAR_EOF > makefile.xen
- # Makefile for "less"
- #
- # Invoked as:
- # make all
- # or make install
- # Plain "make" is equivalent to "make all".
- #
- # If you add or delete functions, remake funcs.h by doing:
- # make newfuncs
- # This depends on the coding convention of function headers looking like:
- # " \t public <function-type> \n <function-name> ( ... ) "
- #
- # Also provided:
- # make lint # Runs "lint" on all the sources.
- # make clean # Removes "less" and the .o files.
- # make clobber # Pretty much the same as make "clean".
-
-
- ##########################################################################
- # System-specific parameters
- ##########################################################################
-
- # Define XENIX if running under XENIX 3.0
- XENIX = 1
-
- # VOID is 1 if your C compiler supports the "void" type,
- # 0 if it does not.
- VOID = 1
-
- # off_t is the type which lseek() returns.
- # It is also the type of lseek()'s second argument.
- off_t = long
-
- # TERMIO is 1 if your system has /usr/include/termio.h.
- # This is normally the case for System 5.
- # If TERMIO is 0 your system must have /usr/include/sgtty.h.
- # This is normally the case for BSD.
- TERMIO = 1
-
- # SIGSETMASK is 1 if your system has the sigsetmask() call.
- # This is normally the case only for BSD 4.2,
- # not for BSD 4.1 or System 5.
- SIGSETMASK = 0
-
-
- ##########################################################################
- # Optional and semi-optional features
- ##########################################################################
-
- # REGCMP is 1 if your system has the regcmp() function.
- # This is normally the case for System 5.
- # RECOMP is 1 if your system has the re_comp() function.
- # This is normally the case for BSD.
- # If neither is 1, pattern matching is supported, but without metacharacters.
- REGCMP = 1
- RECOMP = 0
-
- # SHELL_ESCAPE is 1 if you wish to allow shell escapes.
- # (This is possible only if your system supplies the system() function.)
- SHELL_ESCAPE = 0
-
- # EDITOR is 1 if you wish to allow editor invocation (the "v" command).
- # (This is possible only if your system supplies the system() function.)
- # EDIT_PGM is the name of the (default) editor to be invoked.
- EDITOR = 0
- EDIT_PGM = /usr/ucb/vi
-
- # ONLY_RETURN is 1 if you want RETURN to be the only input which
- # will continue past an error message.
- # Otherwise, any key will continue past an error message.
- ONLY_RETURN = 0
-
-
- ##########################################################################
- # Compilation environment.
- ##########################################################################
-
- # LIBS is the list of libraries needed.
- LIBS = -lcurses -ltermlib
-
- # INSTALL_LESS is a list of the public versions of less.
- # INSTALL_MAN is a list of the public versions of the manual page.
- INSTALL_LESS = /usr/lbin/less
- INSTALL_MAN = /usr/man/manl/less.l
-
- # OPTIM is passed to the compiler and the loader.
- # It is normally "-O" but may be, for example, "-g".
- OPTIM = -O
-
-
- ##########################################################################
- # Files
- ##########################################################################
-
- SRC1 = main.c option.c prim.c
- SRC2 = ch.c position.c input.c output.c screen.c \
- prompt.c line.c signal.c help.c ttyin.c command.c version.c
- SRC = $(SRC1) $(SRC2)
- OBJ = main.o option.o prim.o ch.o position.o input.o output.o screen.o \
- prompt.o line.o signal.o help.o ttyin.o command.o version.o
-
-
- ##########################################################################
- # Rules
- ##########################################################################
-
- DEFS = "-DTERMIO=$(TERMIO)" \
- "-DSIGSETMASK=$(SIGSETMASK)" \
- "-Doff_t=$(off_t)" "-DVOID=$(VOID)" \
- "-DREGCMP=$(REGCMP)" "-DRECOMP=$(RECOMP)" \
- "-DSHELL_ESCAPE=$(SHELL_ESCAPE)" \
- "-DEDITOR=$(EDITOR)" "-DEDIT_PGM=\"$(EDIT_PGM)\"" \
- "-DONLY_RETURN=$(ONLY_RETURN)" \
- "-DXENIX=$(XENIX)"
-
- CFLAGS = $(OPTIM) $(DEFS)
-
-
- all: less
-
- less: $(OBJ)
- cc $(OPTIM) -o less $(OBJ) $(LIBS)
-
- install: install_man install_less
-
- install_man: less.l
- for f in $(INSTALL_MAN); do rm -f $$f; cp less.l $$f; done
- touch install_man
-
- install_less: less
- for f in $(INSTALL_LESS); do rm -f $$f; cp less $$f; done
- touch install_less
-
- $(OBJ): less.h funcs.h
-
- lint:
- lint -hp $(DEFS) $(SRC)
-
- newfuncs:
- mv funcs.h funcs.h.OLD
- awk -f mkfuncs.awk $(SRC) >funcs.h
-
- clean:
- rm -f $(OBJ) less
-
- clobber:
- rm -f *.o less install_less install_man
-
- shar:
- shar -v INSTALLATION less.l makefile.* *.h *.awk $(SRC1) > less.shar.a
- shar -v $(SRC2) > less.shar.b
- SHAR_EOF
- echo shar: extracting funcs.h
- cat - << \SHAR_EOF > funcs.h
- public void edit ();
- public void next_file ();
- public void prev_file ();
- public void quit ();
- public void init_option ();
- public void toggle_option ();
- public void scan_option ();
- public void forward ();
- public void backward ();
- public void repaint ();
- public void jump_forw ();
- public void jump_back ();
- public void jump_percent ();
- public void jump_loc ();
- public void init_mark ();
- public void setmark ();
- public void gomark ();
- public void search ();
- public int ch_seek ();
- public int ch_end_seek ();
- public POSITION ch_length ();
- public POSITION ch_tell ();
- public int ch_forw_get ();
- public int ch_back_get ();
- public void ch_init ();
- public POSITION position ();
- public void add_forw_pos ();
- public void add_back_pos ();
- public void pos_clear ();
- public int onscreen ();
- public POSITION forw_line ();
- public POSITION back_line ();
- public void put_line ();
- public int control_char ();
- public int carat_char ();
- public void flush ();
- public void dropout ();
- public void putc ();
- public void puts ();
- public void error ();
- public int error_width ();
- public void raw_mode ();
- public void get_term ();
- public void init ();
- public void deinit ();
- public void home ();
- public void add_line ();
- public void lower_left ();
- public void bell ();
- public void vbell ();
- public void clear ();
- public void clear_eol ();
- public void so_enter ();
- public void so_exit ();
- public void ul_enter ();
- public void ul_exit ();
- public void backspace ();
- public void putbs ();
- public char * eq_message ();
- public char * pr_string ();
- public void prewind ();
- public int pappend ();
- public POSITION forw_raw_line ();
- public POSITION back_raw_line ();
- public void init_signals ();
- public void psignals ();
- public void lsystem ();
- public void help ();
- public void open_getc ();
- public int getc ();
- public void commands ();
- SHAR_EOF
- echo shar: extracting less.h
- cat - << \SHAR_EOF > less.h
- /*
- * Standard include file for "less".
- */
-
- /*
- * Language details.
- */
- #if !VOID
- #define void int
- #endif
- #define public /* PUBLIC FUNCTION */
-
- /*
- * Special types and constants.
- */
- typedef long POSITION;
- /*
- * {{ Warning: if POSITION is changed to other than "long",
- * you may have to change some of the printfs which use "%ld"
- * to print a variable of type POSITION. }}
- */
-
- #define END_POSITION ((POSITION)(-2))
- #define NULL_POSITION ((POSITION)(-1))
-
- #define EOF (0)
- #define NULL (0)
-
- /* How quiet should we be? */
- #define NOT_QUIET 0 /* Ring bell at eof and for errors */
- #define LITTLE_QUIET 1 /* Ring bell only for errors */
- #define VERY_QUIET 2 /* Never ring bell */
-
- /* How should we prompt? */
- #define PR_SHORT 0 /* Prompt with colon */
- #define PR_MEDIUM 1 /* Prompt with message */
- #define PR_LONG 2 /* Prompt with longer message */
-
- /* How should we handle backspaces? */
- #define BS_UNDERLINE 0 /* Underlining converted to underline mode */
- #define BS_NORMAL 1 /* \b treated as normal char; actually output */
- #define BS_CONTROL 2 /* \b treated as control char; prints as ^H */
-
- /* Flag to eq_message() telling what to put in the message */
- #define MNAME 001 /* File name */
- #define MOF 002 /* "file x of y" */
- #define MBYTE 004 /* "byte x/y" */
- #define MPCT 010 /* Percentage into the file */
-
- /* Special chars used to tell put_line() to do something special */
- #define UL_CHAR '\201' /* Enter underline mode */
- #define UE_CHAR '\202' /* Exit underline mode */
-
- #define CONTROL(c) ((c)&037)
- #define SIGNAL(sig,func) signal(sig,func)
-
- off_t lseek();
-
- #include "funcs.h"
- SHAR_EOF
- echo shar: extracting position.h
- cat - << \SHAR_EOF > position.h
- /*
- * Include file for interfacing to position.c modules.
- */
- #define TOP 0
- #define TOP_PLUS_ONE 1
- #define BOTTOM -1
- #define BOTTOM_PLUS_ONE -2
- SHAR_EOF
- echo shar: extracting mkfuncs.awk
- cat - << \SHAR_EOF > mkfuncs.awk
- BEGIN { FS="("; state = 0 }
-
- /^ public/ { ftype = $0; state = 1 }
-
- { if (state == 1)
- state = 2
- else if (state == 2)
- { print ftype,$1,"();"; state = 0 }
- }
- SHAR_EOF
- echo shar: extracting main.c
- cat - << \SHAR_EOF > main.c
- /*
- * Entry point, initialization, miscellaneous routines.
- */
-
- #include "less.h"
- #include "position.h"
- #include <setjmp.h>
-
- public int ispipe;
- public jmp_buf main_loop;
- public char * first_cmd;
- public char * every_first_cmd;
- public int new_file;
- public int is_tty;
- public char current_file[128];
- public int ac;
- public char **av;
- public int curr_ac;
- #if EDITOR
- public char * editor;
- #endif
-
- extern int file;
- extern int nbufs;
- extern int sigs;
- extern int quit_at_eof;
- extern int p_nbufs, f_nbufs;
- extern int back_scroll;
- extern int top_scroll;
- extern int sc_height;
-
-
- /*
- * Edit a new file.
- * Filename "-" means standard input.
- * No filename means the "current" file, from the command line.
- */
- public void
- edit(filename)
- char *filename;
- {
- register int f;
- char message[100];
- static int any_edited = 0;
- static int hold_scroll = 0;
-
- if (filename == NULL || *filename == '\0')
- {
- if (curr_ac >= ac)
- {
- error("No current file");
- return;
- }
- filename = av[curr_ac];
- }
- if (strcmp(filename, "-") == 0)
- f = 0; /* Standard input */
- else if ((f = open(filename, 0)) < 0)
- {
- sprintf(message, "Cannot open %.*s",
- error_width()-13, filename);
- if (any_edited)
- error(message);
- else
- {
- puts(message);
- hold_scroll = 1;
- }
- return;
- }
-
- if (isatty(f))
- {
- /*
- * Not really necessary to call this an error,
- * but if the control terminal (for commands)
- * and the input file (for data) are the same,
- * we get weird results at best.
- */
- error("Can't take input from a terminal");
- if (f > 0)
- close(f);
- return;
- }
-
- /*
- * Close the current input file and set up to use the new one.
- */
- if (file > 0)
- close(file);
- new_file = 1;
- strcpy(current_file, filename);
- ispipe = (f == 0);
- file = f;
- ch_init( (ispipe) ? p_nbufs : f_nbufs );
- init_mark();
- if (every_first_cmd != NULL)
- first_cmd = every_first_cmd;
- if (is_tty)
- {
- any_edited = 1;
- if (hold_scroll)
- {
- /*
- * Before erasing the screen contents,
- * display the file name and ask for a keystroke.
- */
- error(filename);
- hold_scroll = 0;
- }
- if (first_cmd == NULL || *first_cmd == '\0')
- {
- /*
- * Display the first screen.
- */
- jump_back(1);
- } else
- {
- /*
- * The first_cmd will hopefully redisplay the
- * screen, so we need not display anything yet.
- * Indicate there is nothing yet on the screen.
- */
- pos_clear();
- }
- }
- }
-
- /*
- * Edit the next file in the command line list.
- */
- public void
- next_file(n)
- int n;
- {
- if (curr_ac + n >= ac)
- {
- if (quit_at_eof)
- quit();
- error("No (N-th) next file");
- } else
- edit(av[curr_ac += n]);
- }
-
- /*
- * Edit the previous file in the command line list.
- */
- public void
- prev_file(n)
- int n;
- {
- if (curr_ac - n < 0)
- error("No (N-th) previous file");
- else
- edit(av[curr_ac -= n]);
- }
-
- /*
- * Copy a file directly to standard output.
- * Used if standard output is not a tty.
- */
- static void
- cat_file()
- {
- register int c;
-
- while ((c = ch_forw_get()) != EOF)
- putc(c);
- flush();
- }
-
- /*
- * Entry point.
- */
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char *getenv();
-
-
- /*
- * Process command line arguments and LESS environment arguments.
- * Command line arguments override environment arguments.
- */
- init_option();
- scan_option(getenv("LESS"));
- argv++;
- while ( (--argc > 0) &&
- (argv[0][0] == '-' || argv[0][0] == '+') &&
- argv[0][1] != '\0')
- scan_option(*argv++);
-
- #if EDITOR
- editor = getenv("EDITOR");
- if (editor == NULL || *editor == '\0')
- editor = EDIT_PGM;
- #endif
-
- /*
- * Set up list of files to be examined.
- */
- ac = argc;
- av = argv;
- curr_ac = 0;
-
- /*
- * Set up terminal, etc.
- */
- is_tty = isatty(1);
- if (!is_tty)
- {
- /*
- * Output is not a tty.
- * Just copy the input file(s) to output.
- */
- if (ac < 1)
- {
- edit("-");
- cat_file();
- } else
- {
- do
- {
- edit((char *)NULL);
- if (file >= 0)
- cat_file();
- } while (++curr_ac < ac);
- }
- exit(0);
- }
-
- raw_mode(1);
- get_term();
- open_getc();
- init();
-
- if (back_scroll < 0)
- {
- /* {{ KLUDGE }} */
- back_scroll = sc_height-1;
- if (top_scroll)
- back_scroll--;
- }
-
- if (setjmp(main_loop))
- quit();
- init_signals();
-
- /*
- * Select the first file to examine.
- */
- if (ac < 1)
- edit("-"); /* Standard input */
- else
- {
- /*
- * Try all the files named as command arguments.
- * We are simply looking for one which can be
- * opened without error.
- */
- do
- {
- edit((char *)NULL);
- if (file >= 0)
- /* We can open this file. */
- break;
- putc('\n'); flush();
- } while (++curr_ac < ac);
- }
-
- if (file >= 0)
- commands();
- quit();
- }
-
- /*
- * Exit the program.
- */
- public void
- quit()
- {
- /*
- * Put cursor at bottom left corner, clear the line,
- * reset the terminal modes, and exit.
- */
- lower_left();
- clear_eol();
- deinit();
- flush();
- raw_mode(0);
- exit(0);
- }
- SHAR_EOF
- echo shar: extracting option.c
- cat - << \SHAR_EOF > option.c
- /*
- * Process command line options.
- * Each option is a single letter which controls a program variable.
- * The options have defaults which may be changed via
- * the command line option, or toggled via the "-" command.
- */
-
- #include "less.h"
-
- #define toupper(c) ((c)-'a'+'A')
-
- /*
- * Types of options.
- */
- #define BOOL 01 /* Boolean option: 0 or 1 */
- #define TRIPLE 02 /* Triple-valued option: 0, 1 or 2 */
- #define NUMBER 04 /* Numeric option */
- #define NO_TOGGLE 0100 /* Option cannot be toggled with "-" cmd */
-
- /*
- * Variables controlled by command line options.
- */
- public int p_nbufs, f_nbufs; /* Number of buffers. There are two values,
- one used for input from a pipe and
- the other for input from a file. */
- public int clean_data; /* Can we assume the data is "clean"?
- (That is, free of nulls, etc) */
- public int quiet; /* Should we suppress the audible bell? */
- public int top_search; /* Should forward searches start at the top
- of the screen? (alternative is bottom) */
- public int top_scroll; /* Repaint screen from top?
- (alternative is scroll from bottom) */
- public int pr_type; /* Type of prompt (short, medium, long) */
- public int bs_mode; /* How to process backspaces */
- public int know_dumb; /* Don't complain about dumb terminals */
- public int quit_at_eof; /* Quit after hitting end of file twice */
- public int squeeze; /* Squeeze multiple blank lines into one */
- public int tabstop; /* Tab settings */
- public int back_scroll; /* Repaint screen on backwards movement */
- public int twiddle; /* Display "~" for lines after EOF */
-
- extern int nbufs;
- extern char *first_cmd;
- extern char *every_first_cmd;
-
- #define DEF_F_NBUFS 5 /* Default for f_nbufs */
- #define DEF_P_NBUFS 12 /* Default for p_nbufs */
-
- static struct option
- {
- char oletter; /* The controlling letter (a-z) */
- char otype; /* Type of the option */
- int odefault; /* Default value */
- int *ovar; /* Pointer to the associated variable */
- char *odesc[3]; /* Description of each value */
- } option[] =
- {
- { 'c', BOOL, 0, &clean_data,
- { "Don't assume data is clean",
- "Assume data is clean",
- NULL
- }
- },
- { 'd', BOOL|NO_TOGGLE, 0, &know_dumb,
- { NULL, NULL, NULL}
- },
- { 'e', BOOL, 0, &quit_at_eof,
- { "Don't quit at end-of-file",
- "Quit at end-of-file",
- NULL
- }
- },
- { 'h', NUMBER, -1, &back_scroll,
- { "Backwards scroll limit is %d lines",
- NULL, NULL
- }
- },
- { 'p', BOOL, 0, &top_scroll,
- { "Repaint by scrolling from bottom of screen",
- "Repaint by painting from top of screen",
- NULL
- }
- },
- { 'x', NUMBER, 8, &tabstop,
- { "Tab stops every %d spaces",
- NULL, NULL
- }
- },
- { 's', BOOL, 0, &squeeze,
- { "Don't squeeze multiple blank lines",
- "Squeeze multiple blank lines",
- NULL
- }
- },
- { 't', BOOL, 1, &top_search,
- { "Forward search starts from bottom of screen",
- "Forward search starts from top of screen",
- NULL
- }
- },
- { 'w', BOOL, 1, &twiddle,
- { "Display nothing for lines after end-of-file",
- "Display ~ for lines after end-of-file",
- NULL
- }
- },
- { 'm', TRIPLE, 0, &pr_type,
- { "Prompt with a colon",
- "Prompt with a message",
- "Prompt with a verbose message"
- }
- },
- { 'q', TRIPLE, 0, &quiet,
- { "Ring the bell for errors AND at eof/bof",
- "Ring the bell for errors but not at eof/bof",
- "Never ring the bell"
- }
- },
- { 'u', TRIPLE, 0, &bs_mode,
- { "Underlined text displayed in underline mode",
- "All backspaces cause overstrike",
- "Backspaces print as ^H"
- }
- },
- { '\0' }
- };
-
- public char all_options[64]; /* List of all valid options */
-
- /*
- * Initialize each option to its default value.
- */
- public void
- init_option()
- {
- register struct option *o;
- register char *p;
-
- /*
- * First do special cases, not in option table.
- */
- first_cmd = every_first_cmd = NULL;
- f_nbufs = DEF_F_NBUFS; /* -bf */
- p_nbufs = DEF_P_NBUFS; /* -bp */
-
- p = all_options;
- *p++ = 'b';
-
- for (o = option; o->oletter != '\0'; o++)
- {
- /*
- * Set each variable to its default.
- * Also make a list of all options, in "all_options".
- */
- *(o->ovar) = o->odefault;
- *p++ = o->oletter;
- if (o->otype & TRIPLE)
- *p++ = toupper(o->oletter);
- }
- *p = '\0';
- }
-
- /*
- * Toggle command line flags from within the program.
- * Used by the "-" command.
- */
- public void
- toggle_option(c)
- int c;
- {
- register struct option *o;
- char message[100];
- char buf[5];
-
- /*
- * First check for special cases not handled by the option table.
- */
- switch (c)
- {
- case 'b':
- sprintf(message, "%d buffers", nbufs);
- error(message);
- return;
- }
-
-
- for (o = option; o->oletter != '\0'; o++)
- {
- if ((o->otype & BOOL) && (o->oletter == c) &&
- (o->otype & NO_TOGGLE) == 0)
- {
- /*
- * Boolean option:
- * just toggle it.
- */
- *(o->ovar) = ! *(o->ovar);
- error(o->odesc[*(o->ovar)]);
- return;
- } else if ((o->otype & TRIPLE) && (o->oletter == c) &&
- (o->otype & NO_TOGGLE) == 0)
- {
- /*
- * Triple-valued option with lower case letter:
- * make it 1 unless already 1, then make it 0.
- */
- *(o->ovar) = (*(o->ovar) == 1) ? 0 : 1;
- error(o->odesc[*(o->ovar)]);
- return;
- } else if ((o->otype & TRIPLE) && (toupper(o->oletter) == c) &&
- (o->otype & NO_TOGGLE) == 0)
- {
- /*
- * Triple-valued option with upper case letter:
- * make it 2 unless already 2, then make it 0.
- */
- *(o->ovar) = (*(o->ovar) == 2) ? 0 : 2;
- error(o->odesc[*(o->ovar)]);
- return;
- } else if ((o->otype & NUMBER) && (o->oletter == c) &&
- (o->otype & NO_TOGGLE) == 0)
- {
- sprintf(message, o->odesc[0], *(o->ovar));
- error(message);
- return;
- }
- }
-
- if (control_char(c))
- sprintf(buf, "^%c", carat_char(c));
- else
- sprintf(buf, "%c", c);
- sprintf(message, "\"-%s\": no such flag. Use one of \"%s\"",
- buf, all_options);
- error(message);
- }
-
- /*
- * Scan an argument (either from command line or from LESS environment
- * variable) and process it.
- */
- public void
- scan_option(s)
- char *s;
- {
- register struct option *o;
- register int c;
-
- if (s == NULL)
- return;
-
- next:
- if (*s == '\0')
- return;
- switch (c = *s++)
- {
- case '-':
- case ' ':
- case '\t':
- goto next;
- case '+':
- if (*s == '+')
- every_first_cmd = ++s;
- first_cmd = s;
- return;
- case 'b':
- switch (*s)
- {
- case 'f':
- s++;
- f_nbufs = getnum(&s, 'b');
- break;
- case 'p':
- s++;
- p_nbufs = getnum(&s, 'b');
- break;
- default:
- f_nbufs = p_nbufs = getnum(&s, 'b');
- break;
- }
- goto next;
- }
-
- for (o = option; o->oletter != '\0'; o++)
- {
- if ((o->otype & BOOL) && (o->oletter == c))
- {
- *(o->ovar) = ! o->odefault;
- goto next;
- } else if ((o->otype & TRIPLE) && (o->oletter == c))
- {
- *(o->ovar) = (o->odefault == 1) ? 0 : 1;
- goto next;
- } else if ((o->otype & TRIPLE) && (toupper(o->oletter) == c))
- {
- *(o->ovar) = (o->odefault == 2) ? 0 : 2;
- goto next;
- } else if ((o->otype & NUMBER) && (o->oletter == c))
- {
- *(o->ovar) = getnum(&s, c);
- goto next;
- }
- }
-
- printf("\"-%c\": invalid flag\n", c);
- exit(1);
- }
-
- /*
- * Translate a string into a number.
- * Like atoi(), but takes a pointer to a char *, and updates
- * the char * to point after the translated number.
- */
- static int
- getnum(sp, c)
- char **sp;
- int c;
- {
- register char *s;
- register int n;
-
- s = *sp;
- if (*s < '0' || *s > '9')
- {
- printf("number is required after -%c\n", c);
- exit(1);
- }
-
- n = 0;
- while (*s >= '0' && *s <= '9')
- n = 10 * n + *s++ - '0';
- *sp = s;
- return (n);
- }
- SHAR_EOF
- echo shar: extracting prim.c
- cat - << \SHAR_EOF > prim.c
- /*
- * Primitives for displaying the file on the screen.
- */
-
- #include "less.h"
- #include "position.h"
-
- public int hit_eof; /* Keeps track of how many times we hit end of file */
-
- extern int quiet;
- extern int top_search;
- extern int top_scroll;
- extern int back_scroll;
- extern int sc_width, sc_height;
- extern int sigs;
- extern char *line;
- extern char *first_cmd;
-
- /*
- * Sound the bell to indicate he is trying to move past end of file.
- */
- static void
- eof_bell()
- {
- if (quiet == NOT_QUIET)
- bell();
- else
- vbell();
- }
-
- /*
- * Check to see if the end of file is currently "displayed".
- */
- static void
- eof_check()
- {
- POSITION pos;
-
- /*
- * If the bottom line is empty, we are at EOF.
- * If the bottom line ends at the file length,
- * we must be just at EOF.
- */
- pos = position(BOTTOM_PLUS_ONE);
- if (pos == NULL_POSITION || pos == ch_length())
- hit_eof++;
- }
-
- /*
- * Display n lines, scrolling forward,
- * starting at position pos in the input file.
- * "force" means display the n lines even if we hit end of file.
- * "only_last" means display only the last screenful if n > screen size.
- */
- static void
- forw(n, pos, force, only_last)
- register int n;
- POSITION pos;
- int force;
- int only_last;
- {
- int eof = 0;
- int nlines = 0;
- int repaint_flag;
-
- /*
- * repaint_flag tells us not to display anything till the end,
- * then just repaint the entire screen.
- */
- repaint_flag = (only_last && n > sc_height-1);
-
- if (!repaint_flag)
- {
- if (top_scroll && n >= sc_height - 1)
- {
- /*
- * Start a new screen.
- * {{ This is not really desirable if we happen
- * to hit eof in the middle of this screen,
- * but we don't know if that will happen now. }}
- */
- clear();
- home();
- force = 1;
- } else
- {
- lower_left();
- clear_eol();
- }
-
- if (pos != position(BOTTOM_PLUS_ONE))
- {
- /*
- * This is not contiguous with what is
- * currently displayed. Clear the screen image
- * (position table) and start a new screen.
- */
- pos_clear();
- add_forw_pos(pos);
- force = 1;
- if (top_scroll)
- {
- clear();
- home();
- } else
- {
- puts("...skipping...\n");
- }
- }
- }
-
- while (--n >= 0)
- {
- /*
- * Read the next line of input.
- */
- pos = forw_line(pos);
- if (pos == NULL_POSITION)
- {
- /*
- * End of file: stop here unless the top line
- * is still empty, or "force" is true.
- */
- eof = 1;
- if (!force && position(TOP) != NULL_POSITION)
- break;
- line = NULL;
- }
- /*
- * Add the position of the next line to the position table.
- * Display the current line on the screen.
- */
- add_forw_pos(pos);
- nlines++;
- if (!repaint_flag)
- put_line();
- }
-
- if (eof)
- hit_eof++;
- else
- eof_check();
- if (nlines == 0)
- eof_bell();
- else if (repaint_flag)
- repaint();
- }
-
- /*
- * Display n lines, scrolling backward.
- */
- static void
- back(n, pos, force, only_last)
- register int n;
- POSITION pos;
- int force;
- int only_last;
- {
- int nlines = 0;
- int repaint_flag;
-
- repaint_flag = (n > back_scroll || (only_last && n > sc_height-1));
- hit_eof = 0;
- while (--n >= 0)
- {
- /*
- * Get the previous line of input.
- */
- pos = back_line(pos);
- if (pos == NULL_POSITION)
- {
- /*
- * Beginning of file: stop here unless "force" is true.
- */
- if (!force)
- break;
- line = NULL;
- }
- /*
- * Add the position of the previous line to the position table.
- * Display the line on the screen.
- */
- add_back_pos(pos);
- nlines++;
- if (!repaint_flag)
- {
- home();
- add_line();
- put_line();
- }
- }
-
- eof_check();
- if (nlines == 0)
- eof_bell();
- else if (repaint_flag)
- repaint();
- }
-
- /*
- * Display n more lines, forward.
- * Start just after the line currently displayed at the bottom of the screen.
- */
- public void
- forward(n, only_last)
- int n;
- int only_last;
- {
- POSITION pos;
-
- pos = position(BOTTOM_PLUS_ONE);
- if (pos == NULL_POSITION)
- {
- eof_bell();
- hit_eof++;
- return;
- }
- forw(n, pos, 0, only_last);
- }
-
- /*
- * Display n more lines, backward.
- * Start just before the line currently displayed at the top of the screen.
- */
- public void
- backward(n, only_last)
- int n;
- int only_last;
- {
- POSITION pos;
-
- pos = position(TOP);
- if (pos == NULL_POSITION)
- {
- /*
- * This will almost never happen,
- * because the top line is almost never empty.
- */
- eof_bell();
- return;
- }
- back(n, pos, 0, only_last);
- }
-
- /*
- * Repaint the screen, starting from a specified position.
- */
- static void
- prepaint(pos)
- POSITION pos;
- {
- hit_eof = 0;
- forw(sc_height-1, pos, 0, 0);
- }
-
- /*
- * Repaint the screen.
- */
- public void
- repaint()
- {
- /*
- * Start at the line currently at the top of the screen
- * and redisplay the screen.
- */
- prepaint(position(TOP));
- }
-
- /*
- * Jump to the end of the file.
- * It is more convenient to paint the screen backward,
- * from the end of the file toward the beginning.
- */
- public void
- jump_forw()
- {
- POSITION pos;
-
- if (ch_end_seek())
- {
- error("Cannot seek to end of file");
- return;
- }
- pos = ch_tell();
- clear();
- pos_clear();
- add_back_pos(pos);
- back(sc_height - 1, pos, 0, 0);
- }
-
- /*
- * Jump to line n in the file.
- */
- public void
- jump_back(n)
- register int n;
- {
- register int c;
-
- /*
- * This is done the slow way, by starting at the beginning
- * of the file and counting newlines.
- */
- if (ch_seek((POSITION)0))
- {
- /*
- * Probably a pipe with beginning of file no longer buffered.
- */
- error("Cannot get to beginning of file");
- return;
- }
-
- /*
- * Start counting lines.
- */
- while (--n > 0)
- {
- while ((c = ch_forw_get()) != '\n')
- if (c == EOF)
- {
- error("File is not that long");
- /* {{ Maybe tell him how long it is? }} */
- return;
- }
- }
-
- /*
- * Finally found the place to start.
- * Clear and redisplay the screen from there.
- *
- * {{ We *could* figure out if the new position is
- * close enough to just scroll there without clearing
- * the screen, but it's not worth it. }}
- */
- prepaint(ch_tell());
- }
-
- /*
- * Jump to a specified percentage into the file.
- * This is a poor compensation for not being able to
- * quickly jump to a specific line number.
- */
- public void
- jump_percent(percent)
- int percent;
- {
- POSITION pos, len;
-
- /*
- * Determine the position in the file
- * (the specified percentage of the file's length).
- */
- if ((len = ch_length()) == NULL_POSITION)
- {
- error("Don't know length of file");
- return;
- }
- pos = (percent * len) / 100;
- jump_loc(pos);
- }
-
- public void
- jump_loc(pos)
- POSITION pos;
- {
- register int c;
- register int nline;
- POSITION tpos;
-
- /*
- * See if the desired line is BEFORE the currently
- * displayed screen. If so, see if it is close enough
- * to scroll backwards to it.
- */
- tpos = position(TOP);
- if (pos < tpos)
- {
- for (nline = 1; nline <= back_scroll; nline++)
- {
- tpos = back_line(tpos);
- if (tpos == NULL_POSITION || tpos <= pos)
- {
- back(nline, position(TOP), 1, 0);
- return;
- }
- }
- } else if ((nline = onscreen(pos)) >= 0)
- {
- /*
- * The line is currently displayed.
- * Just scroll there.
- */
- forw(nline, position(BOTTOM_PLUS_ONE), 1, 0);
- return;
- }
-
- /*
- * Line is not on screen.
- * Back up to the beginning of the current line.
- */
- if (ch_seek(pos))
- {
- error("Cannot seek to that position");
- return;
- }
- while ((c = ch_back_get()) != '\n' && c != EOF)
- ;
- if (c == '\n')
- (void) ch_forw_get();
-
- /*
- * Clear and paint the screen.
- */
- prepaint(ch_tell());
- }
-
- /*
- * The table of marks.
- * A mark is simply a position in the file.
- */
- static POSITION marks[26];
-
- /*
- * Initialize the mark table to show no marks are set.
- */
- public void
- init_mark()
- {
- int i;
-
- for (i = 0; i < 26; i++)
- marks[i] = NULL_POSITION;
- }
-
- /*
- * See if a mark letter is valid (between a and z).
- */
- static int
- badmark(c)
- int c;
- {
- if (c < 'a' || c > 'z')
- {
- error("Choose a letter between 'a' and 'z'");
- return (1);
- }
- return (0);
- }
-
- /*
- * Set a mark.
- */
- public void
- setmark(c)
- int c;
- {
- if (badmark(c))
- return;
- marks[c-'a'] = position(TOP);
- }
-
- /*
- * Go to a previously set mark.
- */
- public void
- gomark(c)
- int c;
- {
- POSITION pos;
-
- if (badmark(c))
- return;
- if ((pos = marks[c-'a']) == NULL_POSITION)
- error("mark not set");
- else
- jump_loc(pos);
- }
-
- /*
- * Search for the n-th occurence of a specified pattern,
- * either forward (direction == '/'), or backwards (direction == '?').
- */
- public void
- search(direction, pattern, n)
- int direction;
- char *pattern;
- register int n;
- {
- register int search_forward = (direction == '/');
- POSITION pos, linepos;
-
- #if RECOMP
- char *re_comp();
- char *errmsg;
-
- /*
- * (re_comp handles a null pattern internally,
- * so there is no need to check for a null pattern here.)
- */
- if ((errmsg = re_comp(pattern)) != NULL)
- {
- error(errmsg);
- return;
- }
- #else
- #if REGCMP
- char *regcmp();
- static char *cpattern = NULL;
-
- if (pattern == NULL || *pattern == '\0')
- {
- /*
- * A null pattern means use the previous pattern.
- * The compiled previous pattern is in cpattern, so just use it.
- */
- if (cpattern == NULL)
- {
- error("No previous regular expression");
- return;
- }
- } else
- {
- /*
- * Otherwise compile the given pattern.
- */
- char *s;
- if ((s = regcmp(pattern, 0)) == NULL)
- {
- error("Invalid pattern");
- return;
- }
- if (cpattern != NULL)
- free(cpattern);
- cpattern = s;
- }
- #else
- static char lpbuf[100];
- static char *last_pattern = NULL;
-
- if (pattern == NULL || *pattern == '\0')
- {
- /*
- * Null pattern means use the previous pattern.
- */
- if (last_pattern == NULL)
- {
- error("No previous regular expression");
- return;
- }
- pattern = last_pattern;
- } else
- {
- strcpy(lpbuf, pattern);
- last_pattern = lpbuf;
- }
- #endif
- #endif
-
- /*
- * Figure out where to start the search.
- */
-
- if (position(TOP) == NULL_POSITION)
- {
- /*
- * Nothing is currently displayed.
- * Start at the beginning of the file.
- * (This case is mainly for first_cmd searches,
- * for example, "+/xyz" on the command line.)
- */
- pos = (POSITION)0;
- } else if (!search_forward)
- {
- /*
- * Backward search: start just before the top line
- * displayed on the screen.
- */
- pos = position(TOP);
- } else if (top_search)
- {
- /*
- * Forward search and "start from top".
- * Start at the second line displayed on the screen.
- */
- pos = position(TOP_PLUS_ONE);
- } else
- {
- /*
- * Forward search but don't "start from top".
- * Start just after the bottom line displayed on the screen.
- */
- pos = position(BOTTOM_PLUS_ONE);
- }
-
- if (pos == NULL_POSITION)
- {
- /*
- * Can't find anyplace to start searching from.
- */
- error("Nothing to search");
- return;
- }
-
- for (;;)
- {
- /*
- * Get lines until we find a matching one or
- * until we hit end-of-file (or beginning-of-file
- * if we're going backwards).
- */
- if (sigs)
- /*
- * A signal aborts the search.
- */
- return;
-
- if (search_forward)
- {
- /*
- * Read the next line, and save the
- * starting position of that line in linepos.
- */
- linepos = pos;
- pos = forw_raw_line(pos);
- } else
- {
- /*
- * Read the previous line and save the
- * starting position of that line in linepos.
- */
- pos = back_raw_line(pos);
- linepos = pos;
- }
-
- if (pos == NULL_POSITION)
- {
- /*
- * We hit EOF/BOF without a match.
- */
- error("Pattern not found");
- return;
- }
-
- /*
- * Test the next line to see if we have a match.
- * This is done in a variety of ways, depending
- * on what pattern matching functions are available.
- */
- #if REGCMP
- if ( (regex(cpattern, line) != NULL)
- #else
- #if RECOMP
- if ( (re_exec(line) == 1)
- #else
- if ( (match(pattern, line))
- #endif
- #endif
- && (--n <= 0) )
- /*
- * Found the matching line.
- */
- break;
- }
- jump_loc(linepos);
- }
-
- #if (!REGCMP) && (!RECOMP)
- /*
- * We have neither regcmp() nor re_comp().
- * We use this function to do simple pattern matching.
- * It supports no metacharacters like *, etc.
- */
- static int
- match(pattern, buf)
- char *pattern, *buf;
- {
- register char *pp, *lp;
-
- for ( ; *buf != '\0'; buf++)
- {
- for (pp = pattern, lp = buf; *pp == *lp; pp++, lp++)
- if (*pp == '\0' || *lp == '\0')
- break;
- if (*pp == '\0')
- return (1);
- }
- return (0);
- }
- #endif
- SHAR_EOF
-
-
-