Import the [now] dual licensed version 3.5.4 of less. It is

distributed under your choice of the GPL or a BSD style license.

Reviewed by:	peter
Obtained from:	http://home.flash.net/~marknu/less/
This commit is contained in:
Paul Saab 2000-05-22 09:53:22 +00:00
commit a5f0fb151d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/less/dist/; revision=60786
svn path=/vendor/less/v354/; revision=60788; tag=vendor/less/v354
76 changed files with 33117 additions and 0 deletions

340
contrib/less/COPYING Normal file
View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

186
contrib/less/INSTALL Normal file
View File

@ -0,0 +1,186 @@
This file describes how to build and install less using
the "configure" script. This only works on Unix systems.
To install on other systems, read the README file.
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another
architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields:
CPU-COMPANY-SYSTEM
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made.
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.

27
contrib/less/LICENSE Normal file
View File

@ -0,0 +1,27 @@
Less License
------------
Less
Copyright (C) 1984-2000 Mark Nudelman
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice in the documentation and/or other materials provided with
the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

118
contrib/less/Makefile.aut Normal file
View File

@ -0,0 +1,118 @@
# Makefile for authoring less.
EMAIL = marknu@flash.net
HOMEPAGE = http://www.flash.net/~marknu/less
SHELL = /bin/sh
RCS = rcs
NROFF = nroff -man
srcdir = .
SRC = \
main.c screen.c brac.c ch.c charset.c cmdbuf.c \
command.c decode.c edit.c filename.c forwback.c \
help.c ifile.c input.c jump.c line.c linenum.c \
lsystem.c mark.c optfunc.c option.c opttbl.c os.c \
output.c position.c prompt.c search.c signal.c \
tags.c ttyin.c version.c
DISTFILES_W = \
defines.ds Makefile.dsb Makefile.dsg Makefile.dsm \
defines.o2 Makefile.o2e \
defines.o9 Makefile.o9c Makefile.o9u \
defines.wn Makefile.wnm Makefile.wnb
DISTFILES = \
${SRC} regexp.c regexp.h \
COPYING INSTALL LICENSE Makefile.in Makefile.aut NEWS README \
configure configure.in acconfig.h lesskey.c lessecho.c \
cmd.h funcs.h lglob.h less.h lesskey.h option.h pckeys.h position.h \
install.sh defines.h.in defines.h.top mkinstalldirs \
less.nro lesskey.nro less.man lesskey.man less.hlp \
mkfuncs.awk mkhelp.c \
${DISTFILES_W}
all: help.c funcs.h ${srcdir}/configure
help.c: less.hlp mkhelp
-mv -f ${srcdir}/help.c ${srcdir}/help.c.old
rm -rf help.c
./mkhelp < less.hlp > help.c
if cmp -s help.c help.c.old; then mv help.c.old help.c; fi
mkhelp: mkhelp.c
${CC} -o mkhelp mkhelp.c
${srcdir}/configure: ${srcdir}/configure.in \
${srcdir}/Makefile.in \
${srcdir}/defines.h.top \
${srcdir}/acconfig.h
cd ${srcdir}; autoheader; autoconf
funcs.h: ${SRC:%=${srcdir}/%}
-mv -f ${srcdir}/funcs.h ${srcdir}/funcs.h.old
awk -f ${srcdir}/mkfuncs.awk ${SRC:%=${srcdir}/%} >${srcdir}/funcs.h
if cmp -s funcs.h funcs.h.old; then mv funcs.h.old funcs.h; fi
lint:
lint -I. ${CPPFLAGS} ${SRC}
clean:
rm -f Makefile config.status config.log config.cache defines.h stamp-h \
README NEWS less.nro lesskey.nro less.man lesskey.man
distclean: clean
realclean: clean
REPLACE_VERSION = \
@REL=`sed -e '/char version/!d' -e 's/[^0-9.]*\([0-9.]*\).*/\1/' -e q ${srcdir}/version.c`; \
DT=`date '+%d %h %Y'`; \
echo "Stuffing version number $$REL into $@"; \
sed \
-e "s;@@VERSION@@;$$REL;" \
-e "s;@@DATE@@;$$DT;" \
-e "s;@@EMAIL@@;${EMAIL};" \
-e "s;@@HOMEPAGE@@;${HOMEPAGE};" >$@
${srcdir}/README: ${srcdir}/README.VER ${srcdir}/version.c
${REPLACE_VERSION} ${srcdir}/README.VER
${srcdir}/NEWS: ${srcdir}/NEWS.VER ${srcdir}/version.c
${REPLACE_VERSION} ${srcdir}/NEWS.VER
${srcdir}/less.nro: ${srcdir}/less.nro.VER ${srcdir}/version.c
${REPLACE_VERSION} ${srcdir}/less.nro.VER
${srcdir}/lesskey.nro: ${srcdir}/lesskey.nro.VER ${srcdir}/version.c
${REPLACE_VERSION} ${srcdir}/lesskey.nro.VER
${srcdir}/less.hlp: ${srcdir}/less.hlp.VER ${srcdir}/version.c
${REPLACE_VERSION} ${srcdir}/less.hlp.VER
${srcdir}/less.man: ${srcdir}/less.nro
${NROFF} ${srcdir}/less.nro >${srcdir}/less.man
${srcdir}/lesskey.man: ${srcdir}/lesskey.nro
${NROFF} ${srcdir}/lesskey.nro >${srcdir}/lesskey.man
distfiles: ${DISTFILES}
dist: ${DISTFILES}
if [ ! -d ${srcdir}/release ]; then mkdir ${srcdir}/release; fi
@cd ${srcdir}; \
REL=`sed -e '/char version/!d' -e 's/[^0-9.]*\([0-9.]*\).*/less-\1/' -e q version.c`; \
rm -rf release/$$REL; mkdir release/$$REL; \
echo "Preparing $$REL"; \
rm -rf $$REL; mkdir $$REL; \
for file in ${DISTFILES}; do \
cp -p $$file $$REL; \
chmod -w $$REL/$$file; \
done; \
cd $$REL; chmod +w ${DISTFILES_W}; cd ..; \
echo "Creating release/$$REL/$$REL.tar.gz"; \
tar -cf - $$REL | gzip -c >release/$$REL/$$REL.tar.gz; \
echo "Creating release/$$REL/$$REL.zip"; \
zip -rq release/$$REL/$$REL.zip $$REL; \
rm -rf $$REL
tagall:
@REL=`sed -e '/char version/!d' -e 's/[^0-9.]*\([0-9.]*\).*/v\1/' -e q ${srcdir}/version.c`; \
echo "tagging $$REL"; \
for f in ${srcdir}/RCS/*,v; do \
REV=`co -p $$f 2>&1 | sed -e '1d' -e '3,$$d' -e 's/revision //'`; \
${RCS} -N$$REL:$$REV $$f; \
done

50
contrib/less/Makefile.dsb Normal file
View File

@ -0,0 +1,50 @@
# Makefile for less.
# MS-DOS version (Borland C/C++ 4.02)
#### Start of system configuration section. ####
CC = bcc
LIBDIR = \bc\lib
CFLAGS = -A- -mm -O2 -w- -1- -2- -a -d -Z
LDFLAGS = -mm
LIBS =
EXT = .EXE
#### End of system configuration section. ####
# This rule allows us to supply the necessary -D options
# in addition to whatever the user asks for.
.c.obj:
$(CC) -c -I. $(CPPFLAGS) $(CFLAGS) $<
OBJ = main.obj screen.obj brac.obj ch.obj charset.obj cmdbuf.obj command.obj \
decode.obj edit.obj filename.obj forwback.obj help.obj ifile.obj \
input.obj jump.obj line.obj linenum.obj lsystem.obj \
mark.obj optfunc.obj option.obj opttbl.obj os.obj output.obj \
position.obj prompt.obj search.obj signal.obj tags.obj \
ttyin.obj version.obj
all: less$(EXT) lesskey$(EXT)
# This is really horrible, but the command line is too long for
# MS-DOS if we try to link $(OBJ).
less$(EXT): $(OBJ)
ren lesskey.obj lesskey.obo
$(CC) $(LDFLAGS) -e$@ *.obj $(LIBS)
ren lesskey.obo lesskey.obj
lesskey$(EXT): lesskey.obj version.obj
$(CC) $(LDFLAGS) -e$@ lesskey.obj version.obj $(LIBS)
defines.h: defines.ds
-del defines.h
-copy defines.ds defines.h
$(OBJ): less.h defines.h
clean:
-del *.obj
-del less.exe
-del lesskey.exe

74
contrib/less/Makefile.dsg Normal file
View File

@ -0,0 +1,74 @@
# Makefile for less under DJGPP v2.0 or later.
#### Start of system configuration section. ####
srcdir = .
VPATH = .
CC = gcc
AWK = gawk
CFLAGS = -O2 -g
CFLAGS_COMPILE_ONLY = -c
#LDFLAGS = -s
LDFLAGS = -g
O=o
LIBS =
#### End of system configuration section. ####
# This rule allows us to supply the necessary -D options
# in addition to whatever the user asks for.
.c.o:
${CC} -I. ${CFLAGS_COMPILE_ONLY} ${CPPFLAGS} ${CFLAGS} $<
OBJ = main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \
command.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \
help.${O} ifile.${O} input.${O} jump.${O} line.${O} linenum.${O} \
lsystem.${O} mark.${O} optfunc.${O} option.${O} opttbl.${O} os.${O} \
output.${O} position.${O} prompt.${O} search.${O} signal.${O} \
tags.${O} ttyin.${O} version.${O}
all: less lesskey lessecho
less: ${OBJ}
${CC} ${LDFLAGS} -o $@ ${OBJ} ${LIBS}
lesskey: lesskey.${O} version.${O}
${CC} ${LDFLAGS} -o $@ lesskey.${O} version.${O}
lessecho: lessecho.${O} version.${O}
${CC} ${LDFLAGS} -o $@ lessecho.${O} version.${O}
defines.h: defines.ds
command.com /c copy $< $@
${OBJ}: less.h defines.h funcs.h
info:
install-info:
dvi:
check:
installcheck:
TAGS:
etags *.c *.h
newfuncs:
command.com /c if exist funcs.h del funcs.h
${AWK} -f mkfuncs.awk ${OBJ:.${O}=.c} > funcs.h
clean:
command.com /c for %f in (*.${O} less lesskey lessecho *.exe) do if exist %f del %f
mostlyclean: clean
distclean: clean
command.com /c if not exist Makefile.dsg ren Makefile Makefile.dsg
command.com /c if not exist defines.ds ren defines.h defines.ds
command.com /c for %f in (Makefile defines.h) do if exist %f del %f
realclean: distclean
command.com /c if exist TAGS del TAGS

58
contrib/less/Makefile.dsm Normal file
View File

@ -0,0 +1,58 @@
# Makefile for less.
# MS-DOS version
#### Start of system configuration section. ####
CC = cl
# Change the following directories to match your installation.
LIBDIR = c:\msvc\lib
INCDIR = c:\msvc\include
# CFLAGS are compile-time options and LDFLAGS are link-time options. They are
# customized for MSVC 1.0 (MSC 8.0). If you have a different version of the
# compiler, you may need to change some of the options to their equivalents.
# -Ot optimize for speed
# -AL large memory model
# -Za ANSI C conformance
# -nologo suppress MSVC banners
# -onerror:noexe no .EXE file if link errors occur
CFLAGS = -Ot -AL -Za -nologo
LDFLAGS = -onerror:noexe -nologo
LIBS = $(LIBDIR)\llibce.lib $(LIBDIR)\graphics.lib
#### End of system configuration section. ####
# This rule allows us to supply the necessary -D options
# in addition to whatever the user asks for.
.c.obj:
$(CC) -c -I. -I$(INCDIR) $(CPPFLAGS) $(CFLAGS) $<
OBJ = main.obj screen.obj brac.obj ch.obj charset.obj cmdbuf.obj command.obj \
decode.obj edit.obj filename.obj forwback.obj help.obj ifile.obj \
input.obj jump.obj line.obj linenum.obj lsystem.obj \
mark.obj optfunc.obj option.obj opttbl.obj os.obj output.obj \
position.obj prompt.obj search.obj signal.obj tags.obj \
ttyin.obj version.obj
all: less lesskey
# This is really horrible, but the command line is too long for
# MS-DOS if we try to link $(OBJ).
less: $(OBJ)
-if exist lesskey.obj del lesskey.obj
$(CC) $(LDFLAGS) -o $@ *.obj $(LIBS)
lesskey: lesskey.obj version.obj
$(CC) $(LDFLAGS) -o $@ lesskey.obj version.obj $(LIBS)
defines.h: defines.ds
-del defines.h
-copy defines.ds defines.h
$(OBJ): less.h defines.h
clean:
-del *.obj
-del less.exe
-del lesskey.exe

110
contrib/less/Makefile.in Normal file
View File

@ -0,0 +1,110 @@
# Makefile for less.
#### Start of system configuration section. ####
srcdir = @srcdir@
VPATH = @srcdir@
CC = @CC@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CFLAGS = @CFLAGS@
CFLAGS_COMPILE_ONLY = -c
LDFLAGS = @LDFLAGS@
O=o
LIBS = @LIBS@
prefix = @prefix@
exec_prefix = @exec_prefix@
# Where the installed binary goes.
bindir = @bindir@
binprefix =
mandir = @mandir@
manext = 1
manprefix =
#### End of system configuration section. ####
SHELL = /bin/sh
# This rule allows us to supply the necessary -D options
# in addition to whatever the user asks for.
.c.o:
${CC} -I. ${CFLAGS_COMPILE_ONLY} -DSYSDIR=\"${bindir}\" ${CPPFLAGS} ${CFLAGS} $<
OBJ = main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \
command.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \
help.${O} ifile.${O} input.${O} jump.${O} line.${O} linenum.${O} \
lsystem.${O} mark.${O} optfunc.${O} option.${O} opttbl.${O} os.${O} \
output.${O} position.${O} prompt.${O} search.${O} signal.${O} \
tags.${O} ttyin.${O} version.${O} @REGEX_O@
all: less lesskey lessecho
less: ${OBJ}
${CC} ${LDFLAGS} -o $@ ${OBJ} ${LIBS}
lesskey: lesskey.${O} version.${O}
${CC} ${LDFLAGS} -o $@ lesskey.${O} version.${O}
lessecho: lessecho.${O} version.${O}
${CC} ${LDFLAGS} -o $@ lessecho.${O} version.${O}
${OBJ}: ${srcdir}/less.h ${srcdir}/funcs.h defines.h
install: all ${srcdir}/less.nro ${srcdir}/lesskey.nro installdirs
${INSTALL_PROGRAM} less ${bindir}/${binprefix}less
${INSTALL_PROGRAM} lesskey ${bindir}/${binprefix}lesskey
${INSTALL_PROGRAM} lessecho ${bindir}/${binprefix}lessecho
${INSTALL_DATA} ${srcdir}/less.nro ${mandir}/man${manext}/${manprefix}less.${manext}
${INSTALL_DATA} ${srcdir}/lesskey.nro ${mandir}/man${manext}/${manprefix}lesskey.${manext}
install-strip:
${MAKE} INSTALL_PROGRAM='${INSTALL_PROGRAM} -s' install
installdirs: mkinstalldirs
${srcdir}/mkinstalldirs ${bindir} ${mandir}/man${manext}
uninstall:
rm -f ${bindir}/${binprefix}less ${bindir}/${binprefix}lesskey ${bindir}/${binprefix}lessecho
rm -f ${mandir}/man${manext}/${manprefix}less.${manext} ${mandir}/man${manext}/${manprefix}lesskey.${manext}
info:
install-info:
dvi:
check:
installcheck:
TAGS:
cd ${srcdir} && etags *.c *.h
# config.status might not change defines.h
# Don't rerun config.status if we just configured (so there's no stamp-h).
defines.h: stamp-h
stamp-h: defines.h.in config.status
test ! -f stamp-h || CONFIG_FILES= CONFIG_HEADERS=defines.h ./config.status
touch stamp-h
Makefile: ${srcdir}/Makefile.in config.status
CONFIG_FILES=Makefile CONFIG_HEADERS= ./config.status
config.status: ${srcdir}/configure
./config.status --recheck
${srcdir}/configure: ${srcdir}/configure.in
cd ${srcdir}; autoheader; autoconf
clean:
rm -f *.${O} core less lesskey lessecho
mostlyclean: clean
distclean: clean
rm -f Makefile config.status config.log config.cache defines.h stamp-h
realclean: distclean
rm -f TAGS

39
contrib/less/Makefile.o2e Normal file
View File

@ -0,0 +1,39 @@
# Makefile for less.
# OS/2 version, for emx+gcc compiler
#### Start of system configuration section. ####
CC = gcc -Zomf
CFLAGS = -I. -O
LDFLAGS = -s -Zcrtdll -Zstack 512
LIBS = -ltermcap
O = obj
#### End of system configuration section. ####
.SUFFIXES: .c .${O}
# This rule allows us to supply the necessary -D options
# in addition to whatever the user asks for.
.c.${O}:
${CC} -c ${CPPFLAGS} ${CFLAGS} $<
OBJ = main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \
command.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \
help.${O} ifile.${O} input.${O} jump.${O} line.${O} linenum.${O} \
lsystem.${O} mark.${O} optfunc.${O} option.${O} opttbl.${O} os.${O} \
output.${O} position.${O} prompt.${O} search.${O} signal.${O} \
tags.${O} ttyin.${O} version.${O} regexp.${O}
all: less.exe lesskey.exe
less.exe: ${OBJ}
${CC} ${OBJ} -o $@ ${LDFLAGS} ${LIBS}
lesskey.exe: lesskey.${O} version.${O}
${CC} lesskey.${O} version.${O} -o $@ ${LDFLAGS}
${OBJ}: defines.h less.h
defines.h: defines.o2
copy defines.o2 defines.h

46
contrib/less/Makefile.o9c Normal file
View File

@ -0,0 +1,46 @@
# Makefile for less.
# OS-9 version for Microware C 3.2.
#### Start of system configuration section. ####
CC = cc
CPPFLAGS = -D_OSK_MWC32 -DDEBUG=0 -DSTRCSPN
CFLAGS = -k=0 -v=.
CFLAGS_COMPILE_ONLY = -r
LDFLAGS = -igm=8
LIBS = -l=/dd/lib/termlib.l
O = r
#### End of system configuration section. ####
.SUFFIXES: .c .${O}
# This rule allows us to supply the necessary -D options
# in addition to whatever the user asks for.
.c.${O}:
${CC} ${CFLAGS_COMPILE_ONLY} ${CPPFLAGS} ${CFLAGS} $<
OBJ = main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \
command.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \
help.${O} ifile.${O} input.${O} jump.${O} line.${O} linenum.${O} \
lsystem.${O} mark.${O} optfunc.${O} option.${O} opttbl.${O} os.${O} \
output.${O} position.${O} prompt.${O} search.${O} signal.${O} \
tags.${O} ttyin.${O} version.${O} regexp.${O}
all: less lessecho lesskey
less: ${OBJ}
${CC} ${OBJ} -f=$@ ${LDFLAGS} ${LIBS}
lesskey: lesskey.${O} version.${O}
${CC} lesskey.${O} version.${O} -f=$@ ${LDFLAGS}
lessecho: lessecho.${O} version.${O}
${CC} lessecho.${O} version.${O} -f=$@ ${LDFLAGS}
${OBJ}: defines.h less.h
defines.h: defines.o9
copy defines.o9 defines.h -rf

42
contrib/less/Makefile.o9u Normal file
View File

@ -0,0 +1,42 @@
# Makefile for less.
# OS-9 version for Ultra C.
#### Start of system configuration section. ####
CC = cc
CPPFLAGS =
CFLAGS = -v=.
CFLAGS_COMPILE_ONLY = -eas
LDFLAGS = -olM=24k
LIBS = -ltermlib.l -lsys_clib.l -lunix.l
O = r
#### End of system configuration section. ####
.SUFFIXES: .c .${O}
# This rule allows us to supply the necessary -D options
# in addition to whatever the user asks for.
.c.${O}:
${CC} ${CFLAGS_COMPILE_ONLY} ${CPPFLAGS} ${CFLAGS} $<
OBJ = main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \
command.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \
help.${O} ifile.${O} input.${O} jump.${O} line.${O} linenum.${O} \
lsystem.${O} mark.${O} optfunc.${O} option.${O} opttbl.${O} os.${O} \
output.${O} position.${O} prompt.${O} search.${O} signal.${O} \
tags.${O} ttyin.${O} version.${O} regexp.${O}
all: less lesskey
less: ${OBJ}
${CC} ${OBJ} -f=$@ ${LDFLAGS} ${LIBS}
lesskey: lesskey.${O} version.${O}
${CC} lesskey.${O} version.${O} -f=$@ ${LDFLAGS}
${OBJ}: defines.h less.h
defines.h: defines.o9
copy defines.o9 defines.h -rf

49
contrib/less/Makefile.wnb Normal file
View File

@ -0,0 +1,49 @@
# Makefile for less.
# Windows version
#### Start of system configuration section. ####
CC = bcc32
LIBDIR = d:\bc45\lib
CFLAGS = -O2 -w-pro -TWC -P-c -v- -d -f- -ff- -vi
LDFLAGS = /Tpe /v- /ap /c /x
LD = tlink32
LIBS = ${LIBDIR}\import32.lib ${LIBDIR}\cw32.lib
#### End of system configuration section. ####
# This rule allows us to supply the necessary -D options
# in addition to whatever the user asks for.
.c.obj:
${CC} -c -I. ${CPPFLAGS} ${CFLAGS} $<
OBJ = main.obj screen.obj brac.obj ch.obj charset.obj cmdbuf.obj command.obj \
decode.obj edit.obj filename.obj forwback.obj help.obj ifile.obj \
input.obj jump.obj line.obj linenum.obj lsystem.obj \
mark.obj optfunc.obj option.obj opttbl.obj os.obj output.obj \
position.obj prompt.obj search.obj signal.obj tags.obj \
ttyin.obj version.obj regexp.obj
all: less lesskey
# This is really horrible, but the command line is too long for
# MS-DOS if we try to link ${OBJ}.
less: ${OBJ}
-del lesskey.obj
${LD} ${LDFLAGS} ${LIBDIR}\c0x32.obj *.obj, $@,,${LIBS}
lesskey: lesskey.obj version.obj
${LD} ${LDFLAGS} ${LIBDIR}\c0x32.obj lesskey.obj version.obj, $@,,${LIBS}
defines.h: defines.wn
-del defines.h
-copy defines.wn defines.h
${OBJ}: less.h defines.h funcs.h cmd.h
clean:
-del *.obj
-del less.exe
-del lesskey.exe

55
contrib/less/Makefile.wnm Normal file
View File

@ -0,0 +1,55 @@
# Makefile for less.
# Windows 32 Visual C++ version
#### Start of system configuration section. ####
CC = cl
# Normal flags
CFLAGS = /nologo /ML /W3 /GX /O2 /I "." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /c
LDFLAGS = /subsystem:console /incremental:no /machine:I386
# Debugging flags
#CFLAGS = /nologo /MDd /W3 /GX /Od /Gm /Zi /I "." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /c
#LDFLAGS = /subsystem:console /incremental:yes /debug /machine:I386
LD = link
LIBS = user32.lib
#### End of system configuration section. ####
# This rule allows us to supply the necessary -D options
# in addition to whatever the user asks for.
.c.obj:
$(CC) $(CFLAGS) $<
OBJ = main.obj screen.obj brac.obj ch.obj charset.obj cmdbuf.obj command.obj \
decode.obj edit.obj filename.obj forwback.obj help.obj ifile.obj \
input.obj jump.obj line.obj linenum.obj lsystem.obj \
mark.obj optfunc.obj option.obj opttbl.obj os.obj output.obj \
position.obj prompt.obj search.obj signal.obj tags.obj \
ttyin.obj version.obj regexp.obj
all: less.exe lesskey.exe
# This is really horrible, but the command line is too long for
# MS-DOS if we try to link ${OBJ}.
less.exe: $(OBJ)
-del lesskey.obj
$(LD) $(LDFLAGS) *.obj $(LIBS) /out:$@
lesskey.exe: lesskey.obj version.obj
$(LD) $(LDFLAGS) lesskey.obj version.obj $(LIBS) /out:$@
defines.h: defines.wn
-del defines.h
-copy defines.wn defines.h
$(OBJ): less.h defines.h funcs.h cmd.h
clean:
-del *.obj
-del less.exe
-del lesskey.exe

485
contrib/less/NEWS Normal file
View File

@ -0,0 +1,485 @@
NEWS about less
======================================================================
For the latest news about less, see the "less" Web page:
http://www.flash.net/~marknu/less
You can also download the latest version of less from there.
To report bugs, suggestions or comments, send email to
bug-less@gnu.org or marknu@flash.net.
======================================================================
Major changes between "less" versions 352 and 354
* Allow space after numeric-valued command line options.
* Fix problem with configuring terminal libraries on some systems.
* Add support for PCRE regular expression library.
* Add --with-regex option to configure to allow manually selecting
a regular expression library.
* Fix bug compiling with SECURE = 1.
======================================================================
Major changes between "less" versions 346 and 352
* Enable UTF-8 if "UTF-8" appears in locale-related environment variables.
* Add --with-editor option to configure script.
* The -M prompt and = message now show the top and bottom line number.
* Fix bug in running the editor on a file whose name contains quotes, etc.
* Fix bug in horizontal scrolling of long lines.
* Fix bug in doing :d on a file which contains marks.
* Fix bug causing cleared lines to sometimes be filled with standout,
bold, underline, etc. on certain terminals.
* Fixes for MS-DOS (DJGPP) version.
======================================================================
Major changes between "less" versions 340 and 346
* The UTF-8 character set is now supported.
* The default character set is now latin1 rather than ascii.
* New option -R (--RAW-CONTROL-CHARS) is like -r but handles
long (wrapped) lines correctly, as long as the input contains only
normal text and ANSI color escape sequences.
* New option -F (--quit-if-one-screen) quits if the text fits on
the first screen.
* The -w option now highlights the target line of a g or p command.
* A system-wide lesskey file is supported (LESSKEY_SYSTEM).
* New escape for prompt strings: %c is replaced by column number.
* New escape for prompt strings: %P is replaced by percentage into
file, based on line number rather than byte offset.
* HOME and END keys now jump to beginning of file or end of file.
======================================================================
Major changes between "less" versions 337 and 340
* Command line options for less may now be given in either the old
single-letter form, or a new long name form (--option-name).
See the less man page or "less --help" for the list of long option names.
* Command line options for lesskey may now be given in a new long name
form. See the lesskey man page for the list of long option names.
* New command -- toggles an option using the long option name.
* New command __ queries an option using the long option name.
* The old -- command is renamed as -!.
* If a ^P is entered between the dash and the option letter of the -
command, the message describing the new setting is suppressed.
* Lesskey files may now contain \k escape sequences to represent the
"special" keys (arrows, PAGE-UP/PAGE-DOWN, HOME, END, INSERT, DELETE).
* New command :d removes the current file from the list of files.
* New option -~ (like -w before version 335)
suppresses tildes after end-of-file.
* Less is now released under the GNU General Public License.
======================================================================
Major changes between "less" versions 335 and 337
* Fixed bugs in "make install".
======================================================================
Major changes between "less" versions 332 and 335
* The old -w flag (suppress tildes after end-of-file) has been removed.
* New -w flag highlights the first new line after a forward-screen.
* New -W flag highlights the first new line after any forward movement.
* Window resize works even if LINES and/or COLUMNS environment
variables are incorrect.
* New percent escapes for prompt strings:
%d is replaced by the page number, and
%D is replaced by the number of pages in the file.
* Added charsets "iso8859" and "ebcdic".
* In Windows version, uses HOMEDRIVE and HOMEPATH if HOME is not defined.
* Fixed some bugs causing incorrect display on DOS/Windows.
======================================================================
Major changes between "less" versions 330 and 332
* Filenames from the command line are entered into the command history,
so UPARROW/DOWNARROW can be used to retrieve them from the :e command.
* Now works correctly on Windows when using a scrolling terminal
window (buffer larger than display window).
* On Windows, now restores the console screen on exit.
Use -X to get the old behavior.
* Fixed bug on Windows when CAPS-LOCK or NUM-LOCK is pressed.
* Fixed bug on Windows when piping output of an interactive program.
* Fixed bug in tags file processing when tags file has DOS-style
line terminators (CR/LF).
* Fixed compilation problem on OS/2.
======================================================================
Major changes between "less" versions 321 and 330
* Now supports filenames containing spaces (in double quotes).
New option -" can be used to change the quoting characters.
* In filename completion, a slash is appended to a directory name.
If the environment variable LESSSEPARATOR is set, the value of
that variable, rather than a slash, is appended.
* LeftArrow and RightArrow are same as ESC-[ and ESC-].
* Added commands ESC-( and ESC-), same as ESC-[ and ESC-].
* A "quit" command defined in a lesskey file may now have an "extra"
string, which is used to return an exit code from less when it quits.
* New environment variables LESSMETACHARS and LESSMETAESCAPE provide
more control over how less interfaces to the shell.
* Ported to Microsoft Visual C compiler for Windows.
* Ported to DJGPP compiler for MS-DOS.
* Bug fixes.
======================================================================
Major changes between "less" versions 291 and 321
* Command line at bottom of screen now scrolls, so it can be longer
than the screen width.
* New commands ESC-] and ESC-[ scroll the display horizontally.
* New command ESC-SPACE scrolls forward a full screen, even if it
hits end-of-file.
* Alternate modifiers for search commands: ^N is same as !,
^F is same as @, and ^E is same as *.
* New modifier for search commands: ^K means highlight the matches
currently on-screen, but don't move to the first match.
* New modifier for search commands: ^R means don't use regular
expressions in the search.
* Environment variable LESSKEY gives name of default lesskey file.
* Environment variable LESSSECURE will force less to run in
"secure" mode.
* Command line argument "--" signals that the rest of the arguments
are files (not option flags).
* Help file (less.hlp) is no longer installed. Help text is now
embedded in the less executable itself.
* Added -Ph to change the prompt for the help text.
Added -Ps to change the default short prompt (same as plain -P).
* Ported to the Borland C compiler for MS-DOS.
* Ported to Windows 95 & Windows NT.
* Ported to OS-9.
* Ported to GNU Hurd.
======================================================================
Major changes between "less" versions 290 and 291
* Less environment variables can be specified in lesskey files.
* Fixed MS-DOS build.
======================================================================
Major changes between "less" versions 278 and 290
* Accepts GNU-style options "--help" and "--version".
* OS/2 version looks for less.ini in $HOME before $INIT and $PATH.
* Bug fixes
======================================================================
Major changes between "less" versions 252 and 278
* A LESSOPEN preprocessor may now pipe the converted file data to less,
rather than writing it to a temporary file.
* Search pattern highlighting has been fixed. It now highlights
reliably, even if a string is split across two screen lines,
contains TABs, etc.
* The -F flag (which suppress search highlighting) has been changed
to -G. A new flag, -g, changes search highlighting to highlight
only the string found by the last search command, instead of all
strings which match the last search command.
* New flag -I acts like -i, but ignores case even if the search
pattern contains uppercase letters.
* Less now checks for the environment variable VISUAL before EDITOR.
* Ported to OS/2.
======================================================================
Major changes between "less" versions 237 and 252
* Changes in line-editing keys:
The literal key is now ^V or ^A rather than \ (backslash).
Filename completion commands (TAB and ^L) are disabled
when typing a search pattern.
* Line-editing command keys can be redefined using lesskey.
* Lesskey with no input file defaults to $HOME/.lesskey
rather than standard input.
* New option -V displays version number of less.
* New option -V displays version number of lesskey.
* Help file less.hlp is now installed by default in /usr/local/share
rather than /usr/local/lib.
======================================================================
Major changes between "less" versions 170 and 237
* By popular demand, text which matches the current search pattern
is highlighted. New -F flag disables this feature.
* Henry Spencer's regexp.c is now included, for systems which do not
have a regular expression library.
regexp.c is Copyright (c) 1986 by University of Toronto.
* New line-editing keys, including command history (arrow keys) and
filename completion (TAB).
* Input preprocessor allows modification of input files (e.g. uncompress)
via LESSOPEN/LESSCLOSE environment variables.
* New -X flag disables sending termcap "ti" and "te" (initialize and
deinitialize) strings to the terminal.
* Changing -i from within less now correctly affects a subsequent
repeated search.
* Searching for underlined or overstruck text now works when the -u
flag is in effect, rather than the -i flag.
* Use setlocale (LANG and LC_CTYPE environment variables) to determine
the character set if LESSCHARSET/LESSCHARDEF are not set.
* The default format for displaying binary characters is now standout
(reverse video) rather than blinking. This can still be changed by
setting the LESSBINFMT environment variable.
* Use autoconf installation technology.
* Ported to MS-DOS.
********************************
Things that may surprise you
********************************
* When you enter text at the bottom of the screen (search string,
filename, etc.), some keys act different than previously.
Specifically, \ (backslash), ESC, TAB, BACKTAB, and control-L
now have line editing functions.
* Some previous unofficial versions of less were able to display
compressed files. The new LESSOPEN/LESSCLOSE feature now provides
this functionality in a different way.
* Some previous unofficial versions of less provided a -Z flag to
set the number of lines of text to retain between full screen scrolls.
The -z-n flag (that is, -z with a negative number) provides this
functionality.
======================================================================
Major changes between "less" versions 123 and 170
* New option -j allows target lines to be positioned anywhere on screen.
* New option -S truncates displayed line at the screen width,
rather than wrapping onto the next line.
* New option -y limits amount of forward scroll.
* New option -T specifies a "tags" file.
* Non-printable, non-control characters are displayed in octal.
Such characters, as well as control characters, are displayed
in blinking mode.
* New command -+ sets an option to its default.
* New command -- sets an option to the opposite of its default.
* Lesskey file may have a string appended to a key's action,
which acts as though typed in after the command.
* New commands ESC-^F and ESC-^B match arbitrary types of brackets.
* New command F monitors a growing file (like "tail -f").
* New command | pipes a section of the input file into a shell command.
* New command :x directly jumps to a file in the command line list.
* Search commands have been enhanced and reorganized:
n Repeat search, same direction.
N Repeat search, opposite direction.
ESC-/ Search forward thru file boundaries
ESC-? Search backward thru file boundaries
ESC-n Repeat search thru file boundaries, same direction.
ESC-N Repeat search thru file boundaries, opposite direction.
Special character * causes search to search thru file boundaries.
Special character @ causes search to begin at start/end of file list.
* Examining a new file adds it to the command line list.
A list of files, or an expression which matches more than one file,
may be examined; all of them are added to the command line list.
* Environment variables LESSCHARSET and LESSCHARDEF can define
a non-ASCII character set.
* Partial support for MSDOS, including options -R for repainting screen
on quit, -v/-V to select video mode, and -W to change window size.
======================================================================
Major changes between "less" versions 97 and 123
* New option (-N) causes line numbers to be displayed in the
text of the file (like vi "set nu").
* New option (-?) prints help message immediately.
* New option (-r) displays "raw" control characters, without
mapping them to ^X notation.
* New option (-f) forces less to open non-regular files
(directories, etc).
* New option (-k) can be used to specify lesskey files by name.
* New option (-y) can be used to set a forward scroll limit
(like -h sets a backward scroll limit).
* File marks (set by the m command) are now preserved when a new
file is edited. The ' command can thus be used to switch files.
* New command ESC-/ searches all files (on the command line)
for a pattern.
* New command ESC-n repeats previous search, spanning files.
* The N command has been changed to repeat the previous search
in the reverse direction. The old N command is still available
via :n.
* New command ESC-N repeats previous search in the reverse
direction and spanning files.
* 8 bit characters are now supported. A new option (-g) can be
used to strip off the eighth bit (the previous behavior).
* Options which take a following string (like -t) may now
optionally have a space between the option letter and the string.
* Six new commands { } ( ) [ and ] can be used to match
brackets of specific types, similar to vi % command.
* New commands z and w move forward/backward one window and
simultaneously set the window size.
* Prompt string expansion now has %L for line number of the last
line in the file, and %E for the name of the editor.
Also, % escapes which refer to a line (b=bottom, t=top, etc.)
can use j for the jump target line.
* New environment variable LESSEDIT can be used to tailor the
command string passed to the editor by the v command.
* Examining a file which was previously examined will return
to the same position in the file.
* A "%" is expanded to the current filename and a "#" to the
previous filename, in both shell commands and the E command.
(Previously % worked only in shell commands and # worked
only in the E command.)
* New command ":ta" is equivalent to "-t".
* New command "s" is equivalent to "-l".
* The - command may be followed by "+X" to revert to the default
for option X, or "-X" to get the opposite of the default.
* Lesskey files may now include characters after the action as
extra input to be parsed after the action; for example:
"toggle-option X" to toggle a specific option X.

226
contrib/less/README Normal file
View File

@ -0,0 +1,226 @@
Less, version 354
This is the distribution of less, version 354, released 23 Mar 2000.
This program is part of the GNU project (http://www.gnu.org).
This program is free software. You may redistribute it and/or
modify it under the terms of either:
1. The GNU General Public License, as published by the Free
Software Foundation; either version 2, or (at your option) any
later version. A copy of this license is in the file COPYING.
or
2. The Less License, in the file LICENSE.
Please report any problems to bug-less@gnu.org or marknu@flash.net.
See http://www.flash.net/~marknu/less for the latest info.
You may also contact the author at:
Mark Nudelman
Greenwood Software
PO Box 2402
El Granada, CA 94018
USA
=========================================================================
This is the distribution of "less", a paginator similar to "more" or "pg".
The formatted manual page is in less.man.
The manual page nroff source is in less.nro.
Major changes made since the last posted version are in NEWS.
=======================================================================
INSTALLATION (Unix systems only):
1. Move the distributed source to its own directory and unpack it,
if you have not already done so.
2. Type "sh configure".
This will generate a Makefile and a defines.h.
Warning: if you have a GNU sed, make sure it is version 2.05 or later.
The file INSTALL describes the usage of the configure program in
general. In addition, these options to configure are supported:
--with-editor=program
Specifies the default editor program used by the "v" command.
The default is "vi".
--with-regex=lib
Specifies the regular expression library used by less for pattern
matching. The default is "auto", which means the configure program
finds a regular expression library automatically. Other values are:
posix Use the POSIX-compatible regcomp.
pcre Use the PCRE library.
regcmp Use the regcmp library.
re_comp Use the re_comp library.
regcomp Use the V8-compatible regcomp.
regcomp-local Use Henry Spencer's V8-compatible regcomp
(source is supplied with less).
3. It is a good idea to look over the generated Makefile and defines.h
and make sure they look ok. If you know of any peculiarities of
your system that configure might not have detected, you may fix the
Makefile now. Take particular notice of the list of "terminal"
libraries in the LIBS definition in the Makefile; these may need
to be edited. The terminal libraries will be some subset of
-lncurses -lcurses -ltermcap -ltermlib
If you wish, you may edit defines.h to remove some optional features.
If you wish to build a "secure" version of less (which disables all
features which might allow a user to do unintended things to the system
on which less is running), edit defines.h and define SECURE to 1.
If you choose not to include some features in your version, you may
wish to edit the manual page "less.nro" and the help page "less.hlp"
to remove the descriptions of the features which you are removing.
If you edit less.hlp, you should run "make -f Makefile.aut help.c".
4. Type "make" and watch the fun.
5. If the make succeeds, it will generate the programs "less",
"lesskey" and "lessecho" in your current directory. Test the
generated programs.
6. When satisfied that it works, if you wish to install it
in a public place, type "make install".
The default install destinations are:
Executables (less, lesskey, lessecho) in /usr/local/bin
Documentation (less.nro, lesskey.nro) in /usr/local/man/man1
If you want to install any of these files elsewhere, define
bindir and/or mandir to the appropriate directories.
If you have any problems building or running "less", suggestions,
complaints, etc., you may mail to the author at marknu@flash.net.
Note to hackers: comments noting possible improvements are enclosed
in double curly brackets {{ like this }}.
=======================================================================
INSTALLATION (MS-DOS systems only,
with Microsoft C, Borland C, or DJGPP)
1. Move the distributed source to its own directory.
Depending on your compiler, you may need to convert the source
to have CR-LF rather than LF as line terminators.
2. If you are using Microsoft C, rename MAKEFILE.DSM to MAKEFILE.
If you are using Borland C, rename MAKEFILE.DSB to MAKEFILE.
If you are using DJGPP, rename MAKEFILE.DSG to MAKEFILE.
3. Look at MAKEFILE to make sure that the definitions for CC and LIBDIR
are correct. CC should be the name of your C compiler and
LIBDIR should be the directory where the C libraries reside (for
Microsoft C only). If these definitions need to be changed, you can
either modify the definitions directly in MAKEFILE, or set your
environment variables CC and/or LIBDIR to override the definitions
in MAKEFILE.
4. If you wish, you may edit DEFINES.DS to remove some optional features.
If you choose not to include some features in your version, you may
wish to edit the manual page LESS.MAN and the help page HELP.C
to remove the descriptions of the features which you are removing.
5. Run your "make" program and watch the fun.
If your "make" requires a flag to import environment variables,
you should use that flag.
If your compiler runs out of memory, try running "make -n >cmds.bat"
and then run cmds.bat.
6. If the make succeeds, it will generate the programs "LESS.EXE" and
"LESSKEY.EXE" in your current directory. Test the generated programs.
7. When satisfied that it works, you may wish to install LESS.EXE and
LESSKEY.EXE in a directory which is included in your PATH.
=======================================================================
INSTALLATION (Windows-95, Windows-98 and Windows-NT systems only,
with Borland C or Microsoft Visual C++)
1. Move the distributed source to its own directory.
2. If you are using Borland C, rename Makefile.wnb to Makefile.
If you are using Microsoft Visual C++, rename Makefile.wnm to Makefile.
3. Check the Makefile to make sure the definitions look ok.
4. If you wish, you may edit defines.wn to remove some optional features.
If you choose not to include some features in your version, you may
wish to edit the manual page less.man and the help page help.c
to remove the descriptions of the features which you are removing.
5. Type "make" and watch the fun.
6. If the make succeeds, it will generate the programs "less.exe" and
"lesskey.exe" in your current directory. Test the generated programs.
7. When satisfied that it works, if you wish to install it
in a public place, type "make install".
See step 6 of the Unix installation instructions for details
on how to change the default installation directories.
=======================================================================
INSTALLATION (OS/2 systems only,
with EMX C)
1. Move the distributed source to its own directory.
2. Rename Makefile.o2e to Makefile.
3. Check the Makefile to make sure the definitions look ok.
4. If you wish, you may edit defines.o2 to remove some optional features.
If you choose not to include some features in your version, you may
wish to edit the manual page less.man and the help page help.c
to remove the descriptions of the features which you are removing.
5. Type "make" and watch the fun.
6. If the make succeeds, it will generate the programs "less.exe" and
"lesskey.exe" in your current directory. Test the generated programs.
7. Make sure you have the emx runtime installed. You need the emx DLLs
emx.dll and emxlibcs.dll and also the termcap database, termcap.dat.
Make sure you have termcap.dat either in the default location or
somewhere in a directory listed in the PATH or INIT environment
variables.
8. When satisfied that it works, you may wish to install less.exe and
lesskey.exe in a directory which is included in your PATH.
=======================================================================
INSTALLATION (OS-9 systems only,
with Microware C or Ultra C)
1. Move the distributed source to its own directory.
2. If you are using Microware C, rename Makefile.o9c to Makefile.
If you are using Ultra C, rename Makefile.o9u to Makefile.
3. Check the Makefile to make sure the definitions look ok.
4. If you wish, you may edit defines.o9 to remove some optional features.
If you choose not to include some features in your version, you may
wish to edit the manual page less.man and the help page help.c
to remove the descriptions of the features which you are removing.
5. Type "dmake" and watch the fun.
The standard OS-9 "make" will probably not work. If you don't
have dmake, you can get a copy from os9archive.rtsi.com.
6. If the make succeeds, it will generate the programs "less" and
"lesskey" in your current directory. Test the generated programs.
7. When satisfied that it works, if you wish to install it
in a public place, type "dmake install".
See step 6 of the Unix installation instructions for details
on how to change the default installation directories.

70
contrib/less/acconfig.h Normal file
View File

@ -0,0 +1,70 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Regular expression library.
* Define exactly one of the following to be 1:
* HAVE_POSIX_REGCOMP: POSIX regcomp() and regex.h
* HAVE_PCRE: PCRE (Perl-compatible regular expression) library
* HAVE_RE_COMP: BSD re_comp()
* HAVE_REGCMP: System V regcmp()
* HAVE_V8_REGCOMP: Henry Spencer V8 regcomp() and regexp.h
* NO_REGEX: pattern matching is supported, but without metacharacters.
*/
#undef HAVE_POSIX_REGCOMP
#undef HAVE_PCRE
#undef HAVE_RE_COMP
#undef HAVE_REGCMP
#undef HAVE_V8_REGCOMP
#undef NO_REGEX
#undef HAVE_REGEXEC2
/* Define HAVE_VOID if your compiler supports the "void" type. */
#undef HAVE_VOID
/* Define HAVE_CONST if your compiler supports the "const" modifier. */
#undef HAVE_CONST
/* Define HAVE_TIME_T if your system supports the "time_t" type. */
#undef HAVE_TIME_T
/* Define HAVE_STRERROR if you have the strerror() function. */
#undef HAVE_STRERROR
/* Define HAVE_FILENO if you have the fileno() macro. */
#undef HAVE_FILENO
/* Define HAVE_ERRNO if you have the errno variable */
/* Define MUST_DEFINE_ERRNO if you have errno but it is not define
* in errno.h */
#undef HAVE_ERRNO
#undef MUST_DEFINE_ERRNO
/* Define HAVE_SYS_ERRLIST if you have the sys_errlist[] variable */
#undef HAVE_SYS_ERRLIST
/* Define HAVE_OSPEED if your termcap library has the ospeed variable */
/* Define MUST_DEFINE_OSPEED if you have ospeed but it is not defined
* in termcap.h. */
#undef HAVE_OSPEED
#undef MUST_DEFINE_OSPEED
/* Define HAVE_LOCALE if you have locale.h and setlocale. */
#undef HAVE_LOCALE
/* Define HAVE_TERMIOS_FUNCS if you have tcgetattr/tcsetattr */
#undef HAVE_TERMIOS_FUNCS
/* Define HAVE_UPPER_LOWER if you have isupper, islower, toupper, tolower */
#undef HAVE_UPPER_LOWER
/* Define EDIT_PGM to your editor. */
#define EDIT_PGM "vi"

101
contrib/less/brac.c Normal file
View File

@ -0,0 +1,101 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Routines to perform bracket matching functions.
*/
#include "less.h"
#include "position.h"
/*
* Try to match the n-th open bracket
* which appears in the top displayed line (forwdir),
* or the n-th close bracket
* which appears in the bottom displayed line (!forwdir).
* The characters which serve as "open bracket" and
* "close bracket" are given.
*/
public void
match_brac(obrac, cbrac, forwdir, n)
register int obrac;
register int cbrac;
int forwdir;
int n;
{
register int c;
register int nest;
POSITION pos;
int (*chget)();
extern int ch_forw_get(), ch_back_get();
/*
* Seek to the line containing the open bracket.
* This is either the top or bottom line on the screen,
* depending on the type of bracket.
*/
pos = position((forwdir) ? TOP : BOTTOM);
if (pos == NULL_POSITION || ch_seek(pos))
{
if (forwdir)
error("Nothing in top line", NULL_PARG);
else
error("Nothing in bottom line", NULL_PARG);
return;
}
/*
* Look thru the line to find the open bracket to match.
*/
do
{
if ((c = ch_forw_get()) == '\n' || c == EOI)
{
if (forwdir)
error("No bracket in top line", NULL_PARG);
else
error("No bracket in bottom line", NULL_PARG);
return;
}
} while (c != obrac || --n > 0);
/*
* Position the file just "after" the open bracket
* (in the direction in which we will be searching).
* If searching forward, we are already after the bracket.
* If searching backward, skip back over the open bracket.
*/
if (!forwdir)
(void) ch_back_get();
/*
* Search the file for the matching bracket.
*/
chget = (forwdir) ? ch_forw_get : ch_back_get;
nest = 0;
while ((c = (*chget)()) != EOI)
{
if (c == obrac)
nest++;
else if (c == cbrac && --nest < 0)
{
/*
* Found the matching bracket.
* If searching backward, put it on the top line.
* If searching forward, put it on the bottom line.
*/
jump_line_loc(ch_tell(), forwdir ? -1 : 1);
return;
}
}
error("No matching bracket", NULL_PARG);
}

794
contrib/less/ch.c Normal file
View File

@ -0,0 +1,794 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Low level character input from the input file.
* We use these special purpose routines which optimize moving
* both forward and backward from the current read pointer.
*/
#include "less.h"
#if MSDOS_COMPILER==WIN32C
#include <errno.h>
#include <windows.h>
#endif
public int ignore_eoi;
/*
* Pool of buffers holding the most recently used blocks of the input file.
* The buffer pool is kept as a doubly-linked circular list,
* in order from most- to least-recently used.
* The circular list is anchored by the file state "thisfile".
*/
#define LBUFSIZE 1024
struct buf {
struct buf *next, *prev; /* Must be first to match struct filestate */
long block;
unsigned int datasize;
unsigned char data[LBUFSIZE];
};
/*
* The file state is maintained in a filestate structure.
* A pointer to the filestate is kept in the ifile structure.
*/
struct filestate {
/* -- Following members must match struct buf */
struct buf *buf_next, *buf_prev;
long buf_block;
/* -- End of struct buf copy */
int file;
int flags;
POSITION fpos;
int nbufs;
long block;
unsigned int offset;
POSITION fsize;
};
#define END_OF_CHAIN ((struct buf *)thisfile)
#define ch_bufhead thisfile->buf_next
#define ch_buftail thisfile->buf_prev
#define ch_nbufs thisfile->nbufs
#define ch_block thisfile->block
#define ch_offset thisfile->offset
#define ch_fpos thisfile->fpos
#define ch_fsize thisfile->fsize
#define ch_flags thisfile->flags
#define ch_file thisfile->file
static struct filestate *thisfile;
static int ch_ungotchar = -1;
extern int autobuf;
extern int sigs;
extern int cbufs;
extern int secure;
extern constant char helpdata[];
extern constant int size_helpdata;
extern IFILE curr_ifile;
#if LOGFILE
extern int logfile;
extern char *namelogfile;
#endif
static int ch_addbuf();
/*
* Get the character pointed to by the read pointer.
* ch_get() is a macro which is more efficient to call
* than fch_get (the function), in the usual case
* that the block desired is at the head of the chain.
*/
#define ch_get() ((ch_block == ch_bufhead->block && \
ch_offset < ch_bufhead->datasize) ? \
ch_bufhead->data[ch_offset] : fch_get())
int
fch_get()
{
register struct buf *bp;
register int n;
register int slept;
POSITION pos;
POSITION len;
slept = FALSE;
/*
* Look for a buffer holding the desired block.
*/
for (bp = ch_bufhead; bp != END_OF_CHAIN; bp = bp->next)
if (bp->block == ch_block)
{
if (ch_offset >= bp->datasize)
/*
* Need more data in this buffer.
*/
goto read_more;
goto found;
}
/*
* Block is not in a buffer.
* Take the least recently used buffer
* and read the desired block into it.
* If the LRU buffer has data in it,
* then maybe allocate a new buffer.
*/
if (ch_buftail == END_OF_CHAIN || ch_buftail->block != (long)(-1))
{
/*
* There is no empty buffer to use.
* Allocate a new buffer if:
* 1. We can't seek on this file and -b is not in effect; or
* 2. We haven't allocated the max buffers for this file yet.
*/
if ((autobuf && !(ch_flags & CH_CANSEEK)) ||
(cbufs == -1 || ch_nbufs < cbufs))
if (ch_addbuf())
/*
* Allocation failed: turn off autobuf.
*/
autobuf = OPT_OFF;
}
bp = ch_buftail;
bp->block = ch_block;
bp->datasize = 0;
read_more:
pos = (ch_block * LBUFSIZE) + bp->datasize;
if ((len = ch_length()) != NULL_POSITION && pos >= len)
/*
* At end of file.
*/
return (EOI);
if (pos != ch_fpos)
{
/*
* Not at the correct position: must seek.
* If input is a pipe, we're in trouble (can't seek on a pipe).
* Some data has been lost: just return "?".
*/
if (!(ch_flags & CH_CANSEEK))
return ('?');
if (lseek(ch_file, (off_t)pos, 0) == BAD_LSEEK)
{
error("seek error", NULL_PARG);
clear_eol();
return (EOI);
}
ch_fpos = pos;
}
/*
* Read the block.
* If we read less than a full block, that's ok.
* We use partial block and pick up the rest next time.
*/
if (ch_ungotchar != -1)
{
bp->data[bp->datasize] = ch_ungotchar;
n = 1;
ch_ungotchar = -1;
} else if (ch_flags & CH_HELPFILE)
{
bp->data[bp->datasize] = helpdata[ch_fpos];
n = 1;
} else
{
n = iread(ch_file, &bp->data[bp->datasize],
(unsigned int)(LBUFSIZE - bp->datasize));
}
if (n == READ_INTR)
return (EOI);
if (n < 0)
{
#if MSDOS_COMPILER==WIN32C
if (errno != EPIPE)
#endif
{
error("read error", NULL_PARG);
clear_eol();
}
n = 0;
}
#if LOGFILE
/*
* If we have a log file, write the new data to it.
*/
if (!secure && logfile >= 0 && n > 0)
write(logfile, (char *) &bp->data[bp->datasize], n);
#endif
ch_fpos += n;
bp->datasize += n;
/*
* If we have read to end of file, set ch_fsize to indicate
* the position of the end of file.
*/
if (n == 0)
{
ch_fsize = pos;
if (ignore_eoi)
{
/*
* We are ignoring EOF.
* Wait a while, then try again.
*/
if (!slept)
ierror("Waiting for data", NULL_PARG);
#if !MSDOS_COMPILER
sleep(1);
#else
#if MSDOS_COMPILER==WIN32C
Sleep(1000);
#endif
#endif
slept = TRUE;
}
if (sigs)
return (EOI);
}
found:
if (ch_bufhead != bp)
{
/*
* Move the buffer to the head of the buffer chain.
* This orders the buffer chain, most- to least-recently used.
*/
bp->next->prev = bp->prev;
bp->prev->next = bp->next;
bp->next = ch_bufhead;
bp->prev = END_OF_CHAIN;
ch_bufhead->prev = bp;
ch_bufhead = bp;
}
if (ch_offset >= bp->datasize)
/*
* After all that, we still don't have enough data.
* Go back and try again.
*/
goto read_more;
return (bp->data[ch_offset]);
}
/*
* ch_ungetchar is a rather kludgy and limited way to push
* a single char onto an input file descriptor.
*/
public void
ch_ungetchar(c)
int c;
{
if (c != -1 && ch_ungotchar != -1)
error("ch_ungetchar overrun", NULL_PARG);
ch_ungotchar = c;
}
#if LOGFILE
/*
* Close the logfile.
* If we haven't read all of standard input into it, do that now.
*/
public void
end_logfile()
{
static int tried = FALSE;
if (logfile < 0)
return;
if (!tried && ch_fsize == NULL_POSITION)
{
tried = TRUE;
ierror("Finishing logfile", NULL_PARG);
while (ch_forw_get() != EOI)
if (ABORT_SIGS())
break;
}
close(logfile);
logfile = -1;
namelogfile = NULL;
}
/*
* Start a log file AFTER less has already been running.
* Invoked from the - command; see toggle_option().
* Write all the existing buffered data to the log file.
*/
public void
sync_logfile()
{
register struct buf *bp;
int warned = FALSE;
long block;
long nblocks;
nblocks = (ch_fpos + LBUFSIZE - 1) / LBUFSIZE;
for (block = 0; block < nblocks; block++)
{
for (bp = ch_bufhead; ; bp = bp->next)
{
if (bp == END_OF_CHAIN)
{
if (!warned)
{
error("Warning: log file is incomplete",
NULL_PARG);
warned = TRUE;
}
break;
}
if (bp->block == block)
{
write(logfile, (char *) bp->data, bp->datasize);
break;
}
}
}
}
#endif
/*
* Determine if a specific block is currently in one of the buffers.
*/
static int
buffered(block)
long block;
{
register struct buf *bp;
for (bp = ch_bufhead; bp != END_OF_CHAIN; bp = bp->next)
if (bp->block == block)
return (TRUE);
return (FALSE);
}
/*
* Seek to a specified position in the file.
* Return 0 if successful, non-zero if can't seek there.
*/
public int
ch_seek(pos)
register POSITION pos;
{
long new_block;
POSITION len;
len = ch_length();
if (pos < ch_zero() || (len != NULL_POSITION && pos > len))
return (1);
new_block = pos / LBUFSIZE;
if (!(ch_flags & CH_CANSEEK) && pos != ch_fpos && !buffered(new_block))
{
if (ch_fpos > pos)
return (1);
while (ch_fpos < pos)
{
if (ch_forw_get() == EOI)
return (1);
if (ABORT_SIGS())
return (1);
}
return (0);
}
/*
* Set read pointer.
*/
ch_block = new_block;
ch_offset = pos % LBUFSIZE;
return (0);
}
/*
* Seek to the end of the file.
*/
public int
ch_end_seek()
{
POSITION len;
if (ch_flags & CH_CANSEEK)
ch_fsize = filesize(ch_file);
len = ch_length();
if (len != NULL_POSITION)
return (ch_seek(len));
/*
* Do it the slow way: read till end of data.
*/
while (ch_forw_get() != EOI)
if (ABORT_SIGS())
return (1);
return (0);
}
/*
* Seek to the beginning of the file, or as close to it as we can get.
* We may not be able to seek there if input is a pipe and the
* beginning of the pipe is no longer buffered.
*/
public int
ch_beg_seek()
{
register struct buf *bp, *firstbp;
/*
* Try a plain ch_seek first.
*/
if (ch_seek(ch_zero()) == 0)
return (0);
/*
* Can't get to position 0.
* Look thru the buffers for the one closest to position 0.
*/
firstbp = bp = ch_bufhead;
if (bp == END_OF_CHAIN)
return (1);
while ((bp = bp->next) != END_OF_CHAIN)
if (bp->block < firstbp->block)
firstbp = bp;
ch_block = firstbp->block;
ch_offset = 0;
return (0);
}
/*
* Return the length of the file, if known.
*/
public POSITION
ch_length()
{
if (ignore_eoi)
return (NULL_POSITION);
if (ch_flags & CH_HELPFILE)
return (size_helpdata);
return (ch_fsize);
}
/*
* Return the current position in the file.
*/
#define tellpos(blk,off) ((POSITION)((((long)(blk)) * LBUFSIZE) + (off)))
public POSITION
ch_tell()
{
return (tellpos(ch_block, ch_offset));
}
/*
* Get the current char and post-increment the read pointer.
*/
public int
ch_forw_get()
{
register int c;
c = ch_get();
if (c == EOI)
return (EOI);
if (ch_offset < LBUFSIZE-1)
ch_offset++;
else
{
ch_block ++;
ch_offset = 0;
}
return (c);
}
/*
* Pre-decrement the read pointer and get the new current char.
*/
public int
ch_back_get()
{
if (ch_offset > 0)
ch_offset --;
else
{
if (ch_block <= 0)
return (EOI);
if (!(ch_flags & CH_CANSEEK) && !buffered(ch_block-1))
return (EOI);
ch_block--;
ch_offset = LBUFSIZE-1;
}
return (ch_get());
}
/*
* Allocate buffers.
* Caller wants us to have a total of at least want_nbufs buffers.
*/
public int
ch_nbuf(want_nbufs)
int want_nbufs;
{
PARG parg;
while (ch_nbufs < want_nbufs)
{
if (ch_addbuf())
{
/*
* Cannot allocate enough buffers.
* If we don't have ANY, then quit.
* Otherwise, just report the error and return.
*/
parg.p_int = want_nbufs - ch_nbufs;
error("Cannot allocate %d buffers", &parg);
if (ch_nbufs == 0)
quit(QUIT_ERROR);
break;
}
}
return (ch_nbufs);
}
/*
* Flush (discard) any saved file state, including buffer contents.
*/
public void
ch_flush()
{
register struct buf *bp;
if (!(ch_flags & CH_CANSEEK))
{
/*
* If input is a pipe, we don't flush buffer contents,
* since the contents can't be recovered.
*/
ch_fsize = NULL_POSITION;
return;
}
/*
* Initialize all the buffers.
*/
for (bp = ch_bufhead; bp != END_OF_CHAIN; bp = bp->next)
bp->block = (long)(-1);
/*
* Figure out the size of the file, if we can.
*/
ch_fsize = filesize(ch_file);
/*
* Seek to a known position: the beginning of the file.
*/
ch_fpos = 0;
ch_block = 0; /* ch_fpos / LBUFSIZE; */
ch_offset = 0; /* ch_fpos % LBUFSIZE; */
#if 1
/*
* This is a kludge to workaround a Linux kernel bug: files in
* /proc have a size of 0 according to fstat() but have readable
* data. They are sometimes, but not always, seekable.
* Force them to be non-seekable here.
*/
if (ch_fsize == 0)
{
ch_fsize = NULL_POSITION;
ch_flags &= ~CH_CANSEEK;
}
#endif
if (lseek(ch_file, (off_t)0, 0) == BAD_LSEEK)
{
/*
* Warning only; even if the seek fails for some reason,
* there's a good chance we're at the beginning anyway.
* {{ I think this is bogus reasoning. }}
*/
error("seek error to 0", NULL_PARG);
}
}
/*
* Allocate a new buffer.
* The buffer is added to the tail of the buffer chain.
*/
static int
ch_addbuf()
{
register struct buf *bp;
/*
* Allocate and initialize a new buffer and link it
* onto the tail of the buffer list.
*/
bp = (struct buf *) calloc(1, sizeof(struct buf));
if (bp == NULL)
return (1);
ch_nbufs++;
bp->block = (long)(-1);
bp->next = END_OF_CHAIN;
bp->prev = ch_buftail;
ch_buftail->next = bp;
ch_buftail = bp;
return (0);
}
/*
* Delete all buffers for this file.
*/
static void
ch_delbufs()
{
register struct buf *bp;
while (ch_bufhead != END_OF_CHAIN)
{
bp = ch_bufhead;
bp->next->prev = bp->prev;;
bp->prev->next = bp->next;
free(bp);
}
ch_nbufs = 0;
}
/*
* Is it possible to seek on a file descriptor?
*/
public int
seekable(f)
int f;
{
#if MSDOS_COMPILER
extern int fd0;
if (f == fd0 && !isatty(fd0))
{
/*
* In MS-DOS, pipes are seekable. Check for
* standard input, and pretend it is not seekable.
*/
return (0);
}
#endif
return (lseek(f, (off_t)1, 0) != BAD_LSEEK);
}
/*
* Initialize file state for a new file.
*/
public void
ch_init(f, flags)
int f;
int flags;
{
/*
* See if we already have a filestate for this file.
*/
thisfile = (struct filestate *) get_filestate(curr_ifile);
if (thisfile == NULL)
{
/*
* Allocate and initialize a new filestate.
*/
thisfile = (struct filestate *)
calloc(1, sizeof(struct filestate));
thisfile->buf_next = thisfile->buf_prev = END_OF_CHAIN;
thisfile->buf_block = (long)(-1);
thisfile->nbufs = 0;
thisfile->flags = 0;
thisfile->fpos = 0;
thisfile->block = 0;
thisfile->offset = 0;
thisfile->file = -1;
thisfile->fsize = NULL_POSITION;
ch_flags = flags;
/*
* Try to seek; set CH_CANSEEK if it works.
*/
if ((flags & CH_CANSEEK) && !seekable(f))
ch_flags &= ~CH_CANSEEK;
set_filestate(curr_ifile, (void *) thisfile);
}
if (thisfile->file == -1)
thisfile->file = f;
ch_flush();
}
/*
* Close a filestate.
*/
public void
ch_close()
{
int keepstate = FALSE;
if (ch_flags & (CH_CANSEEK|CH_POPENED|CH_HELPFILE))
{
/*
* We can seek or re-open, so we don't need to keep buffers.
*/
ch_delbufs();
} else
keepstate = TRUE;
if (!(ch_flags & CH_KEEPOPEN))
{
/*
* We don't need to keep the file descriptor open
* (because we can re-open it.)
* But don't really close it if it was opened via popen(),
* because pclose() wants to close it.
*/
if (!(ch_flags & (CH_POPENED|CH_HELPFILE)))
close(ch_file);
ch_file = -1;
} else
keepstate = TRUE;
if (!keepstate)
{
/*
* We don't even need to keep the filestate structure.
*/
free(thisfile);
thisfile = NULL;
set_filestate(curr_ifile, (void *) NULL);
}
}
/*
* Return ch_flags for the current file.
*/
public int
ch_getflags()
{
return (ch_flags);
}
#if 0
public void
ch_dump(struct filestate *fs)
{
struct buf *bp;
unsigned char *s;
if (fs == NULL)
{
printf(" --no filestate\n");
return;
}
printf(" file %d, flags %x, fpos %x, fsize %x, blk/off %x/%x\n",
fs->file, fs->flags, fs->fpos,
fs->fsize, fs->block, fs->offset);
printf(" %d bufs:\n", fs->nbufs);
for (bp = fs->buf_next; bp != (struct buf *)fs; bp = bp->next)
{
printf("%x: blk %x, size %x \"",
bp, bp->block, bp->datasize);
for (s = bp->data; s < bp->data + 30; s++)
if (*s >= ' ' && *s < 0x7F)
printf("%c", *s);
else
printf(".");
printf("\"\n");
}
}
#endif

294
contrib/less/charset.c Normal file
View File

@ -0,0 +1,294 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Functions to define the character set
* and do things specific to the character set.
*/
#include "less.h"
#if HAVE_LOCALE
#include <locale.h>
#include <ctype.h>
#endif
public int utf_mode = 0;
/*
* Predefined character sets,
* selected by the LESSCHARSET environment variable.
*/
struct charset {
char *name;
int *p_flag;
char *desc;
} charsets[] = {
{ "ascii", NULL, "8bcccbcc18b95.b" },
{ "dos", NULL, "8bcccbcc12bc5b95.b." },
{ "ebcdic", NULL, "5bc6bcc7bcc41b.9b7.9b5.b..8b6.10b6.b9.7b9.8b8.17b3.3b9.7b9.8b8.6b10.b.b.b." },
{ "iso8859", NULL, "8bcccbcc18b95.33b." },
{ "koi8-r", NULL, "8bcccbcc18b95.b128." },
{ "latin1", NULL, "8bcccbcc18b95.33b." },
{ "next", NULL, "8bcccbcc18b95.bb125.bb" },
{ "utf-8", &utf_mode, "8bcccbcc18b." },
{ NULL, NULL, NULL }
};
#define IS_BINARY_CHAR 01
#define IS_CONTROL_CHAR 02
static char chardef[256];
static char *binfmt = NULL;
public int binattr = AT_STANDOUT;
/*
* Define a charset, given a description string.
* The string consists of 256 letters,
* one for each character in the charset.
* If the string is shorter than 256 letters, missing letters
* are taken to be identical to the last one.
* A decimal number followed by a letter is taken to be a
* repetition of the letter.
*
* Each letter is one of:
* . normal character
* b binary character
* c control character
*/
static void
ichardef(s)
char *s;
{
register char *cp;
register int n;
register char v;
n = 0;
v = 0;
cp = chardef;
while (*s != '\0')
{
switch (*s++)
{
case '.':
v = 0;
break;
case 'c':
v = IS_CONTROL_CHAR;
break;
case 'b':
v = IS_BINARY_CHAR|IS_CONTROL_CHAR;
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
n = (10 * n) + (s[-1] - '0');
continue;
default:
error("invalid chardef", NULL_PARG);
quit(QUIT_ERROR);
/*NOTREACHED*/
}
do
{
if (cp >= chardef + sizeof(chardef))
{
error("chardef longer than 256", NULL_PARG);
quit(QUIT_ERROR);
/*NOTREACHED*/
}
*cp++ = v;
} while (--n > 0);
n = 0;
}
while (cp < chardef + sizeof(chardef))
*cp++ = v;
}
/*
* Define a charset, given a charset name.
* The valid charset names are listed in the "charsets" array.
*/
static int
icharset(name)
register char *name;
{
register struct charset *p;
if (name == NULL || *name == '\0')
return (0);
for (p = charsets; p->name != NULL; p++)
{
if (strcmp(name, p->name) == 0)
{
ichardef(p->desc);
if (p->p_flag != NULL)
*(p->p_flag) = 1;
return (1);
}
}
error("invalid charset name", NULL_PARG);
quit(QUIT_ERROR);
/*NOTREACHED*/
}
#if HAVE_LOCALE
/*
* Define a charset, given a locale name.
*/
static void
ilocale()
{
register int c;
setlocale(LC_ALL, "");
for (c = 0; c < (int) sizeof(chardef); c++)
{
if (isprint(c))
chardef[c] = 0;
else if (iscntrl(c))
chardef[c] = IS_CONTROL_CHAR;
else
chardef[c] = IS_BINARY_CHAR|IS_CONTROL_CHAR;
}
}
#endif
/*
* Define the printing format for control chars.
*/
public void
setbinfmt(s)
char *s;
{
if (s == NULL || *s == '\0')
s = "*s<%X>";
/*
* Select the attributes if it starts with "*".
*/
if (*s == '*')
{
switch (s[1])
{
case 'd': binattr = AT_BOLD; break;
case 'k': binattr = AT_BLINK; break;
case 's': binattr = AT_STANDOUT; break;
case 'u': binattr = AT_UNDERLINE; break;
default: binattr = AT_NORMAL; break;
}
s += 2;
}
binfmt = s;
}
/*
* Initialize charset data structures.
*/
public void
init_charset()
{
register char *s;
s = lgetenv("LESSBINFMT");
setbinfmt(s);
/*
* See if environment variable LESSCHARSET is defined.
*/
s = lgetenv("LESSCHARSET");
if (icharset(s))
return;
/*
* LESSCHARSET is not defined: try LESSCHARDEF.
*/
s = lgetenv("LESSCHARDEF");
if (s != NULL && *s != '\0')
{
ichardef(s);
return;
}
#if HAVE_STRSTR
/*
* Check whether LC_ALL, LC_CTYPE or LANG look like UTF-8 is used.
*/
if ((s = lgetenv("LC_ALL")) != NULL ||
(s = lgetenv("LC_CTYPE")) != NULL ||
(s = lgetenv("LANG")) != NULL)
{
if (strstr(s, "UTF-8") != NULL || strstr(s, "utf-8") != NULL)
if (icharset("utf-8"))
return;
}
#endif
#if HAVE_LOCALE
/*
* Use setlocale.
*/
ilocale();
#else
/*
* Default to "latin1".
*/
(void) icharset("latin1");
#endif
}
/*
* Is a given character a "binary" character?
*/
public int
binary_char(c)
unsigned char c;
{
c &= 0377;
return (chardef[c] & IS_BINARY_CHAR);
}
/*
* Is a given character a "control" character?
*/
public int
control_char(c)
int c;
{
c &= 0377;
return (chardef[c] & IS_CONTROL_CHAR);
}
/*
* Return the printable form of a character.
* For example, in the "ascii" charset '\3' is printed as "^C".
*/
public char *
prchar(c)
int c;
{
static char buf[8];
c &= 0377;
if (!control_char(c))
sprintf(buf, "%c", c);
else if (c == ESC)
sprintf(buf, "ESC");
else if (c < 128 && !control_char(c ^ 0100))
sprintf(buf, "^%c", c ^ 0100);
else
sprintf(buf, binfmt, c);
return (buf);
}

128
contrib/less/cmd.h Normal file
View File

@ -0,0 +1,128 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
#define MAX_USERCMD 500
#define MAX_CMDLEN 16
#define A_B_LINE 2
#define A_B_SCREEN 3
#define A_B_SCROLL 4
#define A_B_SEARCH 5
#define A_DIGIT 6
#define A_DISP_OPTION 7
#define A_DEBUG 8
#define A_EXAMINE 9
#define A_FIRSTCMD 10
#define A_FREPAINT 11
#define A_F_LINE 12
#define A_F_SCREEN 13
#define A_F_SCROLL 14
#define A_F_SEARCH 15
#define A_GOEND 16
#define A_GOLINE 17
#define A_GOMARK 18
#define A_HELP 19
#define A_NEXT_FILE 20
#define A_PERCENT 21
#define A_PREFIX 22
#define A_PREV_FILE 23
#define A_QUIT 24
#define A_REPAINT 25
#define A_SETMARK 26
#define A_SHELL 27
#define A_STAT 28
#define A_FF_LINE 29
#define A_BF_LINE 30
#define A_VERSION 31
#define A_VISUAL 32
#define A_F_WINDOW 33
#define A_B_WINDOW 34
#define A_F_BRACKET 35
#define A_B_BRACKET 36
#define A_PIPE 37
#define A_INDEX_FILE 38
#define A_UNDO_SEARCH 39
#define A_FF_SCREEN 40
#define A_LSHIFT 41
#define A_RSHIFT 42
#define A_AGAIN_SEARCH 43
#define A_T_AGAIN_SEARCH 44
#define A_REVERSE_SEARCH 45
#define A_T_REVERSE_SEARCH 46
#define A_OPT_TOGGLE 47
#define A_OPT_SET 48
#define A_OPT_UNSET 49
#define A_F_FOREVER 50
#define A_GOPOS 51
#define A_REMOVE_FILE 52
#define A_INVALID 100
#define A_NOACTION 101
#define A_UINVALID 102
#define A_END_LIST 103
#define A_SPECIAL_KEY 104
#define A_SKIP 127
#define A_EXTRA 0200
/* Line editting characters */
#define EC_BACKSPACE 1
#define EC_LINEKILL 2
#define EC_RIGHT 3
#define EC_LEFT 4
#define EC_W_LEFT 5
#define EC_W_RIGHT 6
#define EC_INSERT 7
#define EC_DELETE 8
#define EC_HOME 9
#define EC_END 10
#define EC_W_BACKSPACE 11
#define EC_W_DELETE 12
#define EC_UP 13
#define EC_DOWN 14
#define EC_EXPAND 15
#define EC_F_COMPLETE 17
#define EC_B_COMPLETE 18
#define EC_LITERAL 19
#define EC_NOACTION 101
#define EC_UINVALID 102
/* Flags for editchar() */
#define EC_PEEK 01
#define EC_NOHISTORY 02
#define EC_NOCOMPLETE 04
/* Environment variable stuff */
#define EV_OK 01
/* Special keys (keys which output different strings on different terminals) */
#define SK_SPECIAL_KEY CONTROL('K')
#define SK_RIGHT_ARROW 1
#define SK_LEFT_ARROW 2
#define SK_UP_ARROW 3
#define SK_DOWN_ARROW 4
#define SK_PAGE_UP 5
#define SK_PAGE_DOWN 6
#define SK_HOME 7
#define SK_END 8
#define SK_DELETE 9
#define SK_INSERT 10
#define SK_CTL_LEFT_ARROW 11
#define SK_CTL_RIGHT_ARROW 12
#define SK_CTL_DELETE 13
#define SK_F1 14
#define SK_BACKTAB 15
#define SK_CTL_BACKSPACE 16
#define SK_CONTROL_K 40

1022
contrib/less/cmdbuf.c Normal file

File diff suppressed because it is too large Load Diff

1543
contrib/less/command.c Normal file

File diff suppressed because it is too large Load Diff

2737
contrib/less/configure vendored Executable file

File diff suppressed because it is too large Load Diff

302
contrib/less/configure.in Normal file
View File

@ -0,0 +1,302 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(forwback.c)
AC_CONFIG_HEADER(defines.h)
dnl Checks for programs.
AC_PROG_CC
AC_ISC_POSIX
AC_PROG_GCC_TRADITIONAL
AC_PROG_INSTALL
dnl Checks for libraries.
AC_CHECK_LIB(xcurses, initscr, [have_xcurses=yes], [have_xcurses=no])
AC_CHECK_LIB(ncurses, initscr, [have_ncurses=yes], [have_ncurses=no])
AC_CHECK_LIB(curses, initscr, [have_curses=yes], [have_curses=no])
AC_CHECK_LIB(termcap, tgetent, [have_termcap=yes], [have_termcap=no])
AC_CHECK_LIB(termlib, tgetent, [have_termlib=yes], [have_termlib=no])
dnl Regular expressions (regcmp) are in -lgen on Solaris 2,
dnl and in -lintl on SCO Unix.
AC_CHECK_LIB(gen, regcmp)
AC_CHECK_LIB(intl, regcmp)
AC_CHECK_LIB(PW, regcmp)
dnl Checks for terminal libraries
AC_MSG_CHECKING(for working terminal libraries)
TERMLIBS=
dnl Check for systems where curses is broken.
curses_broken=0
if test x`uname -s` = "xHP-UX" >/dev/null 2>&1; then
if test x`uname -r` = "xB.11.00" >/dev/null 2>&1; then
curses_broken=1
fi
fi
if test $curses_broken = 0; then
dnl -- Try xcurses.
if test "x$TERMLIBS" = x; then
if test $have_xcurses = yes; then
TERMLIBS="-lxcurses"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
AC_TRY_LINK(, [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
[termok=yes], [termok=no])
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
fi
fi
dnl -- Try ncurses.
if test "x$TERMLIBS" = x; then
if test $have_ncurses = yes; then
TERMLIBS="-lncurses"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
AC_TRY_LINK(, [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
[termok=yes], [termok=no])
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
fi
fi
dnl -- Try curses.
if test "x$TERMLIBS" = x; then
if test $have_curses = yes; then
TERMLIBS="-lcurses"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
AC_TRY_LINK(, [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
[termok=yes], [termok=no])
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
fi
fi
dnl -- Try curses & termcap.
if test "x$TERMLIBS" = x; then
if test $have_curses = yes; then
if test $have_termcap = yes; then
TERMLIBS="-lcurses -ltermcap"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
AC_TRY_LINK(, [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
[termok=yes], [termok=no])
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
fi
fi
fi
fi
dnl -- Try termcap.
if test "x$TERMLIBS" = x; then
if test $have_termcap = yes; then
TERMLIBS="-ltermcap"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
AC_TRY_LINK(, [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
[termok=yes], [termok=no])
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
fi
fi
dnl -- Try termlib.
if test "x$TERMLIBS" = x; then
if test $have_termlib = yes; then
TERMLIBS="-lcurses -ltermlib"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
AC_TRY_LINK(, [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
[termok=yes], [termok=no])
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
fi
fi
if test "x$TERMLIBS" = x; then
AC_MSG_RESULT(Cannot find terminal libraries - configure failed)
exit 1
fi
AC_MSG_RESULT(using $TERMLIBS)
LIBS="$LIBS $TERMLIBS"
dnl Checks for header files.
AC_CHECK_HEADERS(ctype.h errno.h fcntl.h limits.h stdio.h stdlib.h string.h termcap.h termio.h termios.h time.h unistd.h values.h sys/ioctl.h sys/stream.h sys/ptem.h)
dnl Checks for identifiers.
AC_TYPE_OFF_T
AC_MSG_CHECKING(for void)
AC_TRY_COMPILE(, [void *foo = 0;],
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_VOID)], [AC_MSG_RESULT(no)])
AC_MSG_CHECKING(for const)
AC_TRY_COMPILE(, [const int foo = 0;],
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_CONST)], [AC_MSG_RESULT(no)])
AC_MSG_CHECKING(for time_t)
AC_TRY_COMPILE([#include <time.h>], [time_t t = 0;],
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_TIME_T)], [AC_MSG_RESULT(no)])
dnl Checks for functions and external variables.
AC_TYPE_SIGNAL
AC_CHECK_FUNCS(memcpy popen _setjmp sigsetmask stat strchr strstr system)
dnl Some systems have termios.h but not the corresponding functions.
AC_CHECK_FUNC(tcgetattr, AC_DEFINE(HAVE_TERMIOS_FUNCS))
AC_MSG_CHECKING(for fileno)
AC_TRY_LINK([
#if HAVE_STDIO_H
#include <stdio.h>
#endif], [static int x; x = fileno(stdin);],
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_FILENO)], [AC_MSG_RESULT(no)])
AC_MSG_CHECKING(for strerror)
AC_TRY_LINK([
#if HAVE_STDIO_H
#include <stdio.h>
#endif
#if HAVE_STRING_H
#include <string.h>
#endif
#if HAVE_ERRNO_H
#include <errno.h>
#endif], [static char *x; x = strerror(0);],
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_STRERROR)], [AC_MSG_RESULT(no)])
AC_MSG_CHECKING(for sys_errlist)
AC_TRY_LINK(, [extern char *sys_errlist[]; static char **x; x = sys_errlist;],
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_SYS_ERRLIST)], [AC_MSG_RESULT(no)])
have_errno=no
AC_MSG_CHECKING(for errno)
AC_TRY_LINK([
#if HAVE_ERRNO_H
#include <errno.h>
#endif], [static int x; x = errno;],
[AC_MSG_RESULT(yes - in errno.h); AC_DEFINE(HAVE_ERRNO) have_errno=yes])
if test $have_errno = no; then
AC_TRY_LINK([
#if HAVE_ERRNO_H
#include <errno.h>
#endif], [extern int errno; static int x; x = errno;],
[AC_MSG_RESULT(yes - must define); AC_DEFINE(HAVE_ERRNO) AC_DEFINE(MUST_DEFINE_ERRNO)],
[AC_MSG_RESULT(no)])
fi
AC_MSG_CHECKING(for locale)
AC_TRY_LINK([#include <locale.h>
#include <ctype.h>], [setlocale(LC_CTYPE,""); isprint(0); iscntrl(0);],
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_LOCALE)], [AC_MSG_RESULT(no)])
AC_MSG_CHECKING(for ctype functions)
AC_TRY_LINK([
#if HAVE_CTYPE_H
#include <ctype.h>
#endif], [static int x; x = isupper(x); x = tolower(x); x = toupper(x);],
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_UPPER_LOWER)], [AC_MSG_RESULT(no)])
dnl Checks for external variable ospeed in the termcap library.
have_ospeed=no
AC_MSG_CHECKING(termcap for ospeed)
AC_TRY_LINK([
#include <sys/types.h>
#if HAVE_TERMIOS_H
#include <termios.h>
#endif
#if HAVE_TERMCAP_H
#include <termcap.h>
#endif], [ospeed = 0;],
[AC_MSG_RESULT(yes - in termcap.h); AC_DEFINE(HAVE_OSPEED) have_ospeed=yes])
if test $have_ospeed = no; then
AC_TRY_LINK(, [extern short ospeed; ospeed = 0;],
[AC_MSG_RESULT(yes - must define); AC_DEFINE(HAVE_OSPEED) AC_DEFINE(MUST_DEFINE_OSPEED)],
[AC_MSG_RESULT(no)])
fi
dnl Checks for regular expression functions.
have_regex=no
have_posix_regex=unknown
AC_MSG_CHECKING(for regcomp)
WANT_REGEX=auto
AC_ARG_WITH(regex,
[ --with-regex={auto,pcre,posix,regcmp,re_comp,regcomp,regcomp-local} Select a regular expression library [auto]],
WANT_REGEX="$withval")
if test $have_regex = no; then
if test $WANT_REGEX = auto -o $WANT_REGEX = posix; then
dnl Some versions of Solaris have a regcomp() function, but it doesn't work!
dnl So we run a test program. If we're cross-compiling, do it the old way.
AC_TRY_RUN([
#include <sys/types.h>
#include <regex.h>
main() { regex_t r; regmatch_t rm; char *text = "xabcy";
if (regcomp(&r, "abc", 0)) exit(1);
if (regexec(&r, text, 1, &rm, 0)) exit(1);
#ifndef __WATCOMC__
if (rm.rm_so != 1) exit(1); /* check for correct offset */
#else
if (rm.rm_sp != text + 1) exit(1); /* check for correct offset */
#endif
exit(0); }],
have_posix_regex=yes, have_posix_regex=no, have_posix_regex=unknown)
if test $have_posix_regex = yes; then
AC_MSG_RESULT(using POSIX regcomp)
AC_DEFINE(HAVE_POSIX_REGCOMP)
have_regex=yes
elif test $have_posix_regex = unknown; then
AC_TRY_LINK([
#include <sys/types.h>
#include <regex.h>],
[regex_t *r; regfree(r);],
AC_MSG_RESULT(using POSIX regcomp)
AC_DEFINE(HAVE_POSIX_REGCOMP) have_regex=yes)
else
AC_MSG_RESULT(no)
fi
fi
fi
if test $have_regex = no; then
if test $WANT_REGEX = auto -o $WANT_REGEX = pcre; then
AC_CHECK_LIB(pcre, pcre_compile,
[AC_MSG_RESULT(using pcre); AC_DEFINE(HAVE_PCRE) LIBS="$LIBS -lpcre" have_regex=yes], [])
fi
fi
if test $have_regex = no; then
if test $WANT_REGEX = auto -o $WANT_REGEX = regcmp; then
AC_CHECK_FUNC(regcmp,
AC_MSG_RESULT(using regcmp); AC_DEFINE(HAVE_REGCMP) have_regex=yes)
fi
fi
if test $have_regex = no; then
if test $WANT_REGEX = auto -o $WANT_REGEX = regcomp; then
AC_TRY_LINK([
#include "regexp.h"], [regcomp("");],
AC_MSG_RESULT(using V8 regcomp); AC_DEFINE(HAVE_V8_REGCOMP) have_regex=yes)
fi
fi
if test $have_regex = no && test -f ${srcdir}/regexp.c; then
if test $WANT_REGEX = auto -o $WANT_REGEX = regcomp-local; then
AC_MSG_RESULT(using V8 regcomp -- local source); AC_DEFINE(HAVE_V8_REGCOMP) AC_DEFINE(HAVE_REGEXEC2) REGEX_O='regexp.$(O)' AC_SUBST(REGEX_O) have_regex=yes
fi
fi
if test $have_regex = no; then
if test $WANT_REGEX = auto -o $WANT_REGEX = re_comp; then
AC_MSG_RESULT(using re_comp); AC_CHECK_FUNC(re_comp, AC_DEFINE(HAVE_RE_COMP) have_regex=yes)
fi
fi
if test $have_regex = no; then
AC_MSG_RESULT(cannot find regular expression library); AC_DEFINE(NO_REGEX)
fi
AC_ARG_WITH(editor,
[ --with-editor=PROGRAM use PROGRAM as the default editor [vi]],
AC_DEFINE_UNQUOTED(EDIT_PGM, "$withval"))
AC_OUTPUT(Makefile)

817
contrib/less/decode.c Normal file
View File

@ -0,0 +1,817 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Routines to decode user commands.
*
* This is all table driven.
* A command table is a sequence of command descriptors.
* Each command descriptor is a sequence of bytes with the following format:
* <c1><c2>...<cN><0><action>
* The characters c1,c2,...,cN are the command string; that is,
* the characters which the user must type.
* It is terminated by a null <0> byte.
* The byte after the null byte is the action code associated
* with the command string.
* If an action byte is OR-ed with A_EXTRA, this indicates
* that the option byte is followed by an extra string.
*
* There may be many command tables.
* The first (default) table is built-in.
* Other tables are read in from "lesskey" files.
* All the tables are linked together and are searched in order.
*/
#include "less.h"
#include "cmd.h"
#include "lesskey.h"
extern int erase_char, kill_char;
extern int secure;
#define SK(k) \
SK_SPECIAL_KEY, (k), 6, 1, 1, 1
/*
* Command table is ordered roughly according to expected
* frequency of use, so the common commands are near the beginning.
*/
static unsigned char cmdtable[] =
{
'\r',0, A_F_LINE,
'\n',0, A_F_LINE,
'e',0, A_F_LINE,
'j',0, A_F_LINE,
SK(SK_DOWN_ARROW),0, A_F_LINE,
CONTROL('E'),0, A_F_LINE,
CONTROL('N'),0, A_F_LINE,
'k',0, A_B_LINE,
'y',0, A_B_LINE,
CONTROL('Y'),0, A_B_LINE,
SK(SK_CONTROL_K),0, A_B_LINE,
CONTROL('P'),0, A_B_LINE,
SK(SK_UP_ARROW),0, A_B_LINE,
'J',0, A_FF_LINE,
'K',0, A_BF_LINE,
'Y',0, A_BF_LINE,
'd',0, A_F_SCROLL,
CONTROL('D'),0, A_F_SCROLL,
'u',0, A_B_SCROLL,
CONTROL('U'),0, A_B_SCROLL,
' ',0, A_F_SCREEN,
'f',0, A_F_SCREEN,
CONTROL('F'),0, A_F_SCREEN,
CONTROL('V'),0, A_F_SCREEN,
SK(SK_PAGE_DOWN),0, A_F_SCREEN,
'b',0, A_B_SCREEN,
CONTROL('B'),0, A_B_SCREEN,
ESC,'v',0, A_B_SCREEN,
SK(SK_PAGE_UP),0, A_B_SCREEN,
'z',0, A_F_WINDOW,
'w',0, A_B_WINDOW,
ESC,' ',0, A_FF_SCREEN,
'F',0, A_F_FOREVER,
'R',0, A_FREPAINT,
'r',0, A_REPAINT,
CONTROL('R'),0, A_REPAINT,
CONTROL('L'),0, A_REPAINT,
ESC,'u',0, A_UNDO_SEARCH,
'g',0, A_GOLINE,
SK(SK_HOME),0, A_GOLINE,
'<',0, A_GOLINE,
ESC,'<',0, A_GOLINE,
'p',0, A_PERCENT,
'%',0, A_PERCENT,
ESC,'[',0, A_LSHIFT,
ESC,']',0, A_RSHIFT,
ESC,'(',0, A_LSHIFT,
ESC,')',0, A_RSHIFT,
SK(SK_RIGHT_ARROW),0, A_RSHIFT,
SK(SK_LEFT_ARROW),0, A_LSHIFT,
'{',0, A_F_BRACKET|A_EXTRA, '{','}',0,
'}',0, A_B_BRACKET|A_EXTRA, '{','}',0,
'(',0, A_F_BRACKET|A_EXTRA, '(',')',0,
')',0, A_B_BRACKET|A_EXTRA, '(',')',0,
'[',0, A_F_BRACKET|A_EXTRA, '[',']',0,
']',0, A_B_BRACKET|A_EXTRA, '[',']',0,
ESC,CONTROL('F'),0, A_F_BRACKET,
ESC,CONTROL('B'),0, A_B_BRACKET,
'G',0, A_GOEND,
ESC,'>',0, A_GOEND,
'>',0, A_GOEND,
SK(SK_END),0, A_GOEND,
'P',0, A_GOPOS,
'0',0, A_DIGIT,
'1',0, A_DIGIT,
'2',0, A_DIGIT,
'3',0, A_DIGIT,
'4',0, A_DIGIT,
'5',0, A_DIGIT,
'6',0, A_DIGIT,
'7',0, A_DIGIT,
'8',0, A_DIGIT,
'9',0, A_DIGIT,
'=',0, A_STAT,
CONTROL('G'),0, A_STAT,
':','f',0, A_STAT,
'/',0, A_F_SEARCH,
'?',0, A_B_SEARCH,
ESC,'/',0, A_F_SEARCH|A_EXTRA, '*',0,
ESC,'?',0, A_B_SEARCH|A_EXTRA, '*',0,
'n',0, A_AGAIN_SEARCH,
ESC,'n',0, A_T_AGAIN_SEARCH,
'N',0, A_REVERSE_SEARCH,
ESC,'N',0, A_T_REVERSE_SEARCH,
'm',0, A_SETMARK,
'\'',0, A_GOMARK,
CONTROL('X'),CONTROL('X'),0, A_GOMARK,
'E',0, A_EXAMINE,
':','e',0, A_EXAMINE,
CONTROL('X'),CONTROL('V'),0, A_EXAMINE,
':','n',0, A_NEXT_FILE,
':','p',0, A_PREV_FILE,
':','x',0, A_INDEX_FILE,
':','d',0, A_REMOVE_FILE,
'-',0, A_OPT_TOGGLE,
':','t',0, A_OPT_TOGGLE|A_EXTRA, 't',0,
's',0, A_OPT_TOGGLE|A_EXTRA, 'o',0,
'_',0, A_DISP_OPTION,
'|',0, A_PIPE,
'v',0, A_VISUAL,
'!',0, A_SHELL,
'+',0, A_FIRSTCMD,
'H',0, A_HELP,
'h',0, A_HELP,
SK(SK_F1),0, A_HELP,
'V',0, A_VERSION,
'q',0, A_QUIT,
'Q',0, A_QUIT,
':','q',0, A_QUIT,
':','Q',0, A_QUIT,
'Z','Z',0, A_QUIT
};
static unsigned char edittable[] =
{
'\t',0, EC_F_COMPLETE, /* TAB */
'\17',0, EC_B_COMPLETE, /* BACKTAB */
SK(SK_BACKTAB),0, EC_B_COMPLETE, /* BACKTAB */
ESC,'\t',0, EC_B_COMPLETE, /* ESC TAB */
CONTROL('L'),0, EC_EXPAND, /* CTRL-L */
CONTROL('V'),0, EC_LITERAL, /* BACKSLASH */
CONTROL('A'),0, EC_LITERAL, /* BACKSLASH */
ESC,'l',0, EC_RIGHT, /* ESC l */
SK(SK_RIGHT_ARROW),0, EC_RIGHT, /* RIGHTARROW */
ESC,'h',0, EC_LEFT, /* ESC h */
SK(SK_LEFT_ARROW),0, EC_LEFT, /* LEFTARROW */
ESC,'b',0, EC_W_LEFT, /* ESC b */
ESC,SK(SK_LEFT_ARROW),0, EC_W_LEFT, /* ESC LEFTARROW */
SK(SK_CTL_LEFT_ARROW),0, EC_W_LEFT, /* CTRL-LEFTARROW */
ESC,'w',0, EC_W_RIGHT, /* ESC w */
ESC,SK(SK_RIGHT_ARROW),0, EC_W_RIGHT, /* ESC RIGHTARROW */
SK(SK_CTL_RIGHT_ARROW),0, EC_W_RIGHT, /* CTRL-RIGHTARROW */
ESC,'i',0, EC_INSERT, /* ESC i */
SK(SK_INSERT),0, EC_INSERT, /* INSERT */
ESC,'x',0, EC_DELETE, /* ESC x */
SK(SK_DELETE),0, EC_DELETE, /* DELETE */
ESC,'X',0, EC_W_DELETE, /* ESC X */
ESC,SK(SK_DELETE),0, EC_W_DELETE, /* ESC DELETE */
SK(SK_CTL_DELETE),0, EC_W_DELETE, /* CTRL-DELETE */
SK(SK_CTL_BACKSPACE),0, EC_W_BACKSPACE, /* CTRL-BACKSPACE */
ESC,'\b',0, EC_W_BACKSPACE, /* ESC BACKSPACE */
ESC,'0',0, EC_HOME, /* ESC 0 */
SK(SK_HOME),0, EC_HOME, /* HOME */
ESC,'$',0, EC_END, /* ESC $ */
SK(SK_END),0, EC_END, /* END */
ESC,'k',0, EC_UP, /* ESC k */
SK(SK_UP_ARROW),0, EC_UP, /* UPARROW */
ESC,'j',0, EC_DOWN, /* ESC j */
SK(SK_DOWN_ARROW),0, EC_DOWN, /* DOWNARROW */
};
/*
* Structure to support a list of command tables.
*/
struct tablelist
{
struct tablelist *t_next;
char *t_start;
char *t_end;
};
/*
* List of command tables and list of line-edit tables.
*/
static struct tablelist *list_fcmd_tables = NULL;
static struct tablelist *list_ecmd_tables = NULL;
static struct tablelist *list_var_tables = NULL;
static struct tablelist *list_sysvar_tables = NULL;
/*
* Expand special key abbreviations in a command table.
*/
static void
expand_special_keys(table, len)
char *table;
int len;
{
register char *fm;
register char *to;
register int a;
char *repl;
int klen;
for (fm = table; fm < table + len; )
{
/*
* Rewrite each command in the table with any
* special key abbreviations expanded.
*/
for (to = fm; *fm != '\0'; )
{
if (*fm != SK_SPECIAL_KEY)
{
*to++ = *fm++;
continue;
}
/*
* After SK_SPECIAL_KEY, next byte is the type
* of special key (one of the SK_* contants),
* and the byte after that is the number of bytes,
* N, reserved by the abbreviation (including the
* SK_SPECIAL_KEY and key type bytes).
* Replace all N bytes with the actual bytes
* output by the special key on this terminal.
*/
repl = special_key_str(fm[1]);
klen = fm[2] & 0377;
fm += klen;
if (repl == NULL || strlen(repl) > klen)
repl = "\377";
while (*repl != '\0')
*to++ = *repl++;
}
*to++ = '\0';
/*
* Fill any unused bytes between end of command and
* the action byte with A_SKIP.
*/
while (to <= fm)
*to++ = A_SKIP;
fm++;
a = *fm++ & 0377;
if (a & A_EXTRA)
{
while (*fm++ != '\0')
continue;
}
}
}
/*
* Initialize the command lists.
*/
public void
init_cmds()
{
/*
* Add the default command tables.
*/
add_fcmd_table((char*)cmdtable, sizeof(cmdtable));
add_ecmd_table((char*)edittable, sizeof(edittable));
#if USERFILE
/*
* Try to add the tables in the system lesskey file.
*/
add_hometable("LESSKEY_SYSTEM", LESSKEYFILE_SYS, 1);
/*
* Try to add the tables in the standard lesskey file "$HOME/.less".
*/
add_hometable("LESSKEY", LESSKEYFILE, 0);
#endif
}
/*
* Add a command table.
*/
static int
add_cmd_table(tlist, buf, len)
struct tablelist **tlist;
char *buf;
int len;
{
register struct tablelist *t;
if (len == 0)
return (0);
/*
* Allocate a tablelist structure, initialize it,
* and link it into the list of tables.
*/
if ((t = (struct tablelist *)
calloc(1, sizeof(struct tablelist))) == NULL)
{
return (-1);
}
expand_special_keys(buf, len);
t->t_start = buf;
t->t_end = buf + len;
t->t_next = *tlist;
*tlist = t;
return (0);
}
/*
* Add a command table.
*/
public void
add_fcmd_table(buf, len)
char *buf;
int len;
{
if (add_cmd_table(&list_fcmd_tables, buf, len) < 0)
error("Warning: some commands disabled", NULL_PARG);
}
/*
* Add an editing command table.
*/
public void
add_ecmd_table(buf, len)
char *buf;
int len;
{
if (add_cmd_table(&list_ecmd_tables, buf, len) < 0)
error("Warning: some edit commands disabled", NULL_PARG);
}
/*
* Add an environment variable table.
*/
static void
add_var_table(tlist, buf, len)
struct tablelist **tlist;
char *buf;
int len;
{
if (add_cmd_table(tlist, buf, len) < 0)
error("Warning: environment variables from lesskey file unavailable", NULL_PARG);
}
/*
* Search a single command table for the command string in cmd.
*/
public int
cmd_search(cmd, table, endtable, sp)
char *cmd;
char *table;
char *endtable;
char **sp;
{
register char *p;
register char *q;
register int a;
for (p = table, q = cmd; p < endtable; p++, q++)
{
if (*p == *q)
{
/*
* Current characters match.
* If we're at the end of the string, we've found it.
* Return the action code, which is the character
* after the null at the end of the string
* in the command table.
*/
if (*p == '\0')
{
a = *++p & 0377;
while (a == A_SKIP)
a = *++p & 0377;
if (a == A_END_LIST)
{
/*
* We get here only if the original
* cmd string passed in was empty ("").
* I don't think that can happen,
* but just in case ...
*/
return (A_UINVALID);
}
/*
* Check for an "extra" string.
*/
if (a & A_EXTRA)
{
*sp = ++p;
a &= ~A_EXTRA;
} else
*sp = NULL;
return (a);
}
} else if (*q == '\0')
{
/*
* Hit the end of the user's command,
* but not the end of the string in the command table.
* The user's command is incomplete.
*/
return (A_PREFIX);
} else
{
/*
* Not a match.
* Skip ahead to the next command in the
* command table, and reset the pointer
* to the beginning of the user's command.
*/
if (*p == '\0' && p[1] == A_END_LIST)
{
/*
* A_END_LIST is a special marker that tells
* us to abort the cmd search.
*/
return (A_UINVALID);
}
while (*p++ != '\0')
continue;
while (*p == A_SKIP)
p++;
if (*p & A_EXTRA)
while (*++p != '\0')
continue;
q = cmd-1;
}
}
/*
* No match found in the entire command table.
*/
return (A_INVALID);
}
/*
* Decode a command character and return the associated action.
* The "extra" string, if any, is returned in sp.
*/
static int
cmd_decode(tlist, cmd, sp)
struct tablelist *tlist;
char *cmd;
char **sp;
{
register struct tablelist *t;
register int action = A_INVALID;
/*
* Search thru all the command tables.
* Stop when we find an action which is not A_INVALID.
*/
for (t = tlist; t != NULL; t = t->t_next)
{
action = cmd_search(cmd, t->t_start, t->t_end, sp);
if (action != A_INVALID)
break;
}
return (action);
}
/*
* Decode a command from the cmdtables list.
*/
public int
fcmd_decode(cmd, sp)
char *cmd;
char **sp;
{
return (cmd_decode(list_fcmd_tables, cmd, sp));
}
/*
* Decode a command from the edittables list.
*/
public int
ecmd_decode(cmd, sp)
char *cmd;
char **sp;
{
return (cmd_decode(list_ecmd_tables, cmd, sp));
}
/*
* Get the value of an environment variable.
* Looks first in the lesskey file, then in the real environment.
*/
public char *
lgetenv(var)
char *var;
{
int a;
char *s;
a = cmd_decode(list_var_tables, var, &s);
if (a == EV_OK)
return (s);
s = getenv(var);
if (s != NULL && *s != '\0')
return (s);
a = cmd_decode(list_sysvar_tables, var, &s);
if (a == EV_OK)
return (s);
return (NULL);
}
#if USERFILE
/*
* Get an "integer" from a lesskey file.
* Integers are stored in a funny format:
* two bytes, low order first, in radix KRADIX.
*/
static int
gint(sp)
char **sp;
{
int n;
n = *(*sp)++;
n += *(*sp)++ * KRADIX;
return (n);
}
/*
* Process an old (pre-v241) lesskey file.
*/
static int
old_lesskey(buf, len)
char *buf;
int len;
{
/*
* Old-style lesskey file.
* The file must end with either
* ...,cmd,0,action
* or ...,cmd,0,action|A_EXTRA,string,0
* So the last byte or the second to last byte must be zero.
*/
if (buf[len-1] != '\0' && buf[len-2] != '\0')
return (-1);
add_fcmd_table(buf, len);
return (0);
}
/*
* Process a new (post-v241) lesskey file.
*/
static int
new_lesskey(buf, len, sysvar)
char *buf;
int len;
int sysvar;
{
char *p;
register int c;
register int n;
/*
* New-style lesskey file.
* Extract the pieces.
*/
if (buf[len-3] != C0_END_LESSKEY_MAGIC ||
buf[len-2] != C1_END_LESSKEY_MAGIC ||
buf[len-1] != C2_END_LESSKEY_MAGIC)
return (-1);
p = buf + 4;
for (;;)
{
c = *p++;
switch (c)
{
case CMD_SECTION:
n = gint(&p);
add_fcmd_table(p, n);
p += n;
break;
case EDIT_SECTION:
n = gint(&p);
add_ecmd_table(p, n);
p += n;
break;
case VAR_SECTION:
n = gint(&p);
add_var_table((sysvar) ?
&list_sysvar_tables : &list_var_tables, p, n);
p += n;
break;
case END_SECTION:
return (0);
default:
/*
* Unrecognized section type.
*/
return (-1);
}
}
}
/*
* Set up a user command table, based on a "lesskey" file.
*/
public int
lesskey(filename, sysvar)
char *filename;
int sysvar;
{
register char *buf;
register POSITION len;
register long n;
register int f;
if (secure)
return (1);
/*
* Try to open the lesskey file.
*/
filename = unquote_file(filename);
f = open(filename, OPEN_READ);
free(filename);
if (f < 0)
return (1);
/*
* Read the file into a buffer.
* We first figure out the size of the file and allocate space for it.
* {{ Minimal error checking is done here.
* A garbage .less file will produce strange results.
* To avoid a large amount of error checking code here, we
* rely on the lesskey program to generate a good .less file. }}
*/
len = filesize(f);
if (len == NULL_POSITION || len < 3)
{
/*
* Bad file (valid file must have at least 3 chars).
*/
close(f);
return (-1);
}
if ((buf = (char *) calloc((int)len, sizeof(char))) == NULL)
{
close(f);
return (-1);
}
if (lseek(f, (off_t)0, 0) == BAD_LSEEK)
{
free(buf);
close(f);
return (-1);
}
n = read(f, buf, (unsigned int) len);
close(f);
if (n != len)
{
free(buf);
return (-1);
}
/*
* Figure out if this is an old-style (before version 241)
* or new-style lesskey file format.
*/
if (buf[0] != C0_LESSKEY_MAGIC || buf[1] != C1_LESSKEY_MAGIC ||
buf[2] != C2_LESSKEY_MAGIC || buf[3] != C3_LESSKEY_MAGIC)
return (old_lesskey(buf, (int)len));
return (new_lesskey(buf, (int)len, sysvar));
}
/*
* Add the standard lesskey file "$HOME/.less"
*/
public void
add_hometable(envname, def_filename, sysvar)
char *envname;
char *def_filename;
int sysvar;
{
char *filename;
PARG parg;
if ((filename = lgetenv(envname)) != NULL)
filename = save(filename);
else if (sysvar)
filename = save(def_filename);
else
filename = homefile(def_filename);
if (filename == NULL)
return;
if (lesskey(filename, sysvar) < 0)
{
parg.p_string = filename;
error("Cannot use lesskey file \"%s\"", &parg);
}
free(filename);
}
#endif
/*
* See if a char is a special line-editing command.
*/
public int
editchar(c, flags)
int c;
int flags;
{
int action;
int nch;
char *s;
char usercmd[MAX_CMDLEN+1];
/*
* An editing character could actually be a sequence of characters;
* for example, an escape sequence sent by pressing the uparrow key.
* To match the editing string, we use the command decoder
* but give it the edit-commands command table
* This table is constructed to match the user's keyboard.
*/
if (c == erase_char)
return (EC_BACKSPACE);
if (c == kill_char)
return (EC_LINEKILL);
/*
* Collect characters in a buffer.
* Start with the one we have, and get more if we need them.
*/
nch = 0;
do {
if (nch > 0)
c = getcc();
usercmd[nch] = c;
usercmd[nch+1] = '\0';
nch++;
action = ecmd_decode(usercmd, &s);
} while (action == A_PREFIX);
#if CMD_HISTORY
if (flags & EC_NOHISTORY)
{
/*
* The caller says there is no history list.
* Reject any history-manipulation action.
*/
switch (action)
{
case EC_UP:
case EC_DOWN:
action = A_INVALID;
break;
}
}
#endif
#if TAB_COMPLETE_FILENAME
if (flags & EC_NOCOMPLETE)
{
/*
* The caller says we don't want any filename completion cmds.
* Reject them.
*/
switch (action)
{
case EC_F_COMPLETE:
case EC_B_COMPLETE:
case EC_EXPAND:
action = A_INVALID;
break;
}
}
#endif
if ((flags & EC_PEEK) || action == A_INVALID)
{
/*
* We're just peeking, or we didn't understand the command.
* Unget all the characters we read in the loop above.
* This does NOT include the original character that was
* passed in as a parameter.
*/
while (nch > 1)
{
ungetcc(usercmd[--nch]);
}
} else
{
if (s != NULL)
ungetsc(s);
}
return action;
}

377
contrib/less/defines.ds Normal file
View File

@ -0,0 +1,377 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/* DOS definition file for less. */
/*
* This file has 2 sections:
* User preferences.
* Settings always true for MS-DOS systems.
*/
/* User preferences. */
/*
* SECURE is 1 if you wish to disable a bunch of features in order to
* be safe to run by unprivileged users.
*/
#define SECURE 0
/*
* SHELL_ESCAPE is 1 if you wish to allow shell escapes.
* (This is possible only if your system supplies the system() function.)
*/
#define SHELL_ESCAPE (!SECURE)
/*
* EXAMINE is 1 if you wish to allow examining files by name from within less.
*/
#define EXAMINE (!SECURE)
/*
* TAB_COMPLETE_FILENAME is 1 if you wish to allow the TAB key
* to complete filenames at prompts.
*/
#define TAB_COMPLETE_FILENAME (!SECURE)
/*
* CMD_HISTORY is 1 if you wish to allow keys to cycle through
* previous commands at prompts.
*/
#define CMD_HISTORY 1
/*
* HILITE_SEARCH is 1 if you wish to have search targets to be
* displayed in standout mode.
*/
#define HILITE_SEARCH 1
/*
* 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.
*/
#define EDITOR (!SECURE)
#define EDIT_PGM "vi"
/*
* TAGS is 1 if you wish to support tag files.
*/
#define TAGS (!SECURE)
/*
* USERFILE is 1 if you wish to allow a .less file to specify
* user-defined key bindings.
*/
#define USERFILE (!SECURE)
/*
* GLOB is 1 if you wish to have shell metacharacters expanded in filenames.
* This will generally work if your system provides the "popen" function
* and the "echo" shell command.
*/
#ifdef __DJGPP__
#define GLOB (!SECURE)
#else
#define GLOB 0
#endif
/*
* PIPEC is 1 if you wish to have the "|" command
* which allows the user to pipe data into a shell command.
*/
#ifdef __DJGPP__
#define PIPEC (!SECURE)
#else
#define PIPEC 0
#endif
/*
* LOGFILE is 1 if you wish to allow the -l option (to create log files).
*/
#define LOGFILE (!SECURE)
/*
* GNU_OPTIONS is 1 if you wish to support the GNU-style command
* line options --help and --version.
*/
#define GNU_OPTIONS 1
/*
* 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.
*/
#define ONLY_RETURN 0
/*
* LESSKEYFILE is the filename of the default lesskey output file
* (in the HOME directory).
* LESSKEYFILE_SYS is the filename of the system-wide lesskey output file.
* DEF_LESSKEYINFILE is the filename of the default lesskey input
* (in the HOME directory).
*/
#define LESSKEYFILE "_less"
#define LESSKEYFILE_SYS "c:\\_sysless"
#define DEF_LESSKEYINFILE "_lesskey"
/* Settings always true for MS-DOS systems. */
/*
* Define MSDOS_COMPILER if compiling for MS-DOS.
*/
#ifdef __DJGPP__
#define MSDOS_COMPILER DJGPPC
#else
#ifdef __BORLANDC__
#define MSDOS_COMPILER BORLANDC
#else
#define MSDOS_COMPILER MSOFTC
#endif
#endif
/*
* Pathname separator character.
*/
#define PATHNAME_SEP "\\"
/*
* HAVE_SYS_TYPES_H is 1 if your system has <sys/types.h>.
*/
#define HAVE_SYS_TYPES_H 1
/*
* Define if you have the <sgstat.h> header file.
*/
#define HAVE_SGSTAT_H 0
/*
* HAVE_PERROR is 1 if your system has the perror() call.
* (Actually, if it has sys_errlist, sys_nerr and errno.)
*/
#define HAVE_PERROR 1
/*
* HAVE_TIME is 1 if your system has the time() call.
*/
#define HAVE_TIME 1
/*
* HAVE_SHELL is 1 if your system supports a SHELL command interpreter.
*/
#define HAVE_SHELL 0
/*
* HAVE_DUP is 1 if your system has the dup() call.
*/
#define HAVE_DUP 1
/*
* Sizes of various buffers.
*/
#define CMDBUF_SIZE 512 /* Buffer for multichar commands */
#define UNGOT_SIZE 100 /* Max chars to unget() */
#define LINEBUF_SIZE 1024 /* Max size of line in input file */
#define OUTBUF_SIZE 1024 /* Output buffer */
#define PROMPT_SIZE 200 /* Max size of prompt string */
#define TERMBUF_SIZE 2048 /* Termcap buffer for tgetent */
#define TERMSBUF_SIZE 1024 /* Buffer to hold termcap strings */
#define TAGLINE_SIZE 512 /* Max size of line in tags file */
/* Define to `long' if <sys/types.h> doesn't define. */
#if MSDOS_COMPILER==BORLANDC
#define off_t long
#endif
/* Define if you need to in order for stat and other things to work. */
/* #undef _POSIX_SOURCE */
/* Define as the return type of signal handlers (int or void). */
#define RETSIGTYPE void
/*
* Regular expression library.
* Define exactly one of the following to be 1:
* HAVE_POSIX_REGCOMP: POSIX regcomp() and regex.h
* HAVE_RE_COMP: BSD re_comp()
* HAVE_REGCMP: System V regcmp()
* HAVE_V8_REGCOMP: Henry Spencer V8 regcomp() and regexp.h
* NO_REGEX: pattern matching is supported, but without metacharacters.
*/
/* #undef HAVE_POSIX_REGCOMP */
/* #undef HAVE_RE_COMP */
/* #undef HAVE_REGCMP */
/* #undef HAVE_V8_REGCOMP */
#if MSDOS_COMPILER==DJGPPC
#define HAVE_POSIX_REGCOMP 1
#else
#define NO_REGEX 1
#endif
/* Define HAVE_VOID if your compiler supports the "void" type. */
#define HAVE_VOID 1
/* Define HAVE_CONST if your compiler supports the "const" modifier. */
#define HAVE_CONST 1
/* Define HAVE_TIME_T if your system supports the "time_t" type. */
#define HAVE_TIME_T 1
/* Define HAVE_STRERROR if you have the strerror() function. */
#define HAVE_STRERROR 1
/* Define HAVE_FILENO if you have the fileno() macro. */
#define HAVE_FILENO 1
/* Define HAVE_ERRNO if you have the errno variable */
/* Define MUST_DEFINE_ERRNO if you have errno but it is not defined
* in errno.h */
#if MSDOS_COMPILER==MSOFTC || MSDOS_COMPILER==DJGPPC
#define HAVE_ERRNO 1
#define MUST_DEFINE_ERRNO 0
#else
#define HAVE_ERRNO 1
#define MUST_DEFINE_ERRNO 1
#endif
/* Define HAVE_SYS_ERRLIST if you have the sys_errlist[] variable */
#define HAVE_SYS_ERRLIST 1
/* Define HAVE_OSPEED if your termcap library has the ospeed variable */
/* Define MUST_DEFINE_OSPEED if you have ospeed but it is not defined
* in termcap.h. */
#define HAVE_OSPEED 0
#define MUST_DEFINE_OSPEED 0
/* Define HAVE_LOCALE if you have locale.h and setlocale. */
#define HAVE_LOCALE 1
/* Define HAVE_TERMIOS_FUNCS if you have tcgetattr/tcsetattr */
#define HAVE_TERMIOS_FUNCS 0
/* Define HAVE_UPPER_LOWER if you have isupper, islower, toupper, tolower */
#define HAVE_UPPER_LOWER 1
/* Define if you have the _setjmp function. */
#if MSDOS_COMPILER==MSOFTC || MSDOS_COMPILER==DJGPPC
#define HAVE__SETJMP 0
#else
#define HAVE__SETJMP 1
#endif
/* Define if you have the memcpy function. */
#define HAVE_MEMCPY 1
/* Define if you have the popen function. */
#if MSDOS_COMPILER==DJGPPC
#define HAVE_POPEN 1
#else
#define HAVE_POPEN 0
#endif
/* Define if you have the sigsetmask function. */
#define HAVE_SIGSETMASK 0
/* Define if you have the stat function. */
#define HAVE_STAT 1
/* Define if you have the strchr function. */
#define HAVE_STRCHR 1
/* Define if you have the system function. */
#define HAVE_SYSTEM 1
/* Define if you have the <ctype.h> header file. */
#define HAVE_CTYPE_H 1
/* Define if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define if you have the <stdlib> header file. */
#define HAVE_STDLIB_H 1
/* Define if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define if you have the <sys/ioctl.h> header file. */
#define HAVE_SYS_IOCTL_H 0
/* Define if you have the <sys/ptem.h> header file. */
#define HAVE_SYS_PTEM_H 0
/* Define if you have the <sys/stream.h> header file. */
#define HAVE_SYS_STREAM_H 0
/* Define if you have the <termcap.h> header file. */
#define HAVE_TERMCAP_H 0
/* Define if you have the <termio.h> header file. */
#define HAVE_TERMIO_H 0
/* Define if you have the <termios.h> header file. */
#define HAVE_TERMIOS_H 0
/* Define if you have the <time.h> header file. */
#define HAVE_TIME_H 1
/* Define if you have the <unistd.h> header file. */
#if MSDOS_COMPILER==DJGPPC
#define HAVE_UNISTD_H 1
#else
#define HAVE_UNISTD_H 0
#endif
/* Define if you have the <values.h> header file. */
#if MSDOS_COMPILER==MSOFTC
#define HAVE_VALUES_H 0
#else
#define HAVE_VALUES_H 1
#endif
#if MSDOS_COMPILER == MSOFTC && _MSC_VER >= 700
/*
* The names of these things changed in Microsoft C version 7.0.
*/
#define videoconfig _videoconfig
#define rccoord _rccoord
#define O_RDONLY _O_RDONLY
#define O_WRONLY _O_WRONLY
#define O_APPEND _O_APPEND
#define O_BINARY _O_BINARY
#define O_TEXT _O_TEXT
#define find_t _find_t
#define stat _stat
#define S_IFMT _S_IFMT
#define S_IFDIR _S_IFDIR
#define S_IFREG _S_IFREG
#define dup _dup
#define open _open
#define lseek _lseek
#define write _write
#define creat _creat
#define fstat _fstat
#define isatty _isatty
#define close _close
#define read _read
#define ungetch _ungetch
#define kbhit _kbhit
#define getch _getch
#endif

326
contrib/less/defines.h.in Normal file
View File

@ -0,0 +1,326 @@
/* defines.h.in. Generated automatically from configure.in by autoheader. */
/* Unix definition file for less. -*- C -*-
*
* This file has 3 sections:
* User preferences.
* Settings always true on Unix.
* Settings automatically determined by configure.
*
* * * * * * WARNING * * * * * *
* If you edit defines.h by hand, do "touch stamp-h" before you run make
* so config.status doesn't overwrite your changes.
*/
/* User preferences. */
/*
* SECURE is 1 if you wish to disable a bunch of features in order to
* be safe to run by unprivileged users.
*/
#define SECURE 0
/*
* SHELL_ESCAPE is 1 if you wish to allow shell escapes.
* (This is possible only if your system supplies the system() function.)
*/
#define SHELL_ESCAPE (!SECURE)
/*
* EXAMINE is 1 if you wish to allow examining files by name from within less.
*/
#define EXAMINE (!SECURE)
/*
* TAB_COMPLETE_FILENAME is 1 if you wish to allow the TAB key
* to complete filenames at prompts.
*/
#define TAB_COMPLETE_FILENAME (!SECURE)
/*
* CMD_HISTORY is 1 if you wish to allow keys to cycle through
* previous commands at prompts.
*/
#define CMD_HISTORY 1
/*
* HILITE_SEARCH is 1 if you wish to have search targets to be
* displayed in standout mode.
*/
#define HILITE_SEARCH 1
/*
* 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.
*/
#define EDITOR (!SECURE)
/*
* TAGS is 1 if you wish to support tag files.
*/
#define TAGS (!SECURE)
/*
* USERFILE is 1 if you wish to allow a .less file to specify
* user-defined key bindings.
*/
#define USERFILE (!SECURE)
/*
* GLOB is 1 if you wish to have shell metacharacters expanded in filenames.
* This will generally work if your system provides the "popen" function
* and the "echo" shell command.
*/
#define GLOB (!SECURE)
/*
* PIPEC is 1 if you wish to have the "|" command
* which allows the user to pipe data into a shell command.
*/
#define PIPEC (!SECURE)
/*
* LOGFILE is 1 if you wish to allow the -l option (to create log files).
*/
#define LOGFILE (!SECURE)
/*
* GNU_OPTIONS is 1 if you wish to support the GNU-style command
* line options --help and --version.
*/
#define GNU_OPTIONS 1
/*
* 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.
*/
#define ONLY_RETURN 0
/*
* LESSKEYFILE is the filename of the default lesskey output file
* (in the HOME directory).
* LESSKEYFILE_SYS is the filename of the system-wide lesskey output file.
* DEF_LESSKEYINFILE is the filename of the default lesskey input
* (in the HOME directory).
*/
#define LESSKEYFILE ".less"
#define LESSKEYFILE_SYS SYSDIR "/.sysless"
#define DEF_LESSKEYINFILE ".lesskey"
/* Settings always true on Unix. */
/*
* Define MSDOS_COMPILER if compiling under Microsoft C.
*/
#define MSDOS_COMPILER 0
/*
* Pathname separator character.
*/
#define PATHNAME_SEP "/"
/*
* HAVE_SYS_TYPES_H is 1 if your system has <sys/types.h>.
*/
#define HAVE_SYS_TYPES_H 1
/*
* Define if you have the <sgstat.h> header file.
*/
#undef HAVE_SGSTAT_H
/*
* HAVE_PERROR is 1 if your system has the perror() call.
* (Actually, if it has sys_errlist, sys_nerr and errno.)
*/
#define HAVE_PERROR 1
/*
* HAVE_TIME is 1 if your system has the time() call.
*/
#define HAVE_TIME 1
/*
* HAVE_SHELL is 1 if your system supports a SHELL command interpreter.
*/
#define HAVE_SHELL 1
/*
* Default shell metacharacters and meta-escape character.
*/
#define DEF_METACHARS "; \t\n'\"()<>|&^`\\"
#define DEF_METAESCAPE "\\"
/*
* HAVE_DUP is 1 if your system has the dup() call.
*/
#define HAVE_DUP 1
/*
* Sizes of various buffers.
*/
#define CMDBUF_SIZE 512 /* Buffer for multichar commands */
#define UNGOT_SIZE 100 /* Max chars to unget() */
#define LINEBUF_SIZE 1024 /* Max size of line in input file */
#define OUTBUF_SIZE 1024 /* Output buffer */
#define PROMPT_SIZE 200 /* Max size of prompt string */
#define TERMBUF_SIZE 2048 /* Termcap buffer for tgetent */
#define TERMSBUF_SIZE 1024 /* Buffer to hold termcap strings */
#define TAGLINE_SIZE 512 /* Max size of line in tags file */
/* Settings automatically determined by configure. */
/* Define to `long' if <sys/types.h> doesn't define. */
#undef off_t
/* Define if you need to in order for stat and other things to work. */
#undef _POSIX_SOURCE
/* Define as the return type of signal handlers (int or void). */
#undef RETSIGTYPE
/* Define if you have the ANSI C header files. */
#undef STDC_HEADERS
/*
* Regular expression library.
* Define exactly one of the following to be 1:
* HAVE_POSIX_REGCOMP: POSIX regcomp() and regex.h
* HAVE_PCRE: PCRE (Perl-compatible regular expression) library
* HAVE_RE_COMP: BSD re_comp()
* HAVE_REGCMP: System V regcmp()
* HAVE_V8_REGCOMP: Henry Spencer V8 regcomp() and regexp.h
* NO_REGEX: pattern matching is supported, but without metacharacters.
*/
#undef HAVE_POSIX_REGCOMP
#undef HAVE_PCRE
#undef HAVE_RE_COMP
#undef HAVE_REGCMP
#undef HAVE_V8_REGCOMP
#undef NO_REGEX
#undef HAVE_REGEXEC2
/* Define HAVE_VOID if your compiler supports the "void" type. */
#undef HAVE_VOID
/* Define HAVE_CONST if your compiler supports the "const" modifier. */
#undef HAVE_CONST
/* Define HAVE_TIME_T if your system supports the "time_t" type. */
#undef HAVE_TIME_T
/* Define HAVE_STRERROR if you have the strerror() function. */
#undef HAVE_STRERROR
/* Define HAVE_FILENO if you have the fileno() macro. */
#undef HAVE_FILENO
/* Define HAVE_ERRNO if you have the errno variable */
/* Define MUST_DEFINE_ERRNO if you have errno but it is not define
* in errno.h */
#undef HAVE_ERRNO
#undef MUST_DEFINE_ERRNO
/* Define HAVE_SYS_ERRLIST if you have the sys_errlist[] variable */
#undef HAVE_SYS_ERRLIST
/* Define HAVE_OSPEED if your termcap library has the ospeed variable */
/* Define MUST_DEFINE_OSPEED if you have ospeed but it is not defined
* in termcap.h. */
#undef HAVE_OSPEED
#undef MUST_DEFINE_OSPEED
/* Define HAVE_LOCALE if you have locale.h and setlocale. */
#undef HAVE_LOCALE
/* Define HAVE_TERMIOS_FUNCS if you have tcgetattr/tcsetattr */
#undef HAVE_TERMIOS_FUNCS
/* Define HAVE_UPPER_LOWER if you have isupper, islower, toupper, tolower */
#undef HAVE_UPPER_LOWER
/* Define EDIT_PGM to your editor. */
#define EDIT_PGM "vi"
/* Define if you have the _setjmp function. */
#undef HAVE__SETJMP
/* Define if you have the memcpy function. */
#undef HAVE_MEMCPY
/* Define if you have the popen function. */
#undef HAVE_POPEN
/* Define if you have the sigsetmask function. */
#undef HAVE_SIGSETMASK
/* Define if you have the stat function. */
#undef HAVE_STAT
/* Define if you have the strchr function. */
#undef HAVE_STRCHR
/* Define if you have the strstr function. */
#undef HAVE_STRSTR
/* Define if you have the system function. */
#undef HAVE_SYSTEM
/* Define if you have the <ctype.h> header file. */
#undef HAVE_CTYPE_H
/* Define if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
/* Define if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* Define if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H
/* Define if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define if you have the <sys/ioctl.h> header file. */
#undef HAVE_SYS_IOCTL_H
/* Define if you have the <sys/ptem.h> header file. */
#undef HAVE_SYS_PTEM_H
/* Define if you have the <sys/stream.h> header file. */
#undef HAVE_SYS_STREAM_H
/* Define if you have the <termcap.h> header file. */
#undef HAVE_TERMCAP_H
/* Define if you have the <termio.h> header file. */
#undef HAVE_TERMIO_H
/* Define if you have the <termios.h> header file. */
#undef HAVE_TERMIOS_H
/* Define if you have the <time.h> header file. */
#undef HAVE_TIME_H
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define if you have the <values.h> header file. */
#undef HAVE_VALUES_H
/* Define if you have the PW library (-lPW). */
#undef HAVE_LIBPW
/* Define if you have the gen library (-lgen). */
#undef HAVE_LIBGEN
/* Define if you have the intl library (-lintl). */
#undef HAVE_LIBINTL

172
contrib/less/defines.h.top Normal file
View File

@ -0,0 +1,172 @@
/* Unix definition file for less. -*- C -*-
*
* This file has 3 sections:
* User preferences.
* Settings always true on Unix.
* Settings automatically determined by configure.
*
* * * * * * WARNING * * * * * *
* If you edit defines.h by hand, do "touch stamp-h" before you run make
* so config.status doesn't overwrite your changes.
*/
/* User preferences. */
/*
* SECURE is 1 if you wish to disable a bunch of features in order to
* be safe to run by unprivileged users.
*/
#define SECURE 0
/*
* SHELL_ESCAPE is 1 if you wish to allow shell escapes.
* (This is possible only if your system supplies the system() function.)
*/
#define SHELL_ESCAPE (!SECURE)
/*
* EXAMINE is 1 if you wish to allow examining files by name from within less.
*/
#define EXAMINE (!SECURE)
/*
* TAB_COMPLETE_FILENAME is 1 if you wish to allow the TAB key
* to complete filenames at prompts.
*/
#define TAB_COMPLETE_FILENAME (!SECURE)
/*
* CMD_HISTORY is 1 if you wish to allow keys to cycle through
* previous commands at prompts.
*/
#define CMD_HISTORY 1
/*
* HILITE_SEARCH is 1 if you wish to have search targets to be
* displayed in standout mode.
*/
#define HILITE_SEARCH 1
/*
* 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.
*/
#define EDITOR (!SECURE)
/*
* TAGS is 1 if you wish to support tag files.
*/
#define TAGS (!SECURE)
/*
* USERFILE is 1 if you wish to allow a .less file to specify
* user-defined key bindings.
*/
#define USERFILE (!SECURE)
/*
* GLOB is 1 if you wish to have shell metacharacters expanded in filenames.
* This will generally work if your system provides the "popen" function
* and the "echo" shell command.
*/
#define GLOB (!SECURE)
/*
* PIPEC is 1 if you wish to have the "|" command
* which allows the user to pipe data into a shell command.
*/
#define PIPEC (!SECURE)
/*
* LOGFILE is 1 if you wish to allow the -l option (to create log files).
*/
#define LOGFILE (!SECURE)
/*
* GNU_OPTIONS is 1 if you wish to support the GNU-style command
* line options --help and --version.
*/
#define GNU_OPTIONS 1
/*
* 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.
*/
#define ONLY_RETURN 0
/*
* LESSKEYFILE is the filename of the default lesskey output file
* (in the HOME directory).
* LESSKEYFILE_SYS is the filename of the system-wide lesskey output file.
* DEF_LESSKEYINFILE is the filename of the default lesskey input
* (in the HOME directory).
*/
#define LESSKEYFILE ".less"
#define LESSKEYFILE_SYS SYSDIR "/.sysless"
#define DEF_LESSKEYINFILE ".lesskey"
/* Settings always true on Unix. */
/*
* Define MSDOS_COMPILER if compiling under Microsoft C.
*/
#define MSDOS_COMPILER 0
/*
* Pathname separator character.
*/
#define PATHNAME_SEP "/"
/*
* HAVE_SYS_TYPES_H is 1 if your system has <sys/types.h>.
*/
#define HAVE_SYS_TYPES_H 1
/*
* Define if you have the <sgstat.h> header file.
*/
#undef HAVE_SGSTAT_H
/*
* HAVE_PERROR is 1 if your system has the perror() call.
* (Actually, if it has sys_errlist, sys_nerr and errno.)
*/
#define HAVE_PERROR 1
/*
* HAVE_TIME is 1 if your system has the time() call.
*/
#define HAVE_TIME 1
/*
* HAVE_SHELL is 1 if your system supports a SHELL command interpreter.
*/
#define HAVE_SHELL 1
/*
* Default shell metacharacters and meta-escape character.
*/
#define DEF_METACHARS "; \t\n'\"()<>|&^`\\"
#define DEF_METAESCAPE "\\"
/*
* HAVE_DUP is 1 if your system has the dup() call.
*/
#define HAVE_DUP 1
/*
* Sizes of various buffers.
*/
#define CMDBUF_SIZE 512 /* Buffer for multichar commands */
#define UNGOT_SIZE 100 /* Max chars to unget() */
#define LINEBUF_SIZE 1024 /* Max size of line in input file */
#define OUTBUF_SIZE 1024 /* Output buffer */
#define PROMPT_SIZE 200 /* Max size of prompt string */
#define TERMBUF_SIZE 2048 /* Termcap buffer for tgetent */
#define TERMSBUF_SIZE 1024 /* Buffer to hold termcap strings */
#define TAGLINE_SIZE 512 /* Max size of line in tags file */
/* Settings automatically determined by configure. */

302
contrib/less/defines.o2 Normal file
View File

@ -0,0 +1,302 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/* OS/2 definition file for less. */
/*
* This file has 2 sections:
* User preferences.
* Settings always true for the emx compiler for OS/2 systems.
*/
/* User preferences. */
/*
* SECURE is 1 if you wish to disable a bunch of features in order to
* be safe to run by unprivileged users.
*/
#define SECURE 0
/*
* SHELL_ESCAPE is 1 if you wish to allow shell escapes.
* (This is possible only if your system supplies the system() function.)
*/
#define SHELL_ESCAPE (!SECURE)
/*
* EXAMINE is 1 if you wish to allow examining files by name from within less.
*/
#define EXAMINE (!SECURE)
/*
* TAB_COMPLETE_FILENAME is 1 if you wish to allow the TAB key
* to complete filenames at prompts.
*/
#define TAB_COMPLETE_FILENAME (!SECURE)
/*
* CMD_HISTORY is 1 if you wish to allow keys to cycle through
* previous commands at prompts.
*/
#define CMD_HISTORY 1
/*
* HILITE_SEARCH is 1 if you wish to have search targets to be
* displayed in standout mode.
*/
#define HILITE_SEARCH 1
/*
* 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.
*/
#define EDITOR (!SECURE)
#define EDIT_PGM "me"
/*
* TAGS is 1 if you wish to support tag files.
*/
#define TAGS (!SECURE)
/*
* USERFILE is 1 if you wish to allow a .less file to specify
* user-defined key bindings.
*/
#define USERFILE (!SECURE)
/*
* GLOB is 1 if you wish to have shell metacharacters expanded in filenames.
* This will generally work if your system provides the "popen" function
* and the "echo" shell command.
*/
#define GLOB (!SECURE)
/*
* PIPEC is 1 if you wish to have the "|" command
* which allows the user to pipe data into a shell command.
*/
#define PIPEC (!SECURE)
/*
* LOGFILE is 1 if you wish to allow the -l option (to create log files).
*/
#define LOGFILE (!SECURE)
/*
* GNU_OPTIONS is 1 if you wish to support the GNU-style command
* line options --help and --version.
*/
#define GNU_OPTIONS 1
/*
* 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.
*/
#define ONLY_RETURN 0
/*
* LESSKEYFILE is the filename of the default lesskey output file
* (in the HOME directory).
* LESSKEYFILE_SYS is the filename of the system-wide lesskey output file.
* DEF_LESSKEYINFILE is the filename of the default lesskey input
* (in the HOME directory).
*/
#define LESSKEYFILE "less.ini"
#define LESSKEYFILE_SYS "\\sysless.ini"
#define DEF_LESSKEYINFILE "lesskey.ini"
/* Settings always true for the emx compiler for OS/2 systems. */
#define OS2 1
/*
* Pathname separator character.
*/
#define PATHNAME_SEP "\\"
/*
* HAVE_SYS_TYPES_H is 1 if your system has <sys/types.h>.
*/
#define HAVE_SYS_TYPES_H 1
/*
* Define if you have the <sgstat.h> header file.
*/
#define HAVE_SGSTAT_H 0
/*
* HAVE_PERROR is 1 if your system has the perror() call.
* (Actually, if it has sys_errlist, sys_nerr and errno.)
*/
#define HAVE_PERROR 1
/*
* HAVE_TIME is 1 if your system has the time() call.
*/
#define HAVE_TIME 1
/*
* HAVE_SHELL is 1 if your system supports a SHELL command interpreter.
*/
#define HAVE_SHELL 0
/*
* HAVE_DUP is 1 if your system has the dup() call.
*/
#define HAVE_DUP 1
/*
* Sizes of various buffers.
*/
#define CMDBUF_SIZE 512 /* Buffer for multichar commands */
#define UNGOT_SIZE 100 /* Max chars to unget() */
#define LINEBUF_SIZE 1024 /* Max size of line in input file */
#define OUTBUF_SIZE 1024 /* Output buffer */
#define PROMPT_SIZE 200 /* Max size of prompt string */
#define TERMBUF_SIZE 2048 /* Termcap buffer for tgetent */
#define TERMSBUF_SIZE 1024 /* Buffer to hold termcap strings */
#define TAGLINE_SIZE 512 /* Max size of line in tags file */
/* Define to `long' if <sys/types.h> doesn't define. */
/* #define off_t long */
/* Define if you need to in order for stat and other things to work. */
/* #undef _POSIX_SOURCE */
/* Define as the return type of signal handlers (int or void). */
#define RETSIGTYPE void
/*
* Regular expression library.
* Define exactly one of the following to be 1:
* HAVE_POSIX_REGCOMP: POSIX regcomp() and regex.h
* HAVE_RE_COMP: BSD re_comp()
* HAVE_REGCMP: System V regcmp()
* HAVE_V8_REGCOMP: Henry Spencer V8 regcomp() and regexp.h
* NO_REGEX: pattern matching is supported, but without metacharacters.
*/
/* #undef HAVE_POSIX_REGCOMP */
/* #undef HAVE_RE_COMP */
/* #undef HAVE_REGCMP */
#define HAVE_V8_REGCOMP 1
/* #undef NO_REGEX */
#define HAVE_REGEXEC2 1
/* Define HAVE_VOID if your compiler supports the "void" type. */
#define HAVE_VOID 1
/* Define HAVE_CONST if your compiler supports the "const" modifier. */
#define HAVE_CONST 1
/* Define HAVE_TIME_T if your system supports the "time_t" type. */
#define HAVE_TIME_T 0
/* Define HAVE_STRERROR if you have the strerror() function. */
#define HAVE_STRERROR 1
/* Define HAVE_FILENO if you have the fileno() macro. */
#define HAVE_FILENO 1
/* Define HAVE_ERRNO if you have the errno variable */
/* Define MUST_DEFINE_ERRNO if you have errno but it is not define
* in errno.h */
#define HAVE_ERRNO 1
#define MUST_DEFINE_ERRNO 1
/* Define HAVE_SYS_ERRLIST if you have the sys_errlist[] variable */
#define HAVE_SYS_ERRLIST 1
/* Define HAVE_OSPEED if your termcap library has the ospeed variable */
#define HAVE_OSPEED 0
/* Define MUST_DEFINE_OSPEED if you have ospeed but it is not defined
* in termcap.h. */
#define MUST_DEFINE_OSPEED 0
/* Define HAVE_LOCALE if you have locale.h and setlocale. */
#define HAVE_LOCALE 0
/* Define HAVE_TERMIOS_FUNCS if you have tcgetattr/tcsetattr */
#define HAVE_TERMIOS_FUNCS 0
/* Define HAVE_UPPER_LOWER if you have isupper, islower, toupper, tolower */
#define HAVE_UPPER_LOWER 1
/* Define if you have the _setjmp function. */
#define HAVE__SETJMP 0
/* Define if you have the memcpy function. */
#define HAVE_MEMCPY 1
/* Define if you have the popen function. */
#define HAVE_POPEN 0
/* Define if you have the sigsetmask function. */
#define HAVE_SIGSETMASK 0
/* Define if you have the stat function. */
#define HAVE_STAT 1
/* Define if you have the strchr function. */
#define HAVE_STRCHR 1
/* Define if you have the system function. */
#define HAVE_SYSTEM 1
/* Define if you have the <ctype.h> header file. */
#define HAVE_CTYPE_H 1
/* Define if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 0
/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 0
/* Define if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define if you have the <stdlib> header file. */
#define HAVE_STDLIB_H 1
/* Define if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define if you have the <sys/ioctl.h> header file. */
#define HAVE_SYS_IOCTL_H 0
/* Define if you have the <sys/ptem.h> header file. */
#define HAVE_SYS_PTEM_H 0
/* Define if you have the <sys/stream.h> header file. */
#define HAVE_SYS_STREAM_H 0
/* Define if you have the <termcap.h> header file. */
#define HAVE_TERMCAP_H 0
/* Define if you have the <termio.h> header file. */
#define HAVE_TERMIO_H 0
/* Define if you have the <termios.h> header file. */
#define HAVE_TERMIOS_H 0
/* Define if you have the <time.h> header file. */
#define HAVE_TIME_H 1
/* Define if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define if you have the <values.h> header file. */
#define HAVE_VALUES_H 0

323
contrib/less/defines.o9 Normal file
View File

@ -0,0 +1,323 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/* OS/9 definition file for less. */
/*
* This file has 2 sections:
* User preferences.
* Settings always true for OS-9 systems.
*/
/* User preferences. */
/*
* SECURE is 1 if you wish to disable a bunch of features in order to
* be safe to run by unprivileged users.
*/
#define SECURE 0
/*
* SHELL_ESCAPE is 1 if you wish to allow shell escapes.
* (This is possible only if your system supplies the system() function.)
*/
#define SHELL_ESCAPE (!SECURE)
/*
* EXAMINE is 1 if you wish to allow examining files by name from within less.
*/
#define EXAMINE (!SECURE)
/*
* TAB_COMPLETE_FILENAME is 1 if you wish to allow the TAB key
* to complete filenames at prompts.
*/
#define TAB_COMPLETE_FILENAME 1
/*
* CMD_HISTORY is 1 if you wish to allow keys to cycle through
* previous commands at prompts.
*/
#define CMD_HISTORY 1
/*
* HILITE_SEARCH is 1 if you wish to have search targets to be
* displayed in standout mode.
*/
#define HILITE_SEARCH 1
/*
* 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.
*/
#define EDITOR (!SECURE)
#define EDIT_PGM "umacs"
/*
* TAGS is 1 if you wish to support tag files.
*/
#define TAGS (!SECURE)
/*
* USERFILE is 1 if you wish to allow a .less file to specify
* user-defined key bindings.
*/
#define USERFILE (!SECURE)
/*
* GLOB is 1 if you wish to have shell metacharacters expanded in filenames.
* This will generally work if your system provides the "popen" function
* and the "echo" shell command.
*/
#define GLOB (!SECURE)
/*
* PIPEC is 1 if you wish to have the "|" command
* which allows the user to pipe data into a shell command.
*/
#define PIPEC (!SECURE)
/*
* LOGFILE is 1 if you wish to allow the -l option (to create log files).
*/
#define LOGFILE (!SECURE)
/*
* GNU_OPTIONS is 1 if you wish to support the GNU-style command
* line options --help and --version.
*/
#define GNU_OPTIONS 1
/*
* 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.
*/
#define ONLY_RETURN 0
/*
* LESSKEYFILE is the filename of the default lesskey output file
* (in the HOME directory).
* LESSKEYFILE_SYS is the filename of the system-wide lesskey output file.
* DEF_LESSKEYINFILE is the filename of the default lesskey input
* (in the HOME directory).
*/
#define LESSKEYFILE ".less"
#define LESSKEYFILE_SYS "/.sysless"
#define DEF_LESSKEYINFILE ".lesskey"
/* Settings always true for OS-9. */
/* This is not needed; it is defined by the compiler. */
/* #define _OSK 1 */
#define OS2 0
#define MSDOS_COMPILER 0
/*
* Pathname separator character.
*/
#define PATHNAME_SEP "/"
/*
* HAVE_SYS_TYPES_H is 1 if your system has <sys/types.h>.
*/
#define HAVE_SYS_TYPES_H 0
/*
* Define if you have the <sgstat.h> header file.
*/
#define HAVE_SGSTAT_H 1
/*
* HAVE_PERROR is 1 if your system has the perror() call.
* (Actually, if it has sys_errlist, sys_nerr and errno.)
*/
#if _OSK_MWC32
#define HAVE_PERROR 0
#else
#define HAVE_PERROR 1
#endif
/*
* HAVE_TIME is 1 if your system has the time() call.
*/
#define HAVE_TIME 1
/*
* HAVE_SHELL is 1 if your system supports a SHELL command interpreter.
*/
#define HAVE_SHELL 0
/*
* Default shell metacharacters and meta-escape character.
*/
#define DEF_METACHARS "; \t\n'\"()<>|&^`#\\"
#define DEF_METAESCAPE "\\"
/*
* HAVE_DUP is 1 if your system has the dup() call.
*/
#define HAVE_DUP 0
/*
* Sizes of various buffers.
*/
#define CMDBUF_SIZE 512 /* Buffer for multichar commands */
#define UNGOT_SIZE 100 /* Max chars to unget() */
#define LINEBUF_SIZE 1024 /* Max size of line in input file */
#define OUTBUF_SIZE 1024 /* Output buffer */
#define PROMPT_SIZE 200 /* Max size of prompt string */
#define TERMBUF_SIZE 2048 /* Termcap buffer for tgetent */
#define TERMSBUF_SIZE 1024 /* Buffer to hold termcap strings */
#define TAGLINE_SIZE 512 /* Max size of line in tags file */
/* Define to `long' if <sys/types.h> doesn't define. */
#define off_t long
/* Define if you need to in order for stat and other things to work. */
#define _POSIX_SOURCE 0
/* Define as the return type of signal handlers (int or void). */
#if _OSK_MWC32
#define RETSIGTYPE int
#else
#define RETSIGTYPE void
#endif
/*
* Regular expression library.
* Define exactly one of the following to be 1:
* HAVE_POSIX_REGCOMP: POSIX regcomp() and regex.h
* HAVE_RE_COMP: BSD re_comp()
* HAVE_REGCMP: System V regcmp()
* HAVE_V8_REGCOMP: Henry Spencer V8 regcomp() and regexp.h
* NO_REGEX: pattern matching is supported, but without metacharacters.
*/
#define HAVE_POSIX_REGCOMP 0
#define HAVE_RE_COMP 0
#define HAVE_REGCMP 0
#define HAVE_V8_REGCOMP 1
#define NO_REGEX 0
#define HAVE_REGEXEC2 1
/* Define HAVE_VOID if your compiler supports the "void" type. */
#define HAVE_VOID 1
/* Define HAVE_CONST if your compiler supports the "const" modifier. */
#define HAVE_CONST 0
/* Define HAVE_TIME_T if your system supports the "time_t" type. */
#define HAVE_TIME_T 1
/* Define HAVE_STRERROR if you have the strerror() function. */
#define HAVE_STRERROR 0
/* Define HAVE_FILENO if you have the fileno() macro. */
#define HAVE_FILENO 1
/* Define HAVE_ERRNO if you have the errno variable */
/* Define MUST_DEFINE_ERRNO if you have errno but it is not define
* in errno.h */
#define HAVE_ERRNO 1
#define MUST_DEFINE_ERRNO 0
/* Define HAVE_SYS_ERRLIST if you have the sys_errlist[] variable */
#define HAVE_SYS_ERRLIST 0
/* Define HAVE_OSPEED if your termcap library has the ospeed variable */
/* Define MUST_DEFINE_OSPEED if you have ospeed but it is not defined
* in termcap.h. */
#define HAVE_OSPEED 0
#define MUST_DEFINE_OSPEED 0
/* Define HAVE_LOCALE if you have locale.h and setlocale. */
#define HAVE_LOCALE 0
/* Define HAVE_TERMIOS_FUNCS if you have tcgetattr/tcsetattr */
#define HAVE_TERMIOS_FUNCS 0
/* Define HAVE_UPPER_LOWER if you have isupper, islower, toupper, tolower */
#define HAVE_UPPER_LOWER 1
/* Define if you have the _setjmp function. */
#define HAVE__SETJMP 1
/* Define if you have the memcpy function. */
#define HAVE_MEMCPY 1
/* Define if you have the popen function. */
#define HAVE_POPEN 1
/* Define if you have the sigsetmask function. */
#define HAVE_SIGSETMASK 0
/* Define if you have the stat function. */
#define HAVE_STAT 0
/* Define if you have the strchr function. */
#define HAVE_STRCHR 0
/* Define if you have the system function. */
#define HAVE_SYSTEM 1
/* Define if you have the <ctype.h> header file. */
#define HAVE_CTYPE_H 1
/* Define if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 0
/* Define if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 0
/* Define if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define if you have the <stdlib> header file. */
#if _OSK_MWC32
#define HAVE_STDLIB_H 0
#else
#define HAVE_STDLIB_H 1
#endif
/* Define if you have the <sys/ioctl.h> header file. */
#define HAVE_SYS_IOCTL_H 0
/* Define if you have the <sys/ptem.h> header file. */
#define HAVE_SYS_PTEM_H 0
/* Define if you have the <sys/stream.h> header file. */
#define HAVE_SYS_STREAM_H 0
/* Define if you have the <termcap.h> header file. */
#define HAVE_TERMCAP_H 1
/* Define if you have the <termio.h> header file. */
#define HAVE_TERMIO_H 0
/* Define if you have the <termios.h> header file. */
#define HAVE_TERMIOS_H 0
/* Define if you have the <time.h> header file. */
#define HAVE_TIME_H 1
/* Define if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 0
/* Define if you have the <values.h> header file. */
#define HAVE_VALUES_H 0

310
contrib/less/defines.wn Normal file
View File

@ -0,0 +1,310 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/* Windows definition file for less. */
/*
* This file has 2 sections:
* User preferences.
* Settings always true for Windows systems.
*/
/* User preferences. */
/*
* SECURE is 1 if you wish to disable a bunch of features in order to
* be safe to run by unprivileged users.
*/
#define SECURE 0
/*
* SHELL_ESCAPE is 1 if you wish to allow shell escapes.
* (This is possible only if your system supplies the system() function.)
*/
#define SHELL_ESCAPE (!SECURE)
/*
* EXAMINE is 1 if you wish to allow examining files by name from within less.
*/
#define EXAMINE (!SECURE)
/*
* TAB_COMPLETE_FILENAME is 1 if you wish to allow the TAB key
* to complete filenames at prompts.
*/
#define TAB_COMPLETE_FILENAME (!SECURE)
/*
* CMD_HISTORY is 1 if you wish to allow keys to cycle through
* previous commands at prompts.
*/
#define CMD_HISTORY 1
/*
* HILITE_SEARCH is 1 if you wish to have search targets to be
* displayed in standout mode.
*/
#define HILITE_SEARCH 1
/*
* 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.
*/
#define EDITOR (!SECURE)
#define EDIT_PGM "edit"
/*
* TAGS is 1 if you wish to support tag files.
*/
#define TAGS (!SECURE)
/*
* USERFILE is 1 if you wish to allow a .less file to specify
* user-defined key bindings.
*/
#define USERFILE (!SECURE)
/*
* GLOB is 1 if you wish to have shell metacharacters expanded in filenames.
* This will generally work if your system provides the "popen" function
* and the "echo" shell command.
*/
#define GLOB 0
/*
* PIPEC is 1 if you wish to have the "|" command
* which allows the user to pipe data into a shell command.
*/
#define PIPEC 1
/*
* LOGFILE is 1 if you wish to allow the -l option (to create log files).
*/
#define LOGFILE (!SECURE)
/*
* GNU_OPTIONS is 1 if you wish to support the GNU-style command
* line options --help and --version.
*/
#define GNU_OPTIONS 1
/*
* 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.
*/
#define ONLY_RETURN 0
/*
* LESSKEYFILE is the filename of the default lesskey output file
* (in the HOME directory).
* LESSKEYFILE_SYS is the filename of the system-wide lesskey output file.
* DEF_LESSKEYINFILE is the filename of the default lesskey input
* (in the HOME directory).
*/
#define LESSKEYFILE "_less"
#define LESSKEYFILE_SYS "c:\\_sysless"
#define DEF_LESSKEYINFILE "_lesskey"
/* Settings always true for Windows systems. */
#define MSDOS_COMPILER WIN32C
/*
* Pathname separator character.
*/
#define PATHNAME_SEP "\\"
/*
* HAVE_SYS_TYPES_H is 1 if your system has <sys/types.h>.
*/
#define HAVE_SYS_TYPES_H 1
/*
* Define if you have the <sgstat.h> header file.
*/
#define HAVE_SGSTAT_H 0
/*
* HAVE_PERROR is 1 if your system has the perror() call.
* (Actually, if it has sys_errlist, sys_nerr and errno.)
*/
#define HAVE_PERROR 1
/*
* HAVE_TIME is 1 if your system has the time() call.
*/
#define HAVE_TIME 1
/*
* HAVE_SHELL is 1 if your system supports a SHELL command interpreter.
*/
#define HAVE_SHELL 0
/*
* HAVE_DUP is 1 if your system has the dup() call.
*/
#define HAVE_DUP 1
/*
* Sizes of various buffers.
*/
#define CMDBUF_SIZE 512 /* Buffer for multichar commands */
#define UNGOT_SIZE 100 /* Max chars to unget() */
#define LINEBUF_SIZE 1024 /* Max size of line in input file */
#define OUTBUF_SIZE 1024 /* Output buffer */
#define PROMPT_SIZE 200 /* Max size of prompt string */
#define TERMBUF_SIZE 2048 /* Termcap buffer for tgetent */
#define TERMSBUF_SIZE 1024 /* Buffer to hold termcap strings */
#define TAGLINE_SIZE 512 /* Max size of line in tags file */
/* Define to `long' if <sys/types.h> doesn't define. */
/* #define off_t long */
/* Define if you need to in order for stat and other things to work. */
/* #undef _POSIX_SOURCE */
/* Define as the return type of signal handlers (int or void). */
#define RETSIGTYPE void
/*
* Regular expression library.
* Define exactly one of the following to be 1:
* HAVE_POSIX_REGCOMP: POSIX regcomp() and regex.h
* HAVE_RE_COMP: BSD re_comp()
* HAVE_REGCMP: System V regcmp()
* HAVE_V8_REGCOMP: Henry Spencer V8 regcomp() and regexp.h
* NO_REGEX: pattern matching is supported, but without metacharacters.
*/
/* #undef HAVE_POSIX_REGCOMP */
/* #undef HAVE_RE_COMP */
/* #undef HAVE_REGCMP */
#define HAVE_V8_REGCOMP 1
/* #undef NO_REGEX */
#define HAVE_REGEXEC2 1
/* Define HAVE_VOID if your compiler supports the "void" type. */
#define HAVE_VOID 1
/* Define HAVE_CONST if your compiler supports the "const" modifier. */
#define HAVE_CONST 1
/* Define HAVE_TIME_T if your system supports the "time_t" type. */
#define HAVE_TIME_T 1
/* Define HAVE_STRERROR if you have the strerror() function. */
#define HAVE_STRERROR 1
/* Define HAVE_FILENO if you have the fileno() macro. */
#define HAVE_FILENO 1
/* Define HAVE_ERRNO if you have the errno variable */
/* Define MUST_DEFINE_ERRNO if you have errno but it is not define
* in errno.h */
#define HAVE_ERRNO 1
#define MUST_DEFINE_ERRNO 1
/* Define HAVE_SYS_ERRLIST if you have the sys_errlist[] variable */
#define HAVE_SYS_ERRLIST 1
/* Define HAVE_OSPEED if your termcap library has the ospeed variable */
#define HAVE_OSPEED 0
/* Define MUST_DEFINE_OSPEED if you have ospeed but it is not defined
* in termcap.h. */
#define MUST_DEFINE_OSPEED 0
/* Define HAVE_LOCALE if you have locale.h and setlocale. */
#define HAVE_LOCALE 1
/* Define HAVE_TERMIOS_FUNCS if you have tcgetattr/tcsetattr */
#define HAVE_TERMIOS_FUNCS 0
/* Define HAVE_UPPER_LOWER if you have isupper, islower, toupper, tolower */
#define HAVE_UPPER_LOWER 1
/* Define if you have the _setjmp function. */
#define HAVE__SETJMP 1
/* Define if you have the memcpy function. */
#define HAVE_MEMCPY 1
/* Define if you have the popen function. */
#define HAVE_POPEN 0
/* Define if you have the sigsetmask function. */
#define HAVE_SIGSETMASK 0
/* Define if you have the stat function. */
#define HAVE_STAT 1
/* Define if you have the strchr function. */
#define HAVE_STRCHR 1
/* Define if you have the system function. */
#define HAVE_SYSTEM 1
/* Define if you have the <ctype.h> header file. */
#define HAVE_CTYPE_H 1
/* Define if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 0
/* Define if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define if you have the <stdlib> header file. */
#define HAVE_STDLIB_H 1
/* Define if you have the <sys/ioctl.h> header file. */
#define HAVE_SYS_IOCTL_H 0
/* Define if you have the <sys/ptem.h> header file. */
#define HAVE_SYS_PTEM_H 0
/* Define if you have the <sys/stream.h> header file. */
#define HAVE_SYS_STREAM_H 0
/* Define if you have the <termcap.h> header file. */
#define HAVE_TERMCAP_H 0
/* Define if you have the <termio.h> header file. */
#define HAVE_TERMIO_H 0
/* Define if you have the <termios.h> header file. */
#define HAVE_TERMIOS_H 0
/* Define if you have the <time.h> header file. */
#define HAVE_TIME_H 1
/* Define if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 0
/* Define if you have the <values.h> header file. */
#ifdef _MSC_VER
#define HAVE_VALUES_H 0
#else
#define HAVE_VALUES_H 1
#endif
#define popen _popen
#define pclose _pclose

761
contrib/less/edit.c Normal file
View File

@ -0,0 +1,761 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
#include "less.h"
public int fd0 = 0;
extern int new_file;
extern int errmsgs;
extern int cbufs;
extern char *every_first_cmd;
extern int any_display;
extern int force_open;
extern int is_tty;
extern int sigs;
extern IFILE curr_ifile;
extern IFILE old_ifile;
extern struct scrpos initial_scrpos;
extern void constant *ml_examine;
#if SPACES_IN_FILENAMES
extern char openquote;
extern char closequote;
#endif
#if LOGFILE
extern int logfile;
extern int force_logfile;
extern char *namelogfile;
#endif
char *curr_altfilename = NULL;
static void *curr_altpipe;
/*
* Textlist functions deal with a list of words separated by spaces.
* init_textlist sets up a textlist structure.
* forw_textlist uses that structure to iterate thru the list of
* words, returning each one as a standard null-terminated string.
* back_textlist does the same, but runs thru the list backwards.
*/
public void
init_textlist(tlist, str)
struct textlist *tlist;
char *str;
{
char *s;
#if SPACES_IN_FILENAMES
int quoted = 0;
#endif
tlist->string = skipsp(str);
tlist->endstring = tlist->string + strlen(tlist->string);
for (s = str; s < tlist->endstring; s++)
{
#if SPACES_IN_FILENAMES
if (*s == ' ' && !quoted)
*s = '\0';
if (!quoted && *s == openquote)
quoted = 1;
else if (quoted && *s == closequote)
quoted = 0;
#else
if (*s == ' ')
*s = '\0';
#endif
}
}
public char *
forw_textlist(tlist, prev)
struct textlist *tlist;
char *prev;
{
char *s;
/*
* prev == NULL means return the first word in the list.
* Otherwise, return the word after "prev".
*/
if (prev == NULL)
s = tlist->string;
else
s = prev + strlen(prev);
if (s >= tlist->endstring)
return (NULL);
while (*s == '\0')
s++;
if (s >= tlist->endstring)
return (NULL);
return (s);
}
public char *
back_textlist(tlist, prev)
struct textlist *tlist;
char *prev;
{
char *s;
/*
* prev == NULL means return the last word in the list.
* Otherwise, return the word before "prev".
*/
if (prev == NULL)
s = tlist->endstring;
else if (prev <= tlist->string)
return (NULL);
else
s = prev - 1;
while (*s == '\0')
s--;
if (s <= tlist->string)
return (NULL);
while (s[-1] != '\0' && s > tlist->string)
s--;
return (s);
}
/*
* Close the current input file.
*/
static void
close_file()
{
struct scrpos scrpos;
char *filename;
if (curr_ifile == NULL_IFILE)
return;
/*
* Save the current position so that we can return to
* the same position if we edit this file again.
*/
get_scrpos(&scrpos);
if (scrpos.pos != NULL_POSITION)
{
store_pos(curr_ifile, &scrpos);
lastmark();
}
/*
* Close the file descriptor, unless it is a pipe.
*/
ch_close();
/*
* If we opened a file using an alternate name,
* do special stuff to close it.
*/
if (curr_altfilename != NULL)
{
filename = unquote_file(get_filename(curr_ifile));
close_altfile(curr_altfilename, filename, curr_altpipe);
free(filename);
free(curr_altfilename);
curr_altfilename = NULL;
}
curr_ifile = NULL_IFILE;
}
/*
* Edit a new file (given its name).
* Filename == "-" means standard input.
* Filename == NULL means just close the current file.
*/
public int
edit(filename)
char *filename;
{
if (filename == NULL)
return (edit_ifile(NULL_IFILE));
return (edit_ifile(get_ifile(filename, curr_ifile)));
}
/*
* Edit a new file (given its IFILE).
* ifile == NULL means just close the current file.
*/
public int
edit_ifile(ifile)
IFILE ifile;
{
int f;
int answer;
int no_display;
int chflags;
char *filename;
char *open_filename;
char *alt_filename;
void *alt_pipe;
IFILE was_curr_ifile;
PARG parg;
if (ifile == curr_ifile)
{
/*
* Already have the correct file open.
*/
return (0);
}
/*
* We must close the currently open file now.
* This is necessary to make the open_altfile/close_altfile pairs
* nest properly (or rather to avoid nesting at all).
* {{ Some stupid implementations of popen() mess up if you do:
* fA = popen("A"); fB = popen("B"); pclose(fA); pclose(fB); }}
*/
#if LOGFILE
end_logfile();
#endif
was_curr_ifile = save_curr_ifile();
if (curr_ifile != NULL_IFILE)
{
chflags = ch_getflags();
close_file();
if ((chflags & CH_HELPFILE) && held_ifile(was_curr_ifile) <= 1)
{
/*
* Don't keep the help file in the ifile list.
*/
del_ifile(was_curr_ifile);
was_curr_ifile = old_ifile;
}
}
if (ifile == NULL_IFILE)
{
/*
* No new file to open.
* (Don't set old_ifile, because if you call edit_ifile(NULL),
* you're supposed to have saved curr_ifile yourself,
* and you'll restore it if necessary.)
*/
unsave_ifile(was_curr_ifile);
return (0);
}
filename = unquote_file(get_filename(ifile));
/*
* See if LESSOPEN specifies an "alternate" file to open.
*/
alt_pipe = NULL;
alt_filename = open_altfile(filename, &f, &alt_pipe);
open_filename = (alt_filename != NULL) ? alt_filename : filename;
chflags = 0;
if (alt_pipe != NULL)
{
/*
* The alternate "file" is actually a pipe.
* f has already been set to the file descriptor of the pipe
* in the call to open_altfile above.
* Keep the file descriptor open because it was opened
* via popen(), and pclose() wants to close it.
*/
chflags |= CH_POPENED;
} else if (strcmp(open_filename, "-") == 0)
{
/*
* Use standard input.
* Keep the file descriptor open because we can't reopen it.
*/
f = fd0;
chflags |= CH_KEEPOPEN;
/*
* Must switch stdin to BINARY mode.
*/
SET_BINARY(f);
#if MSDOS_COMPILER==DJGPPC
/*
* Setting stdin to binary by default causes
* Ctrl-C to not raise SIGINT. We must undo
* that side-effect.
*/
__djgpp_set_ctrl_c(1);
#endif
} else if (strcmp(open_filename, FAKE_HELPFILE) == 0)
{
f = -1;
chflags |= CH_HELPFILE;
} else if ((parg.p_string = bad_file(open_filename)) != NULL)
{
/*
* It looks like a bad file. Don't try to open it.
*/
error("%s", &parg);
free(parg.p_string);
err1:
if (alt_filename != NULL)
{
close_altfile(alt_filename, filename, alt_pipe);
free(alt_filename);
}
del_ifile(ifile);
free(filename);
/*
* Re-open the current file.
*/
reedit_ifile(was_curr_ifile);
return (1);
} else if ((f = open(open_filename, OPEN_READ)) < 0)
{
/*
* Got an error trying to open it.
*/
parg.p_string = errno_message(filename);
error("%s", &parg);
free(parg.p_string);
goto err1;
} else
{
chflags |= CH_CANSEEK;
if (!force_open && !opened(ifile) && bin_file(f))
{
/*
* Looks like a binary file.
* Ask user if we should proceed.
*/
parg.p_string = filename;
answer = query("\"%s\" may be a binary file. See it anyway? ",
&parg);
if (answer != 'y' && answer != 'Y')
{
close(f);
goto err1;
}
}
}
/*
* Get the new ifile.
* Get the saved position for the file.
*/
if (was_curr_ifile != NULL_IFILE)
{
old_ifile = was_curr_ifile;
unsave_ifile(was_curr_ifile);
}
curr_ifile = ifile;
curr_altfilename = alt_filename;
curr_altpipe = alt_pipe;
set_open(curr_ifile); /* File has been opened */
get_pos(curr_ifile, &initial_scrpos);
new_file = TRUE;
ch_init(f, chflags);
if (!(chflags & CH_HELPFILE))
{
#if LOGFILE
if (namelogfile != NULL && is_tty)
use_logfile(namelogfile);
#endif
if (every_first_cmd != NULL)
ungetsc(every_first_cmd);
}
no_display = !any_display;
flush();
any_display = TRUE;
if (is_tty)
{
/*
* Output is to a real tty.
*/
/*
* Indicate there is nothing displayed yet.
*/
pos_clear();
clr_linenum();
#if HILITE_SEARCH
clr_hilite();
#endif
cmd_addhist(ml_examine, filename);
if (no_display && errmsgs > 0)
{
/*
* We displayed some messages on error output
* (file descriptor 2; see error() function).
* Before erasing the screen contents,
* display the file name and wait for a keystroke.
*/
parg.p_string = filename;
error("%s", &parg);
}
}
free(filename);
return (0);
}
/*
* Edit a space-separated list of files.
* For each filename in the list, enter it into the ifile list.
* Then edit the first one.
*/
public int
edit_list(filelist)
char *filelist;
{
IFILE save_ifile;
char *good_filename;
char *filename;
char *gfilelist;
char *gfilename;
struct textlist tl_files;
struct textlist tl_gfiles;
save_ifile = save_curr_ifile();
good_filename = NULL;
/*
* Run thru each filename in the list.
* Try to glob the filename.
* If it doesn't expand, just try to open the filename.
* If it does expand, try to open each name in that list.
*/
init_textlist(&tl_files, filelist);
filename = NULL;
while ((filename = forw_textlist(&tl_files, filename)) != NULL)
{
gfilelist = lglob(filename);
init_textlist(&tl_gfiles, gfilelist);
gfilename = NULL;
while ((gfilename = forw_textlist(&tl_gfiles, gfilename)) != NULL)
{
if (edit(gfilename) == 0 && good_filename == NULL)
good_filename = get_filename(curr_ifile);
}
free(gfilelist);
}
/*
* Edit the first valid filename in the list.
*/
if (good_filename == NULL)
{
unsave_ifile(save_ifile);
return (1);
}
if (get_ifile(good_filename, curr_ifile) == curr_ifile)
{
/*
* Trying to edit the current file; don't reopen it.
*/
unsave_ifile(save_ifile);
return (0);
}
reedit_ifile(save_ifile);
return (edit(good_filename));
}
/*
* Edit the first file in the command line (ifile) list.
*/
public int
edit_first()
{
curr_ifile = NULL_IFILE;
return (edit_next(1));
}
/*
* Edit the last file in the command line (ifile) list.
*/
public int
edit_last()
{
curr_ifile = NULL_IFILE;
return (edit_prev(1));
}
/*
* Edit the next or previous file in the command line (ifile) list.
*/
static int
edit_istep(h, n, dir)
IFILE h;
int n;
int dir;
{
IFILE next;
/*
* Skip n filenames, then try to edit each filename.
*/
for (;;)
{
next = (dir > 0) ? next_ifile(h) : prev_ifile(h);
if (--n < 0)
{
if (edit_ifile(h) == 0)
break;
}
if (next == NULL_IFILE)
{
/*
* Reached end of the ifile list.
*/
return (1);
}
if (ABORT_SIGS())
{
/*
* Interrupt breaks out, if we're in a long
* list of files that can't be opened.
*/
return (1);
}
h = next;
}
/*
* Found a file that we can edit.
*/
return (0);
}
static int
edit_inext(h, n)
IFILE h;
int n;
{
return (edit_istep(h, n, 1));
}
public int
edit_next(n)
int n;
{
return edit_istep(curr_ifile, n, 1);
}
static int
edit_iprev(h, n)
IFILE h;
int n;
{
return (edit_istep(h, n, -1));
}
public int
edit_prev(n)
int n;
{
return edit_istep(curr_ifile, n, -1);
}
/*
* Edit a specific file in the command line (ifile) list.
*/
public int
edit_index(n)
int n;
{
IFILE h;
h = NULL_IFILE;
do
{
if ((h = next_ifile(h)) == NULL_IFILE)
{
/*
* Reached end of the list without finding it.
*/
return (1);
}
} while (get_index(h) != n);
return (edit_ifile(h));
}
public IFILE
save_curr_ifile()
{
if (curr_ifile != NULL_IFILE)
hold_ifile(curr_ifile, 1);
return (curr_ifile);
}
public void
unsave_ifile(save_ifile)
IFILE save_ifile;
{
if (save_ifile != NULL_IFILE)
hold_ifile(save_ifile, -1);
}
/*
* Reedit the ifile which was previously open.
*/
public void
reedit_ifile(save_ifile)
IFILE save_ifile;
{
IFILE next;
IFILE prev;
/*
* Try to reopen the ifile.
* Note that opening it may fail (maybe the file was removed),
* in which case the ifile will be deleted from the list.
* So save the next and prev ifiles first.
*/
unsave_ifile(save_ifile);
next = next_ifile(save_ifile);
prev = prev_ifile(save_ifile);
if (edit_ifile(save_ifile) == 0)
return;
/*
* If can't reopen it, open the next input file in the list.
*/
if (next != NULL_IFILE && edit_inext(next, 0) == 0)
return;
/*
* If can't open THAT one, open the previous input file in the list.
*/
if (prev != NULL_IFILE && edit_iprev(prev, 0) == 0)
return;
/*
* If can't even open that, we're stuck. Just quit.
*/
quit(QUIT_ERROR);
}
/*
* Edit standard input.
*/
public int
edit_stdin()
{
if (isatty(fd0))
{
error("Missing filename (\"less --help\" for help)", NULL_PARG);
quit(QUIT_OK);
}
return (edit("-"));
}
/*
* Copy a file directly to standard output.
* Used if standard output is not a tty.
*/
public void
cat_file()
{
register int c;
while ((c = ch_forw_get()) != EOI)
putchr(c);
flush();
}
#if LOGFILE
/*
* If the user asked for a log file and our input file
* is standard input, create the log file.
* We take care not to blindly overwrite an existing file.
*/
public void
use_logfile(filename)
char *filename;
{
register int exists;
register int answer;
PARG parg;
if (ch_getflags() & CH_CANSEEK)
/*
* Can't currently use a log file on a file that can seek.
*/
return;
/*
* {{ We could use access() here. }}
*/
filename = unquote_file(filename);
exists = open(filename, OPEN_READ);
close(exists);
exists = (exists >= 0);
/*
* Decide whether to overwrite the log file or append to it.
* If it doesn't exist we "overwrite" it.
*/
if (!exists || force_logfile)
{
/*
* Overwrite (or create) the log file.
*/
answer = 'O';
} else
{
/*
* Ask user what to do.
*/
parg.p_string = filename;
answer = query("Warning: \"%s\" exists; Overwrite, Append or Don't log? ", &parg);
}
loop:
switch (answer)
{
case 'O': case 'o':
/*
* Overwrite: create the file.
*/
logfile = creat(filename, 0644);
break;
case 'A': case 'a':
/*
* Append: open the file and seek to the end.
*/
logfile = open(filename, OPEN_APPEND);
if (lseek(logfile, (off_t)0, 2) == BAD_LSEEK)
{
close(logfile);
logfile = -1;
}
break;
case 'D': case 'd':
/*
* Don't do anything.
*/
free(filename);
return;
case 'q':
quit(QUIT_OK);
/*NOTREACHED*/
default:
/*
* Eh?
*/
answer = query("Overwrite, Append, or Don't log? (Type \"O\", \"A\", \"D\" or \"q\") ", NULL_PARG);
goto loop;
}
if (logfile < 0)
{
/*
* Error in opening logfile.
*/
parg.p_string = filename;
error("Cannot write to \"%s\"", &parg);
free(filename);
return;
}
free(filename);
SET_BINARY(logfile);
}
#endif

1011
contrib/less/filename.c Normal file

File diff suppressed because it is too large Load Diff

412
contrib/less/forwback.c Normal file
View File

@ -0,0 +1,412 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Primitives for displaying the file on the screen,
* scrolling either forward or backward.
*/
#include "less.h"
#include "position.h"
public int hit_eof; /* Keeps track of how many times we hit end of file */
public int screen_trashed;
public int squished;
public int no_back_scroll = 0;
extern int sigs;
extern int top_scroll;
extern int quiet;
extern int sc_width, sc_height;
extern int quit_at_eof;
extern int plusoption;
extern int forw_scroll;
extern int back_scroll;
extern int ignore_eoi;
extern int clear_bg;
extern int final_attr;
#if TAGS
extern char *tagoption;
#endif
/*
* Sound the bell to indicate user 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 (ignore_eoi)
return;
if (ABORT_SIGS())
return;
/*
* 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++;
}
/*
* If the screen is "squished", repaint it.
* "Squished" means the first displayed line is not at the top
* of the screen; this can happen when we display a short file
* for the first time.
*/
static void
squish_check()
{
if (!squished)
return;
squished = 0;
repaint();
}
/*
* 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.
* "nblank" is the number of blank lines to draw before the first
* real line. If nblank > 0, the pos must be NULL_POSITION.
* The first real line after the blanks will start at ch_zero().
*/
public void
forw(n, pos, force, only_last, nblank)
register int n;
POSITION pos;
int force;
int only_last;
int nblank;
{
int eof = 0;
int nlines = 0;
int do_repaint;
static int first_time = 1;
squish_check();
/*
* do_repaint tells us not to display anything till the end,
* then just repaint the entire screen.
* We repaint if we are supposed to display only the last
* screenful and the request is for more than a screenful.
* Also if the request exceeds the forward scroll limit
* (but not if the request is for exactly a screenful, since
* repainting itself involves scrolling forward a screenful).
*/
do_repaint = (only_last && n > sc_height-1) ||
(forw_scroll >= 0 && n > forw_scroll && n != sc_height-1);
if (!do_repaint)
{
/*
* Forget any current line shift we might have
* (from the last line of the previous screenful).
*/
extern int cshift;
cshift = 0;
if (top_scroll && n >= sc_height - 1 && pos != ch_length())
{
/*
* 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 yet know if that will happen. }}
*/
pos_clear();
add_forw_pos(pos);
force = 1;
if (top_scroll == OPT_ONPLUS || first_time)
clear();
home();
} else
{
clear_bot();
}
if (pos != position(BOTTOM_PLUS_ONE) || empty_screen())
{
/*
* 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)
{
if (top_scroll == OPT_ONPLUS)
clear();
home();
} else if (!first_time)
{
putstr("...skipping...\n");
}
}
}
while (--n >= 0)
{
/*
* Read the next line of input.
*/
if (nblank > 0)
{
/*
* Still drawing blanks; don't get a line
* from the file yet.
* If this is the last blank line, get ready to
* read a line starting at ch_zero() next time.
*/
if (--nblank == 0)
pos = ch_zero();
} else
{
/*
* Get the next line from the file.
*/
pos = forw_line(pos);
if (pos == NULL_POSITION)
{
/*
* End of file: stop here unless the top line
* is still empty, or "force" is true.
* Even if force is true, stop when the last
* line in the file reaches the top of screen.
*/
eof = 1;
if (!force && position(TOP) != NULL_POSITION)
break;
if (!empty_lines(0, 0) &&
!empty_lines(1, 1) &&
empty_lines(2, sc_height-1))
break;
}
}
/*
* Add the position of the next line to the position table.
* Display the current line on the screen.
*/
add_forw_pos(pos);
nlines++;
if (do_repaint)
continue;
/*
* If this is the first screen displayed and
* we hit an early EOF (i.e. before the requested
* number of lines), we "squish" the display down
* at the bottom of the screen.
* But don't do this if a + option or a -t option
* was given. These options can cause us to
* start the display after the beginning of the file,
* and it is not appropriate to squish in that case.
*/
if (first_time && pos == NULL_POSITION && !top_scroll &&
#if TAGS
tagoption == NULL &&
#endif
!plusoption)
{
squished = 1;
continue;
}
if (top_scroll == OPT_ON)
clear_eol();
put_line();
if (clear_bg && final_attr != AT_NORMAL)
{
/*
* Writing the last character on the last line
* of the display may have scrolled the screen.
* If we were in standout mode, clear_bg terminals
* will fill the new line with the standout color.
* Now we're in normal mode again, so clear the line.
*/
clear_eol();
}
}
if (ignore_eoi)
hit_eof = 0;
else if (eof && !ABORT_SIGS())
hit_eof++;
else
eof_check();
if (nlines == 0)
eof_bell();
else if (do_repaint)
repaint();
first_time = 0;
(void) currline(BOTTOM);
}
/*
* Display n lines, scrolling backward.
*/
public void
back(n, pos, force, only_last)
register int n;
POSITION pos;
int force;
int only_last;
{
int nlines = 0;
int do_repaint;
squish_check();
do_repaint = (n > get_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;
}
/*
* Add the position of the previous line to the position table.
* Display the line on the screen.
*/
add_back_pos(pos);
nlines++;
if (!do_repaint)
{
home();
add_line();
put_line();
}
}
eof_check();
if (nlines == 0)
eof_bell();
else if (do_repaint)
repaint();
(void) currline(BOTTOM);
}
/*
* Display n more lines, forward.
* Start just after the line currently displayed at the bottom of the screen.
*/
public void
forward(n, force, only_last)
int n;
int force;
int only_last;
{
POSITION pos;
if (quit_at_eof && hit_eof && !(ch_getflags() & CH_HELPFILE))
{
/*
* If the -e flag is set and we're trying to go
* forward from end-of-file, go on to the next file.
*/
if (edit_next(1))
quit(QUIT_OK);
return;
}
pos = position(BOTTOM_PLUS_ONE);
if (pos == NULL_POSITION && (!force || empty_lines(2, sc_height-1)))
{
if (ignore_eoi)
{
/*
* ignore_eoi is to support A_F_FOREVER.
* Back up until there is a line at the bottom
* of the screen.
*/
if (empty_screen())
pos = ch_zero();
else
{
do
{
back(1, position(TOP), 1, 0);
pos = position(BOTTOM_PLUS_ONE);
} while (pos == NULL_POSITION);
}
} else
{
eof_bell();
hit_eof++;
return;
}
}
forw(n, pos, force, only_last, 0);
}
/*
* Display n more lines, backward.
* Start just before the line currently displayed at the top of the screen.
*/
public void
backward(n, force, only_last)
int n;
int force;
int only_last;
{
POSITION pos;
pos = position(TOP);
if (pos == NULL_POSITION && (!force || position(BOTTOM) == 0))
{
eof_bell();
return;
}
back(n, pos, force, only_last);
}
/*
* Get the backwards scroll limit.
* Must call this function instead of just using the value of
* back_scroll, because the default case depends on sc_height and
* top_scroll, as well as back_scroll.
*/
public int
get_back_scroll()
{
if (no_back_scroll)
return (0);
if (back_scroll >= 0)
return (back_scroll);
if (top_scroll)
return (sc_height - 2);
return (10000); /* infinity */
}

240
contrib/less/funcs.h Normal file
View File

@ -0,0 +1,240 @@
public char * save ();
public VOID_POINTER ecalloc ();
public char * skipsp ();
public int sprefix ();
public void quit ();
public void raw_mode ();
public void scrsize ();
public char * special_key_str ();
public void get_term ();
public void init ();
public void deinit ();
public void home ();
public void add_line ();
public void remove_top ();
public void lower_left ();
public void check_winch ();
public void goto_line ();
public void vbell ();
public void bell ();
public void clear ();
public void clear_eol ();
public void clear_bot ();
public void so_enter ();
public void so_exit ();
public void ul_enter ();
public void ul_exit ();
public void bo_enter ();
public void bo_exit ();
public void bl_enter ();
public void bl_exit ();
public void backspace ();
public void putbs ();
public char WIN32getch ();
public void match_brac ();
public void ch_ungetchar ();
public void end_logfile ();
public void sync_logfile ();
public int ch_seek ();
public int ch_end_seek ();
public int ch_beg_seek ();
public POSITION ch_length ();
public POSITION ch_tell ();
public int ch_forw_get ();
public int ch_back_get ();
public int ch_nbuf ();
public void ch_flush ();
public int seekable ();
public void ch_init ();
public void ch_close ();
public int ch_getflags ();
public void ch_dump ();
public void init_charset ();
public int binary_char ();
public int control_char ();
public char * prchar ();
public void cmd_reset ();
public void clear_cmd ();
public void cmd_putstr ();
public int len_cmdbuf ();
public void set_mlist ();
public void cmd_addhist ();
public void cmd_accept ();
public int cmd_char ();
public int cmd_int ();
public char * get_cmdbuf ();
public int in_mca ();
public void dispversion ();
public int getcc ();
public void ungetcc ();
public void ungetsc ();
public void commands ();
public void init_cmds ();
public void add_fcmd_table ();
public void add_ecmd_table ();
public int cmd_search ();
public int fcmd_decode ();
public int ecmd_decode ();
public char * lgetenv ();
public int lesskey ();
public void add_hometable ();
public int editchar ();
public void init_textlist ();
public char * forw_textlist ();
public char * back_textlist ();
public int edit ();
public int edit_ifile ();
public int edit_list ();
public int edit_first ();
public int edit_last ();
public int edit_next ();
public int edit_prev ();
public int edit_index ();
public IFILE save_curr_ifile ();
public void unsave_ifile ();
public void reedit_ifile ();
public int edit_stdin ();
public void cat_file ();
public void use_logfile ();
public char * unquote_file ();
public char * homefile ();
public char * fexpand ();
public char * fcomplete ();
public int bin_file ();
public char * esc_metachars ();
public char * esc_metachars ();
public char * lglob ();
public char * open_altfile ();
public void close_altfile ();
public int is_dir ();
public char * bad_file ();
public POSITION filesize ();
public void forw ();
public void back ();
public void forward ();
public void backward ();
public int get_back_scroll ();
public void del_ifile ();
public IFILE next_ifile ();
public IFILE prev_ifile ();
public IFILE getoff_ifile ();
public int nifile ();
public IFILE get_ifile ();
public char * get_filename ();
public int get_index ();
public void store_pos ();
public void get_pos ();
public void set_open ();
public int opened ();
public void hold_ifile ();
public int held_ifile ();
public void * get_filestate ();
public void set_filestate ();
public void if_dump ();
public POSITION forw_line ();
public POSITION back_line ();
public void set_attnpos ();
public void jump_forw ();
public void jump_back ();
public void repaint ();
public void jump_percent ();
public void jump_line_loc ();
public void jump_loc ();
public void init_line ();
public void prewind ();
public void plinenum ();
public int pappend ();
public void pdone ();
public int gline ();
public void null_line ();
public POSITION forw_raw_line ();
public POSITION back_raw_line ();
public void clr_linenum ();
public void add_lnum ();
public int find_linenum ();
public POSITION find_pos ();
public int currline ();
public void lsystem ();
public int pipe_mark ();
public int pipe_data ();
public void init_mark ();
public int badmark ();
public void setmark ();
public void lastmark ();
public void gomark ();
public POSITION markpos ();
public void unmark ();
public void opt_o ();
public void opt__O ();
public void opt_l ();
public void opt_k ();
public void opt_t ();
public void opt__T ();
public void opt_p ();
public void opt__P ();
public void opt_b ();
public void opt_i ();
public void opt__V ();
public void opt_D ();
public void opt_quote ();
public void opt_query ();
public int get_swindow ();
public void scan_option ();
public void toggle_option ();
public int single_char_option ();
public char * opt_prompt ();
public int isoptpending ();
public void nopendopt ();
public int getnum ();
public void init_option ();
public struct option * findopt ();
public struct option * findopt_name ();
public int iread ();
public void intread ();
public long get_time ();
public char * errno_message ();
public int percentage ();
public POSITION percent_pos ();
public int os9_signal ();
public int isatty ();
public void put_line ();
public void flush ();
public int putchr ();
public void putstr ();
public void get_return ();
public void error ();
public void ierror ();
public int query ();
public POSITION position ();
public void add_forw_pos ();
public void add_back_pos ();
public void pos_clear ();
public void pos_init ();
public int onscreen ();
public int empty_screen ();
public int empty_lines ();
public void get_scrpos ();
public int adjsline ();
public void init_prompt ();
public char * pr_expand ();
public char * eq_message ();
public char * pr_string ();
public void repaint_hilite ();
public void clear_attn ();
public void undo_search ();
public void clr_hilite ();
public int is_hilited ();
public void chg_caseless ();
public void chg_hilite ();
public int search ();
public void prep_hilite ();
public RETSIGTYPE winch ();
public RETSIGTYPE winch ();
public void init_signals ();
public void psignals ();
public void findtag ();
public int edit_tagfile ();
public POSITION tagsearch ();
public void open_getchr ();
public void close_getchr ();
public int getchr ();

214
contrib/less/help.c Normal file
View File

@ -0,0 +1,214 @@
/* This file was generated by mkhelp from less.hlp */
#include "less.h"
constant char helpdata[] = {
'\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','\b','S','U','\b','U','M','\b','M','M','\b','M','A','\b','A','R','\b','R','Y','\b','Y',' ','O','\b','O','F','\b','F',' ','L','\b','L','E','\b','E','S','\b','S','S','\b','S',' ','C','\b','C','O','\b','O','M','\b','M','M','\b','M','A','\b','A','N','\b','N','D','\b','D','S','\b','S','\n',
'\n',
' ',' ',' ',' ',' ',' ','C','o','m','m','a','n','d','s',' ','m','a','r','k','e','d',' ','w','i','t','h',' ','*',' ','m','a','y',' ','b','e',' ','p','r','e','c','e','d','e','d',' ','b','y',' ','a',' ','n','u','m','b','e','r',',',' ','_','\b','N','.','\n',
' ',' ',' ',' ',' ',' ','N','o','t','e','s',' ','i','n',' ','p','a','r','e','n','t','h','e','s','e','s',' ','i','n','d','i','c','a','t','e',' ','t','h','e',' ','b','e','h','a','v','i','o','r',' ','i','f',' ','_','\b','N',' ','i','s',' ','g','i','v','e','n','.','\n',
'\n',
' ',' ','h',' ',' ','H',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','t','h','i','s',' ','h','e','l','p','.','\n',
' ',' ','q',' ',' ',':','q',' ',' ','Q',' ',' ',':','Q',' ',' ','Z','Z',' ',' ',' ',' ',' ','E','x','i','t','.','\n',
' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
'\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','M','\b','M','O','\b','O','V','\b','V','I','\b','I','N','\b','N','G','\b','G','\n',
'\n',
' ',' ','e',' ',' ','^','E',' ',' ','j',' ',' ','^','N',' ',' ','C','R',' ',' ','*',' ',' ','F','o','r','w','a','r','d',' ',' ','o','n','e',' ','l','i','n','e',' ',' ',' ','(','o','r',' ','_','\b','N',' ','l','i','n','e','s',')','.','\n',
' ',' ','y',' ',' ','^','Y',' ',' ','k',' ',' ','^','K',' ',' ','^','P',' ',' ','*',' ',' ','B','a','c','k','w','a','r','d',' ','o','n','e',' ','l','i','n','e',' ',' ',' ','(','o','r',' ','_','\b','N',' ','l','i','n','e','s',')','.','\n',
' ',' ','f',' ',' ','^','F',' ',' ','^','V',' ',' ','S','P','A','C','E',' ',' ','*',' ',' ','F','o','r','w','a','r','d',' ',' ','o','n','e',' ','w','i','n','d','o','w',' ','(','o','r',' ','_','\b','N',' ','l','i','n','e','s',')','.','\n',
' ',' ','b',' ',' ','^','B',' ',' ','E','S','C','-','v',' ',' ',' ',' ',' ',' ','*',' ',' ','B','a','c','k','w','a','r','d',' ','o','n','e',' ','w','i','n','d','o','w',' ','(','o','r',' ','_','\b','N',' ','l','i','n','e','s',')','.','\n',
' ',' ','z',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','F','o','r','w','a','r','d',' ',' ','o','n','e',' ','w','i','n','d','o','w',' ','(','a','n','d',' ','s','e','t',' ','w','i','n','d','o','w',' ','t','o',' ','_','\b','N',')','.','\n',
' ',' ','w',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','B','a','c','k','w','a','r','d',' ','o','n','e',' ','w','i','n','d','o','w',' ','(','a','n','d',' ','s','e','t',' ','w','i','n','d','o','w',' ','t','o',' ','_','\b','N',')','.','\n',
' ',' ','E','S','C','-','S','P','A','C','E',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','F','o','r','w','a','r','d',' ',' ','o','n','e',' ','w','i','n','d','o','w',',',' ','b','u','t',' ','d','o','n','\'','t',' ','s','t','o','p',' ','a','t',' ','e','n','d','-','o','f','-','f','i','l','e','.','\n',
' ',' ','d',' ',' ','^','D',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','F','o','r','w','a','r','d',' ',' ','o','n','e',' ','h','a','l','f','-','w','i','n','d','o','w',' ','(','a','n','d',' ','s','e','t',' ','h','a','l','f','-','w','i','n','d','o','w',' ','t','o',' ','_','\b','N',')','.','\n',
' ',' ','u',' ',' ','^','U',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','B','a','c','k','w','a','r','d',' ','o','n','e',' ','h','a','l','f','-','w','i','n','d','o','w',' ','(','a','n','d',' ','s','e','t',' ','h','a','l','f','-','w','i','n','d','o','w',' ','t','o',' ','_','\b','N',')','.','\n',
' ',' ','E','S','C','-','(',' ',' ','R','i','g','h','t','A','r','r','o','w',' ','*',' ',' ','L','e','f','t',' ',' ','8',' ','c','h','a','r','a','c','t','e','r',' ','p','o','s','i','t','i','o','n','s',' ','(','o','r',' ','_','\b','N',' ','p','o','s','i','t','i','o','n','s',')','.','\n',
' ',' ','E','S','C','-',')',' ',' ','L','e','f','t','A','r','r','o','w',' ',' ','*',' ',' ','R','i','g','h','t',' ','8',' ','c','h','a','r','a','c','t','e','r',' ','p','o','s','i','t','i','o','n','s',' ','(','o','r',' ','_','\b','N',' ','p','o','s','i','t','i','o','n','s',')','.','\n',
' ',' ','F',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','F','o','r','w','a','r','d',' ','f','o','r','e','v','e','r',';',' ','l','i','k','e',' ','"','t','a','i','l',' ','-','f','"','.','\n',
' ',' ','r',' ',' ','^','R',' ',' ','^','L',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','p','a','i','n','t',' ','s','c','r','e','e','n','.','\n',
' ',' ','R',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','p','a','i','n','t',' ','s','c','r','e','e','n',',',' ','d','i','s','c','a','r','d','i','n','g',' ','b','u','f','f','e','r','e','d',' ','i','n','p','u','t','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
' ',' ',' ',' ',' ',' ',' ',' ','D','e','f','a','u','l','t',' ','"','w','i','n','d','o','w','"',' ','i','s',' ','t','h','e',' ','s','c','r','e','e','n',' ','h','e','i','g','h','t','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','D','e','f','a','u','l','t',' ','"','h','a','l','f','-','w','i','n','d','o','w','"',' ','i','s',' ','h','a','l','f',' ','o','f',' ','t','h','e',' ','s','c','r','e','e','n',' ','h','e','i','g','h','t','.','\n',
' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
'\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','\b','S','E','\b','E','A','\b','A','R','\b','R','C','\b','C','H','\b','H','I','\b','I','N','\b','N','G','\b','G','\n',
'\n',
' ',' ','/','_','\b','p','_','\b','a','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','S','e','a','r','c','h',' ','f','o','r','w','a','r','d',' ','f','o','r',' ','(','_','\b','N','-','t','h',')',' ','m','a','t','c','h','i','n','g',' ','l','i','n','e','.','\n',
' ',' ','?','_','\b','p','_','\b','a','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','S','e','a','r','c','h',' ','b','a','c','k','w','a','r','d',' ','f','o','r',' ','(','_','\b','N','-','t','h',')',' ','m','a','t','c','h','i','n','g',' ','l','i','n','e','.','\n',
' ',' ','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','R','e','p','e','a','t',' ','p','r','e','v','i','o','u','s',' ','s','e','a','r','c','h',' ','(','f','o','r',' ','_','\b','N','-','t','h',' ','o','c','c','u','r','r','e','n','c','e',')','.','\n',
' ',' ','N',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','R','e','p','e','a','t',' ','p','r','e','v','i','o','u','s',' ','s','e','a','r','c','h',' ','i','n',' ','r','e','v','e','r','s','e',' ','d','i','r','e','c','t','i','o','n','.','\n',
' ',' ','E','S','C','-','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','R','e','p','e','a','t',' ','p','r','e','v','i','o','u','s',' ','s','e','a','r','c','h',',',' ','s','p','a','n','n','i','n','g',' ','f','i','l','e','s','.','\n',
' ',' ','E','S','C','-','N',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','R','e','p','e','a','t',' ','p','r','e','v','i','o','u','s',' ','s','e','a','r','c','h',',',' ','r','e','v','e','r','s','e',' ','d','i','r','.',' ','&',' ','s','p','a','n','n','i','n','g',' ','f','i','l','e','s','.','\n',
' ',' ','E','S','C','-','u',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','n','d','o',' ','(','t','o','g','g','l','e',')',' ','s','e','a','r','c','h',' ','h','i','g','h','l','i','g','h','t','i','n','g','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
' ',' ',' ',' ',' ',' ',' ',' ','S','e','a','r','c','h',' ','p','a','t','t','e','r','n','s',' ','m','a','y',' ','b','e',' ','m','o','d','i','f','i','e','d',' ','b','y',' ','o','n','e',' ','o','r',' ','m','o','r','e',' ','o','f',':','\n',
' ',' ',' ',' ',' ',' ',' ',' ','^','N',' ','o','r',' ','!',' ',' ','S','e','a','r','c','h',' ','f','o','r',' ','N','O','N','-','m','a','t','c','h','i','n','g',' ','l','i','n','e','s','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','^','E',' ','o','r',' ','*',' ',' ','S','e','a','r','c','h',' ','m','u','l','t','i','p','l','e',' ','f','i','l','e','s',' ','(','p','a','s','s',' ','t','h','r','u',' ','E','N','D',' ','O','F',' ','F','I','L','E',')','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','^','F',' ','o','r',' ','@',' ',' ','S','t','a','r','t',' ','s','e','a','r','c','h',' ','a','t',' ','F','I','R','S','T',' ','f','i','l','e',' ','(','f','o','r',' ','/',')',' ','o','r',' ','l','a','s','t',' ','f','i','l','e',' ','(','f','o','r',' ','?',')','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','^','K',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','m','a','t','c','h','e','s',',',' ','b','u','t',' ','d','o','n','\'','t',' ','m','o','v','e',' ','(','K','E','E','P',' ','p','o','s','i','t','i','o','n',')','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','^','R',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','u','s','e',' ','R','E','G','U','L','A','R',' ','E','X','P','R','E','S','S','I','O','N','S','.','\n',
' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
'\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','J','\b','J','U','\b','U','M','\b','M','P','\b','P','I','\b','I','N','\b','N','G','\b','G','\n',
'\n',
' ',' ','g',' ',' ','<',' ',' ','E','S','C','-','<',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','G','o',' ','t','o',' ','f','i','r','s','t',' ','l','i','n','e',' ','i','n',' ','f','i','l','e',' ','(','o','r',' ','l','i','n','e',' ','_','\b','N',')','.','\n',
' ',' ','G',' ',' ','>',' ',' ','E','S','C','-','>',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','G','o',' ','t','o',' ','l','a','s','t',' ','l','i','n','e',' ','i','n',' ','f','i','l','e',' ','(','o','r',' ','l','i','n','e',' ','_','\b','N',')','.','\n',
' ',' ','p',' ',' ','%',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','G','o',' ','t','o',' ','b','e','g','i','n','n','i','n','g',' ','o','f',' ','f','i','l','e',' ','(','o','r',' ','_','\b','N',' ','p','e','r','c','e','n','t',' ','i','n','t','o',' ','f','i','l','e',')','.','\n',
' ',' ','{',' ',' ','(',' ',' ','[',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','F','i','n','d',' ','c','l','o','s','e',' ','b','r','a','c','k','e','t',' ','}',' ',')',' ',']','.','\n',
' ',' ','}',' ',' ',')',' ',' ',']',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','F','i','n','d',' ','o','p','e','n',' ','b','r','a','c','k','e','t',' ','{',' ','(',' ','[','.','\n',
' ',' ','E','S','C','-','^','F',' ','_','\b','<','_','\b','c','_','\b','1','_','\b','>',' ','_','\b','<','_','\b','c','_','\b','2','_','\b','>',' ',' ','*',' ',' ','F','i','n','d',' ','c','l','o','s','e',' ','b','r','a','c','k','e','t',' ','_','\b','<','_','\b','c','_','\b','2','_','\b','>','.','\n',
' ',' ','E','S','C','-','^','B',' ','_','\b','<','_','\b','c','_','\b','1','_','\b','>',' ','_','\b','<','_','\b','c','_','\b','2','_','\b','>',' ',' ','*',' ',' ','F','i','n','d',' ','o','p','e','n',' ','b','r','a','c','k','e','t',' ','_','\b','<','_','\b','c','_','\b','1','_','\b','>',' ','\n',
' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
' ',' ',' ',' ',' ',' ',' ',' ','E','a','c','h',' ','"','f','i','n','d',' ','c','l','o','s','e',' ','b','r','a','c','k','e','t','"',' ','c','o','m','m','a','n','d',' ','g','o','e','s',' ','f','o','r','w','a','r','d',' ','t','o',' ','t','h','e',' ','c','l','o','s','e',' ','b','r','a','c','k','e','t',' ','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','m','a','t','c','h','i','n','g',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','o','p','e','n',' ','b','r','a','c','k','e','t',' ','i','n',' ','t','h','e',' ','t','o','p',' ','l','i','n','e','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','E','a','c','h',' ','"','f','i','n','d',' ','o','p','e','n',' ','b','r','a','c','k','e','t','"',' ','c','o','m','m','a','n','d',' ','g','o','e','s',' ','b','a','c','k','w','a','r','d',' ','t','o',' ','t','h','e',' ','o','p','e','n',' ','b','r','a','c','k','e','t',' ','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','m','a','t','c','h','i','n','g',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','c','l','o','s','e',' ','b','r','a','c','k','e','t',' ','i','n',' ','t','h','e',' ','b','o','t','t','o','m',' ','l','i','n','e','.','\n',
'\n',
' ',' ','m','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','M','a','r','k',' ','t','h','e',' ','c','u','r','r','e','n','t',' ','p','o','s','i','t','i','o','n',' ','w','i','t','h',' ','<','l','e','t','t','e','r','>','.','\n',
' ',' ','\'','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','G','o',' ','t','o',' ','a',' ','p','r','e','v','i','o','u','s','l','y',' ','m','a','r','k','e','d',' ','p','o','s','i','t','i','o','n','.','\n',
' ',' ','\'','\'',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','G','o',' ','t','o',' ','t','h','e',' ','p','r','e','v','i','o','u','s',' ','p','o','s','i','t','i','o','n','.','\n',
' ',' ','^','X','^','X',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','a','m','e',' ','a','s',' ','\'','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
' ',' ',' ',' ',' ',' ',' ',' ','A',' ','m','a','r','k',' ','i','s',' ','a','n','y',' ','u','p','p','e','r','-','c','a','s','e',' ','o','r',' ','l','o','w','e','r','-','c','a','s','e',' ','l','e','t','t','e','r','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','C','e','r','t','a','i','n',' ','m','a','r','k','s',' ','a','r','e',' ','p','r','e','d','e','f','i','n','e','d',':','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','^',' ',' ','m','e','a','n','s',' ',' ','b','e','g','i','n','n','i','n','g',' ','o','f',' ','t','h','e',' ','f','i','l','e','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','$',' ',' ','m','e','a','n','s',' ',' ','e','n','d',' ','o','f',' ','t','h','e',' ','f','i','l','e','\n',
' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
'\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','\b','C','H','\b','H','A','\b','A','N','\b','N','G','\b','G','I','\b','I','N','\b','N','G','\b','G',' ','F','\b','F','I','\b','I','L','\b','L','E','\b','E','S','\b','S','\n',
'\n',
' ',' ',':','e',' ','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','a','m','i','n','e',' ','a',' ','n','e','w',' ','f','i','l','e','.','\n',
' ',' ','^','X','^','V',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','a','m','e',' ','a','s',' ',':','e','.','\n',
' ',' ',':','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','E','x','a','m','i','n','e',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','n','e','x','t',' ','f','i','l','e',' ','f','r','o','m',' ','t','h','e',' ','c','o','m','m','a','n','d',' ','l','i','n','e','.','\n',
' ',' ',':','p',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','E','x','a','m','i','n','e',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','p','r','e','v','i','o','u','s',' ','f','i','l','e',' ','f','r','o','m',' ','t','h','e',' ','c','o','m','m','a','n','d',' ','l','i','n','e','.','\n',
' ',' ',':','x',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','E','x','a','m','i','n','e',' ','t','h','e',' ','f','i','r','s','t',' ','(','o','r',' ','_','\b','N','-','t','h',')',' ','f','i','l','e',' ','f','r','o','m',' ','t','h','e',' ','c','o','m','m','a','n','d',' ','l','i','n','e','.','\n',
' ',' ',':','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','e','l','e','t','e',' ','t','h','e',' ','c','u','r','r','e','n','t',' ','f','i','l','e',' ','f','r','o','m',' ','t','h','e',' ','c','o','m','m','a','n','d',' ','l','i','n','e',' ','l','i','s','t','.','\n',
' ',' ','=',' ',' ','^','G',' ',' ',':','f',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','P','r','i','n','t',' ','c','u','r','r','e','n','t',' ','f','i','l','e',' ','n','a','m','e','.','\n',
' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
'\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','M','\b','M','I','\b','I','S','\b','S','C','\b','C','E','\b','E','L','\b','L','L','\b','L','A','\b','A','N','\b','N','E','\b','E','O','\b','O','U','\b','U','S','\b','S',' ','C','\b','C','O','\b','O','M','\b','M','M','\b','M','A','\b','A','N','\b','N','D','\b','D','S','\b','S','\n',
'\n',
' ',' ','-','_','\b','<','_','\b','f','_','\b','l','_','\b','a','_','\b','g','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','T','o','g','g','l','e',' ','a',' ','c','o','m','m','a','n','d',' ','l','i','n','e',' ','o','p','t','i','o','n',' ','[','s','e','e',' ','O','P','T','I','O','N','S',' ','b','e','l','o','w',']','.','\n',
' ',' ','-','-','_','\b','<','_','\b','n','_','\b','a','_','\b','m','_','\b','e','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','T','o','g','g','l','e',' ','a',' ','c','o','m','m','a','n','d',' ','l','i','n','e',' ','o','p','t','i','o','n',',',' ','b','y',' ','n','a','m','e','.','\n',
' ',' ','_','_','\b','<','_','\b','f','_','\b','l','_','\b','a','_','\b','g','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','t','h','e',' ','s','e','t','t','i','n','g',' ','o','f',' ','a',' ','c','o','m','m','a','n','d',' ','l','i','n','e',' ','o','p','t','i','o','n','.','\n',
' ',' ','_','_','_','\b','<','_','\b','n','_','\b','a','_','\b','m','_','\b','e','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','t','h','e',' ','s','e','t','t','i','n','g',' ','o','f',' ','a','n',' ','o','p','t','i','o','n',',',' ','b','y',' ','n','a','m','e','.','\n',
' ',' ','+','_','\b','c','_','\b','m','_','\b','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','e','c','u','t','e',' ','t','h','e',' ','l','e','s','s',' ','c','m','d',' ','e','a','c','h',' ','t','i','m','e',' ','a',' ','n','e','w',' ','f','i','l','e',' ','i','s',' ','e','x','a','m','i','n','e','d','.','\n',
'\n',
' ',' ','!','_','\b','c','_','\b','o','_','\b','m','_','\b','m','_','\b','a','_','\b','n','_','\b','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','e','c','u','t','e',' ','t','h','e',' ','s','h','e','l','l',' ','c','o','m','m','a','n','d',' ','w','i','t','h',' ','$','S','H','E','L','L','.','\n',
' ',' ','|','X','\b','X','_','\b','c','_','\b','o','_','\b','m','_','\b','m','_','\b','a','_','\b','n','_','\b','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','P','i','p','e',' ','f','i','l','e',' ','b','e','t','w','e','e','n',' ','c','u','r','r','e','n','t',' ','p','o','s',' ','&',' ','m','a','r','k',' ','X','\b','X',' ','t','o',' ','s','h','e','l','l',' ','c','o','m','m','a','n','d','.','\n',
' ',' ','v',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','d','i','t',' ','t','h','e',' ','c','u','r','r','e','n','t',' ','f','i','l','e',' ','w','i','t','h',' ','$','V','I','S','U','A','L',' ','o','r',' ','$','E','D','I','T','O','R','.','\n',
' ',' ','V',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','P','r','i','n','t',' ','v','e','r','s','i','o','n',' ','n','u','m','b','e','r',' ','o','f',' ','"','l','e','s','s','"','.','\n',
' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
'\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','O','\b','O','P','\b','P','T','\b','T','I','\b','I','O','\b','O','N','\b','N','S','\b','S','\n',
'\n',
' ',' ',' ',' ',' ',' ',' ',' ','M','o','s','t',' ','o','p','t','i','o','n','s',' ','m','a','y',' ','b','e',' ','c','h','a','n','g','e','d',' ','e','i','t','h','e','r',' ','o','n',' ','t','h','e',' ','c','o','m','m','a','n','d',' ','l','i','n','e',',','\n',
' ',' ',' ',' ',' ',' ',' ',' ','o','r',' ','f','r','o','m',' ','w','i','t','h','i','n',' ','l','e','s','s',' ','b','y',' ','u','s','i','n','g',' ','t','h','e',' ','-',' ','o','r',' ','-','-',' ','c','o','m','m','a','n','d','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','O','p','t','i','o','n','s',' ','m','a','y',' ','b','e',' ','g','i','v','e','n',' ','i','n',' ','o','n','e',' ','o','f',' ','t','w','o',' ','f','o','r','m','s',':',' ','e','i','t','h','e','r',' ','a',' ','s','i','n','g','l','e','\n',
' ',' ',' ',' ',' ',' ',' ',' ','c','h','a','r','a','c','t','e','r',' ','p','r','e','c','e','d','e','d',' ','b','y',' ','a',' ','-',',',' ','o','r',' ','a',' ','n','a','m','e',' ','p','r','e','c','e','e','d','e','d',' ','b','y',' ','-','-','.','\n',
'\n',
' ',' ','-','?',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','h','e','l','p','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','h','e','l','p',' ','(','f','r','o','m',' ','c','o','m','m','a','n','d',' ','l','i','n','e',')','.','\n',
' ',' ','-','a',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','s','e','a','r','c','h','-','s','k','i','p','-','s','c','r','e','e','n','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','F','o','r','w','a','r','d',' ','s','e','a','r','c','h',' ','s','k','i','p','s',' ','c','u','r','r','e','n','t',' ','s','c','r','e','e','n','.','\n',
' ',' ','-','b',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','b','u','f','f','e','r','s','=','[','_','\b','N',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','N','u','m','b','e','r',' ','o','f',' ','b','u','f','f','e','r','s','.','\n',
' ',' ','-','B',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','a','u','t','o','-','b','u','f','f','e','r','s','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','a','u','t','o','m','a','t','i','c','a','l','l','y',' ','a','l','l','o','c','a','t','e',' ','b','u','f','f','e','r','s',' ','f','o','r',' ','p','i','p','e','s','.','\n',
' ',' ','-','c',' ',' ','-','C',' ',' ','.','.','.','.',' ',' ','-','-','c','l','e','a','r','-','s','c','r','e','e','n',' ',' ','-','-','C','L','E','A','R','-','S','C','R','E','E','N','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','p','a','i','n','t',' ','b','y',' ','s','c','r','o','l','l','i','n','g','/','c','l','e','a','r','i','n','g','.','\n',
' ',' ','-','d',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','d','u','m','b','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','u','m','b',' ','t','e','r','m','i','n','a','l','.','\n',
' ',' ','-','D',' ','[','_','\b','x','_','\b','n','_','\b','.','_','\b','n',']',' ',' ','.',' ',' ','-','-','c','o','l','o','r','=','_','\b','x','_','\b','n','_','\b','.','_','\b','n','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','s','c','r','e','e','n',' ','c','o','l','o','r','s','.',' ','(','M','S','-','D','O','S',' ','o','n','l','y',')','\n',
' ',' ','-','e',' ',' ','-','E',' ',' ','.','.','.','.',' ',' ','-','-','q','u','i','t','-','a','t','-','e','o','f',' ',' ','-','-','Q','U','I','T','-','A','T','-','E','O','F','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','Q','u','i','t',' ','a','t',' ','e','n','d',' ','o','f',' ','f','i','l','e','.','\n',
' ',' ','-','f',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','f','o','r','c','e','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','F','o','r','c','e',' ','o','p','e','n',' ','n','o','n','-','r','e','g','u','l','a','r',' ','f','i','l','e','s','.','\n',
' ',' ','-','F',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','q','u','i','t','-','i','f','-','o','n','e','-','s','c','r','e','e','n','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','Q','u','i','t',' ','i','f',' ','e','n','t','i','r','e',' ','f','i','l','e',' ','f','i','t','s',' ','o','n',' ','f','i','r','s','t',' ','s','c','r','e','e','n','.','\n',
' ',' ','-','g',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','h','i','l','i','t','e','-','s','e','a','r','c','h','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','o','n','l','y',' ','l','a','s','t',' ','m','a','t','c','h',' ','f','o','r',' ','s','e','a','r','c','h','e','s','.','\n',
' ',' ','-','G',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','H','I','L','I','T','E','-','S','E','A','R','C','H','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','h','i','g','h','l','i','g','h','t',' ','a','n','y',' ','m','a','t','c','h','e','s',' ','f','o','r',' ','s','e','a','r','c','h','e','s','.','\n',
' ',' ','-','h',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','m','a','x','-','b','a','c','k','-','s','c','r','o','l','l','=','[','_','\b','N',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','B','a','c','k','w','a','r','d',' ','s','c','r','o','l','l',' ','l','i','m','i','t','.','\n',
' ',' ','-','i',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','i','g','n','o','r','e','-','c','a','s','e','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','I','g','n','o','r','e',' ','c','a','s','e',' ','i','n',' ','s','e','a','r','c','h','e','s',' ','t','h','a','t',' ','d','o',' ','n','o','t',' ','c','o','n','t','a','i','n',' ','u','p','p','e','r','c','a','s','e','.','\n',
' ',' ','-','I',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','I','G','N','O','R','E','-','C','A','S','E','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','I','g','n','o','r','e',' ','c','a','s','e',' ','i','n',' ','a','l','l',' ','s','e','a','r','c','h','e','s','.','\n',
' ',' ','-','j',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','j','u','m','p','-','t','a','r','g','e','t','=','[','_','\b','N',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','c','r','e','e','n',' ','p','o','s','i','t','i','o','n',' ','o','f',' ','t','a','r','g','e','t',' ','l','i','n','e','s','.','\n',
' ',' ','-','k',' ','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ',' ','.',' ',' ','-','-','l','e','s','s','k','e','y','-','f','i','l','e','=','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','s','e',' ','a',' ','l','e','s','s','k','e','y',' ','f','i','l','e','.','\n',
' ',' ','-','m',' ',' ','-','M',' ',' ','.','.','.','.',' ',' ','-','-','l','o','n','g','-','p','r','o','m','p','t',' ',' ','-','-','L','O','N','G','-','P','R','O','M','P','T','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','p','r','o','m','p','t',' ','s','t','y','l','e','.','\n',
' ',' ','-','n',' ',' ','-','N',' ',' ','.','.','.','.',' ',' ','-','-','l','i','n','e','-','n','u','m','b','e','r','s',' ',' ','-','-','L','I','N','E','-','N','U','M','B','E','R','S','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','s','e',' ','l','i','n','e',' ','n','u','m','b','e','r','s','.','\n',
' ',' ','-','o',' ','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ',' ','.',' ',' ','-','-','l','o','g','-','f','i','l','e','=','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','o','p','y',' ','t','o',' ','l','o','g',' ','f','i','l','e',' ','(','s','t','a','n','d','a','r','d',' ','i','n','p','u','t',' ','o','n','l','y',')','.','\n',
' ',' ','-','O',' ','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ',' ','.',' ',' ','-','-','L','O','G','-','F','I','L','E','=','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','o','p','y',' ','t','o',' ','l','o','g',' ','f','i','l','e',' ','(','u','n','c','o','n','d','i','t','i','o','n','a','l','l','y',' ','o','v','e','r','w','r','i','t','e',')','.','\n',
' ',' ','-','p',' ','[','_','\b','p','_','\b','a','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','n',']',' ',' ','-','-','p','a','t','t','e','r','n','=','[','_','\b','p','_','\b','a','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','n',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','t','a','r','t',' ','a','t',' ','p','a','t','t','e','r','n',' ','(','f','r','o','m',' ','c','o','m','m','a','n','d',' ','l','i','n','e',')','.','\n',
' ',' ','-','P',' ','[','_','\b','p','_','\b','r','_','\b','o','_','\b','m','_','\b','p','_','\b','t',']',' ',' ',' ','-','-','p','r','o','m','p','t','=','[','_','\b','p','_','\b','r','_','\b','o','_','\b','m','_','\b','p','_','\b','t',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','e','f','i','n','e',' ','n','e','w',' ','p','r','o','m','p','t','.','\n',
' ',' ','-','q',' ',' ','-','Q',' ',' ','.','.','.','.',' ',' ','-','-','q','u','i','e','t',' ',' ','-','-','Q','U','I','E','T',' ',' ','-','-','s','i','l','e','n','t',' ','-','-','S','I','L','E','N','T','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','Q','u','i','e','t',' ','t','h','e',' ','t','e','r','m','i','n','a','l',' ','b','e','l','l','.','\n',
' ',' ','-','r',' ',' ','-','R',' ',' ','.','.','.','.',' ',' ','-','-','r','a','w','-','c','o','n','t','r','o','l','-','c','h','a','r','s',' ',' ','-','-','R','A','W','-','C','O','N','T','R','O','L','-','C','H','A','R','S','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','O','u','t','p','u','t',' ','"','r','a','w','"',' ','c','o','n','t','r','o','l',' ','c','h','a','r','a','c','t','e','r','s','.','\n',
' ',' ','-','s',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','s','q','u','e','e','z','e','-','b','l','a','n','k','-','l','i','n','e','s','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','q','u','e','e','z','e',' ','m','u','l','t','i','p','l','e',' ','b','l','a','n','k',' ','l','i','n','e','s','.','\n',
' ',' ','-','S',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','c','h','o','p','-','l','o','n','g','-','l','i','n','e','s','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','h','o','p',' ','l','o','n','g',' ','l','i','n','e','s','.','\n',
' ',' ','-','t',' ','[','_','\b','t','_','\b','a','_','\b','g',']',' ',' ','.','.',' ',' ','-','-','t','a','g','=','[','_','\b','t','_','\b','a','_','\b','g',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','F','i','n','d',' ','a',' ','t','a','g','.','\n',
' ',' ','-','T',' ','[','_','\b','t','_','\b','a','_','\b','g','_','\b','s','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ','-','-','t','a','g','-','f','i','l','e','=','[','_','\b','t','_','\b','a','_','\b','g','_','\b','s','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','s','e',' ','a','n',' ','a','l','t','e','r','n','a','t','e',' ','t','a','g','s',' ','f','i','l','e','.','\n',
' ',' ','-','u',' ',' ','-','U',' ',' ','.','.','.','.',' ',' ','-','-','u','n','d','e','r','l','i','n','e','-','s','p','e','c','i','a','l',' ',' ','-','-','U','N','D','E','R','L','I','N','E','-','S','P','E','C','I','A','L','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','h','a','n','g','e',' ','h','a','n','d','l','i','n','g',' ','o','f',' ','b','a','c','k','s','p','a','c','e','s','.','\n',
' ',' ','-','V',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','v','e','r','s','i','o','n','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','t','h','e',' ','v','e','r','s','i','o','n',' ','n','u','m','b','e','r',' ','o','f',' ','"','l','e','s','s','"','.','\n',
' ',' ','-','w',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','h','i','l','i','t','e','-','u','n','r','e','a','d','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','f','i','r','s','t',' ','n','e','w',' ','l','i','n','e',' ','a','f','t','e','r',' ','f','o','r','w','a','r','d','-','s','c','r','e','e','n','.','\n',
' ',' ','-','W',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','H','I','L','I','T','E','-','U','N','R','E','A','D','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','f','i','r','s','t',' ','n','e','w',' ','l','i','n','e',' ','a','f','t','e','r',' ','a','n','y',' ','f','o','r','w','a','r','d',' ','m','o','v','e','m','e','n','t','.','\n',
' ',' ','-','x',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','t','a','b','s','=','[','_','\b','N',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','t','a','b',' ','s','t','o','p','s','.','\n',
' ',' ','-','X',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','n','o','-','i','n','i','t','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','u','s','e',' ','t','e','r','m','c','a','p',' ','i','n','i','t','/','d','e','i','n','i','t',' ','s','t','r','i','n','g','s','.','\n',
' ',' ','-','y',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','m','a','x','-','f','o','r','w','-','s','c','r','o','l','l','=','[','_','\b','N',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','F','o','r','w','a','r','d',' ','s','c','r','o','l','l',' ','l','i','m','i','t','.','\n',
' ',' ','-','z',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','w','i','n','d','o','w','=','[','_','\b','N',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','s','i','z','e',' ','o','f',' ','w','i','n','d','o','w','.','\n',
' ',' ','-','"',' ','[','_','\b','c','[','_','\b','c',']',']',' ',' ','.',' ',' ','-','-','q','u','o','t','e','s','=','[','_','\b','c','[','_','\b','c',']',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','s','h','e','l','l',' ','q','u','o','t','e',' ','c','h','a','r','a','c','t','e','r','s','.','\n',
' ',' ','-','~',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','t','i','l','d','e','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','d','i','s','p','l','a','y',' ','t','i','l','d','e','s',' ','a','f','t','e','r',' ','e','n','d',' ','o','f',' ','f','i','l','e','.','\n',
' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
'\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','L','\b','L','I','\b','I','N','\b','N','E','\b','E',' ','E','\b','E','D','\b','D','I','\b','I','T','\b','T','I','\b','I','N','\b','N','G','\b','G','\n',
'\n',
' ',' ',' ',' ',' ',' ',' ',' ','T','h','e','s','e',' ','k','e','y','s',' ','c','a','n',' ','b','e',' ','u','s','e','d',' ','t','o',' ','e','d','i','t',' ','t','e','x','t',' ','b','e','i','n','g',' ','e','n','t','e','r','e','d',' ','\n',
' ',' ',' ',' ',' ',' ',' ',' ','o','n',' ','t','h','e',' ','"','c','o','m','m','a','n','d',' ','l','i','n','e','"',' ','a','t',' ','t','h','e',' ','b','o','t','t','o','m',' ','o','f',' ','t','h','e',' ','s','c','r','e','e','n','.','\n',
'\n',
' ','R','i','g','h','t','A','r','r','o','w',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','S','C','-','l',' ',' ',' ',' ',' ','M','o','v','e',' ','c','u','r','s','o','r',' ','r','i','g','h','t',' ','o','n','e',' ','c','h','a','r','a','c','t','e','r','.','\n',
' ','L','e','f','t','A','r','r','o','w',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','S','C','-','h',' ',' ',' ',' ',' ','M','o','v','e',' ','c','u','r','s','o','r',' ','l','e','f','t',' ','o','n','e',' ','c','h','a','r','a','c','t','e','r','.','\n',
' ','C','N','T','L','-','R','i','g','h','t','A','r','r','o','w',' ',' ','E','S','C','-','R','i','g','h','t','A','r','r','o','w',' ',' ','E','S','C','-','w',' ',' ',' ',' ',' ','M','o','v','e',' ','c','u','r','s','o','r',' ','r','i','g','h','t',' ','o','n','e',' ','w','o','r','d','.','\n',
' ','C','N','T','L','-','L','e','f','t','A','r','r','o','w',' ',' ',' ','E','S','C','-','L','e','f','t','A','r','r','o','w',' ',' ',' ','E','S','C','-','b',' ',' ',' ',' ',' ','M','o','v','e',' ','c','u','r','s','o','r',' ','l','e','f','t',' ','o','n','e',' ','w','o','r','d','.','\n',
' ','H','O','M','E',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','S','C','-','0',' ',' ',' ',' ',' ','M','o','v','e',' ','c','u','r','s','o','r',' ','t','o',' ','s','t','a','r','t',' ','o','f',' ','l','i','n','e','.','\n',
' ','E','N','D',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','S','C','-','$',' ',' ',' ',' ',' ','M','o','v','e',' ','c','u','r','s','o','r',' ','t','o',' ','e','n','d',' ','o','f',' ','l','i','n','e','.','\n',
' ','B','A','C','K','S','P','A','C','E',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','e','l','e','t','e',' ','c','h','a','r',' ','t','o',' ','l','e','f','t',' ','o','f',' ','c','u','r','s','o','r','.','\n',
' ','D','E','L','E','T','E',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','S','C','-','x',' ',' ',' ',' ',' ','D','e','l','e','t','e',' ','c','h','a','r',' ','u','n','d','e','r',' ','c','u','r','s','o','r','.','\n',
' ','C','N','T','L','-','B','A','C','K','S','P','A','C','E',' ',' ',' ','E','S','C','-','B','A','C','K','S','P','A','C','E',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','e','l','e','t','e',' ','w','o','r','d',' ','t','o',' ','l','e','f','t',' ','o','f',' ','c','u','r','s','o','r','.','\n',
' ','C','N','T','L','-','D','E','L','E','T','E',' ',' ',' ',' ',' ',' ','E','S','C','-','D','E','L','E','T','E',' ',' ',' ',' ',' ',' ','E','S','C','-','X',' ',' ',' ',' ',' ','D','e','l','e','t','e',' ','w','o','r','d',' ','u','n','d','e','r',' ','c','u','r','s','o','r','.','\n',
' ','C','N','T','L','-','U',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','S','C',' ','(','M','S','-','D','O','S',' ','o','n','l','y',')',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','e','l','e','t','e',' ','e','n','t','i','r','e',' ','l','i','n','e','.','\n',
' ','U','p','A','r','r','o','w',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','S','C','-','k',' ',' ',' ',' ',' ','R','e','t','r','i','e','v','e',' ','p','r','e','v','i','o','u','s',' ','c','o','m','m','a','n','d',' ','l','i','n','e','.','\n',
' ','D','o','w','n','A','r','r','o','w',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','S','C','-','j',' ',' ',' ',' ',' ','R','e','t','r','i','e','v','e',' ','n','e','x','t',' ','c','o','m','m','a','n','d',' ','l','i','n','e','.','\n',
' ','T','A','B',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','o','m','p','l','e','t','e',' ','f','i','l','e','n','a','m','e',' ','&',' ','c','y','c','l','e','.','\n',
' ','S','H','I','F','T','-','T','A','B',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','S','C','-','T','A','B',' ',' ',' ','C','o','m','p','l','e','t','e',' ','f','i','l','e','n','a','m','e',' ','&',' ','r','e','v','e','r','s','e',' ','c','y','c','l','e','.','\n',
' ','C','N','T','L','-','L',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','o','m','p','l','e','t','e',' ','f','i','l','e','n','a','m','e',',',' ','l','i','s','t',' ','a','l','l','.','\n',
'\n',
0 };
constant int size_helpdata = sizeof(helpdata) - 1;

346
contrib/less/ifile.c Normal file
View File

@ -0,0 +1,346 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* An IFILE represents an input file.
*
* It is actually a pointer to an ifile structure,
* but is opaque outside this module.
* Ifile structures are kept in a linked list in the order they
* appear on the command line.
* Any new file which does not already appear in the list is
* inserted after the current file.
*/
#include "less.h"
extern IFILE curr_ifile;
struct ifile {
struct ifile *h_next; /* Links for command line list */
struct ifile *h_prev;
char *h_filename; /* Name of the file */
void *h_filestate; /* File state (used in ch.c) */
int h_index; /* Index within command line list */
int h_hold; /* Hold count */
char h_opened; /* Has this ifile been opened? */
struct scrpos h_scrpos; /* Saved position within the file */
};
/*
* Convert an IFILE (external representation)
* to a struct file (internal representation), and vice versa.
*/
#define int_ifile(h) ((struct ifile *)(h))
#define ext_ifile(h) ((IFILE)(h))
/*
* Anchor for linked list.
*/
static struct ifile anchor = { &anchor, &anchor, NULL, NULL, 0, 0, '\0',
{ NULL_POSITION, 0 } };
static int ifiles = 0;
static void
incr_index(p, incr)
register struct ifile *p;
int incr;
{
for (; p != &anchor; p = p->h_next)
p->h_index += incr;
}
/*
* Link an ifile into the ifile list.
*/
static void
link_ifile(p, prev)
struct ifile *p;
struct ifile *prev;
{
/*
* Link into list.
*/
if (prev == NULL)
prev = &anchor;
p->h_next = prev->h_next;
p->h_prev = prev;
prev->h_next->h_prev = p;
prev->h_next = p;
/*
* Calculate index for the new one,
* and adjust the indexes for subsequent ifiles in the list.
*/
p->h_index = prev->h_index + 1;
incr_index(p->h_next, 1);
ifiles++;
}
/*
* Unlink an ifile from the ifile list.
*/
static void
unlink_ifile(p)
struct ifile *p;
{
p->h_next->h_prev = p->h_prev;
p->h_prev->h_next = p->h_next;
incr_index(p->h_next, -1);
ifiles--;
}
/*
* Allocate a new ifile structure and stick a filename in it.
* It should go after "prev" in the list
* (or at the beginning of the list if "prev" is NULL).
* Return a pointer to the new ifile structure.
*/
static struct ifile *
new_ifile(filename, prev)
char *filename;
struct ifile *prev;
{
register struct ifile *p;
/*
* Allocate and initialize structure.
*/
p = (struct ifile *) ecalloc(1, sizeof(struct ifile));
p->h_filename = save(filename);
p->h_scrpos.pos = NULL_POSITION;
p->h_opened = 0;
p->h_hold = 0;
p->h_filestate = NULL;
link_ifile(p, prev);
return (p);
}
/*
* Delete an existing ifile structure.
*/
public void
del_ifile(h)
IFILE h;
{
register struct ifile *p;
if (h == NULL_IFILE)
return;
/*
* If the ifile we're deleting is the currently open ifile,
* move off it.
*/
unmark(h);
if (h == curr_ifile)
curr_ifile = getoff_ifile(curr_ifile);
p = int_ifile(h);
unlink_ifile(p);
free(p->h_filename);
free(p);
}
/*
* Get the ifile after a given one in the list.
*/
public IFILE
next_ifile(h)
IFILE h;
{
register struct ifile *p;
p = (h == NULL_IFILE) ? &anchor : int_ifile(h);
if (p->h_next == &anchor)
return (NULL_IFILE);
return (ext_ifile(p->h_next));
}
/*
* Get the ifile before a given one in the list.
*/
public IFILE
prev_ifile(h)
IFILE h;
{
register struct ifile *p;
p = (h == NULL_IFILE) ? &anchor : int_ifile(h);
if (p->h_prev == &anchor)
return (NULL_IFILE);
return (ext_ifile(p->h_prev));
}
/*
* Return a different ifile from the given one.
*/
public IFILE
getoff_ifile(ifile)
IFILE ifile;
{
IFILE newifile;
if ((newifile = prev_ifile(ifile)) != NULL_IFILE)
return (newifile);
if ((newifile = next_ifile(ifile)) != NULL_IFILE)
return (newifile);
return (NULL_IFILE);
}
/*
* Return the number of ifiles.
*/
public int
nifile()
{
return (ifiles);
}
/*
* Find an ifile structure, given a filename.
*/
static struct ifile *
find_ifile(filename)
char *filename;
{
register struct ifile *p;
for (p = anchor.h_next; p != &anchor; p = p->h_next)
if (strcmp(filename, p->h_filename) == 0)
return (p);
return (NULL);
}
/*
* Get the ifile associated with a filename.
* If the filename has not been seen before,
* insert the new ifile after "prev" in the list.
*/
public IFILE
get_ifile(filename, prev)
char *filename;
IFILE prev;
{
register struct ifile *p;
if ((p = find_ifile(filename)) == NULL)
p = new_ifile(filename, int_ifile(prev));
return (ext_ifile(p));
}
/*
* Get the filename associated with a ifile.
*/
public char *
get_filename(ifile)
IFILE ifile;
{
if (ifile == NULL)
return (NULL);
return (int_ifile(ifile)->h_filename);
}
/*
* Get the index of the file associated with a ifile.
*/
public int
get_index(ifile)
IFILE ifile;
{
return (int_ifile(ifile)->h_index);
}
/*
* Save the file position to be associated with a given file.
*/
public void
store_pos(ifile, scrpos)
IFILE ifile;
struct scrpos *scrpos;
{
int_ifile(ifile)->h_scrpos = *scrpos;
}
/*
* Recall the file position associated with a file.
* If no position has been associated with the file, return NULL_POSITION.
*/
public void
get_pos(ifile, scrpos)
IFILE ifile;
struct scrpos *scrpos;
{
*scrpos = int_ifile(ifile)->h_scrpos;
}
/*
* Mark the ifile as "opened".
*/
public void
set_open(ifile)
IFILE ifile;
{
int_ifile(ifile)->h_opened = 1;
}
/*
* Return whether the ifile has been opened previously.
*/
public int
opened(ifile)
IFILE ifile;
{
return (int_ifile(ifile)->h_opened);
}
public void
hold_ifile(ifile, incr)
IFILE ifile;
int incr;
{
int_ifile(ifile)->h_hold += incr;
}
public int
held_ifile(ifile)
IFILE ifile;
{
return (int_ifile(ifile)->h_hold);
}
public void *
get_filestate(ifile)
IFILE ifile;
{
return (int_ifile(ifile)->h_filestate);
}
public void
set_filestate(ifile, filestate)
IFILE ifile;
void *filestate;
{
int_ifile(ifile)->h_filestate = filestate;
}
#if 0
public void
if_dump()
{
register struct ifile *p;
for (p = anchor.h_next; p != &anchor; p = p->h_next)
{
printf("%x: %d. <%s> pos %d,%x\n",
p, p->h_index, p->h_filename,
p->h_scrpos.ln, p->h_scrpos.pos);
ch_dump(p->h_filestate);
}
}
#endif

342
contrib/less/input.c Normal file
View File

@ -0,0 +1,342 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* High level routines dealing with getting lines of input
* from the file being viewed.
*
* When we speak of "lines" here, we mean PRINTABLE lines;
* lines processed with respect to the screen width.
* We use the term "raw line" to refer to lines simply
* delimited by newlines; not processed with respect to screen width.
*/
#include "less.h"
extern int squeeze;
extern int chopline;
extern int quit_if_one_screen;
extern int sigs;
extern int ignore_eoi;
extern POSITION start_attnpos;
extern POSITION end_attnpos;
#if HILITE_SEARCH
extern int hilite_search;
extern int size_linebuf;
#endif
/*
* Get the next line.
* A "current" position is passed and a "new" position is returned.
* The current position is the position of the first character of
* a line. The new position is the position of the first character
* of the NEXT line. The line obtained is the line starting at curr_pos.
*/
public POSITION
forw_line(curr_pos)
POSITION curr_pos;
{
POSITION new_pos;
register int c;
int blankline;
int endline;
if (curr_pos == NULL_POSITION)
{
null_line();
return (NULL_POSITION);
}
#if HILITE_SEARCH
if (hilite_search == OPT_ONPLUS)
/*
* If we are ignoring EOI (command F), only prepare
* one line ahead, to avoid getting stuck waiting for
* slow data without displaying the data we already have.
* If we're not ignoring EOI, we *could* do the same, but
* for efficiency we prepare several lines ahead at once.
*/
prep_hilite(curr_pos, curr_pos + 3*size_linebuf,
ignore_eoi ? 1 : -1);
#endif
if (ch_seek(curr_pos))
{
null_line();
return (NULL_POSITION);
}
prewind();
plinenum(curr_pos);
(void) ch_seek(curr_pos);
c = ch_forw_get();
if (c == EOI)
{
null_line();
return (NULL_POSITION);
}
blankline = (c == '\n' || c == '\r');
for (;;)
{
if (ABORT_SIGS())
{
null_line();
return (NULL_POSITION);
}
if (c == '\n' || c == EOI)
{
/*
* End of the line.
*/
new_pos = ch_tell();
endline = TRUE;
break;
}
/*
* Append the char to the line and get the next char.
*/
if (pappend(c, ch_tell()-1))
{
/*
* The char won't fit in the line; the line
* is too long to print in the screen width.
* End the line here.
*/
if (chopline)
{
do
{
c = ch_forw_get();
} while (c != '\n' && c != EOI);
new_pos = ch_tell();
endline = TRUE;
quit_if_one_screen = FALSE;
} else
{
new_pos = ch_tell() - 1;
endline = FALSE;
}
break;
}
c = ch_forw_get();
}
pdone(endline);
if (squeeze && blankline)
{
/*
* This line is blank.
* Skip down to the last contiguous blank line
* and pretend it is the one which we are returning.
*/
while ((c = ch_forw_get()) == '\n' || c == '\r')
if (ABORT_SIGS())
{
null_line();
return (NULL_POSITION);
}
if (c != EOI)
(void) ch_back_get();
new_pos = ch_tell();
}
return (new_pos);
}
/*
* Get the previous line.
* A "current" position is passed and a "new" position is returned.
* The current position is the position of the first character of
* a line. The new position is the position of the first character
* of the PREVIOUS line. The line obtained is the one starting at new_pos.
*/
public POSITION
back_line(curr_pos)
POSITION curr_pos;
{
POSITION new_pos, begin_new_pos;
int c;
int endline;
if (curr_pos == NULL_POSITION || curr_pos <= ch_zero())
{
null_line();
return (NULL_POSITION);
}
#if HILITE_SEARCH
if (hilite_search == OPT_ONPLUS)
prep_hilite((curr_pos < 3*size_linebuf) ?
0 : curr_pos - 3*size_linebuf, curr_pos, -1);
#endif
if (ch_seek(curr_pos-1))
{
null_line();
return (NULL_POSITION);
}
if (squeeze)
{
/*
* Find out if the "current" line was blank.
*/
(void) ch_forw_get(); /* Skip the newline */
c = ch_forw_get(); /* First char of "current" line */
(void) ch_back_get(); /* Restore our position */
(void) ch_back_get();
if (c == '\n' || c == '\r')
{
/*
* The "current" line was blank.
* Skip over any preceding blank lines,
* since we skipped them in forw_line().
*/
while ((c = ch_back_get()) == '\n' || c == '\r')
if (ABORT_SIGS())
{
null_line();
return (NULL_POSITION);
}
if (c == EOI)
{
null_line();
return (NULL_POSITION);
}
(void) ch_forw_get();
}
}
/*
* Scan backwards until we hit the beginning of the line.
*/
for (;;)
{
if (ABORT_SIGS())
{
null_line();
return (NULL_POSITION);
}
c = ch_back_get();
if (c == '\n')
{
/*
* This is the newline ending the previous line.
* We have hit the beginning of the line.
*/
new_pos = ch_tell() + 1;
break;
}
if (c == EOI)
{
/*
* We have hit the beginning of the file.
* This must be the first line in the file.
* This must, of course, be the beginning of the line.
*/
new_pos = ch_tell();
break;
}
}
/*
* Now scan forwards from the beginning of this line.
* We keep discarding "printable lines" (based on screen width)
* until we reach the curr_pos.
*
* {{ This algorithm is pretty inefficient if the lines
* are much longer than the screen width,
* but I don't know of any better way. }}
*/
if (ch_seek(new_pos))
{
null_line();
return (NULL_POSITION);
}
endline = FALSE;
loop:
begin_new_pos = new_pos;
prewind();
plinenum(new_pos);
(void) ch_seek(new_pos);
do
{
c = ch_forw_get();
if (c == EOI || ABORT_SIGS())
{
null_line();
return (NULL_POSITION);
}
new_pos++;
if (c == '\n')
{
endline = TRUE;
break;
}
if (pappend(c, ch_tell()-1))
{
/*
* Got a full printable line, but we haven't
* reached our curr_pos yet. Discard the line
* and start a new one.
*/
if (chopline)
{
endline = TRUE;
quit_if_one_screen = FALSE;
break;
}
pdone(0);
(void) ch_back_get();
new_pos--;
goto loop;
}
} while (new_pos < curr_pos);
pdone(endline);
return (begin_new_pos);
}
/*
* Set attnpos.
*/
public void
set_attnpos(pos)
POSITION pos;
{
int c;
if (pos != NULL_POSITION)
{
if (ch_seek(pos))
return;
for (;;)
{
c = ch_forw_get();
if (c == EOI)
return;
if (c != '\n' && c != '\r')
break;
pos++;
}
}
start_attnpos = pos;
for (;;)
{
c = ch_forw_get();
pos++;
if (c == EOI || c == '\n' || c == '\r')
break;
}
end_attnpos = pos;
}

119
contrib/less/install.sh Executable file
View File

@ -0,0 +1,119 @@
#!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5; it is not part of GNU.
#
# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
#
# This script is compatible with the BSD install script, but was written
# from scratch.
#
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
instcmd="$mvprog"
chmodcmd=""
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
fi
# Make a temp file name in the proper directory.
dstdir=`dirname $dst`
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp
# and set any options; do chmod last to preserve setuid bits
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi
# Now rename the file to the real destination.
$doit $rmcmd $dst
$doit $mvcmd $dsttmp $dst
exit 0

287
contrib/less/jump.c Normal file
View File

@ -0,0 +1,287 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Routines which jump to a new location in the file.
*/
#include "less.h"
#include "position.h"
extern int hit_eof;
extern int jump_sline;
extern int squished;
extern int screen_trashed;
extern int sc_width, sc_height;
extern int show_attn;
/*
* Jump to the end of the file.
*/
public void
jump_forw()
{
POSITION pos;
if (ch_end_seek())
{
error("Cannot seek to end of file", NULL_PARG);
return;
}
/*
* Position the last line in the file at the last screen line.
* Go back one line from the end of the file
* to get to the beginning of the last line.
*/
pos = back_line(ch_tell());
if (pos == NULL_POSITION)
jump_loc((POSITION)0, sc_height-1);
else
jump_loc(pos, sc_height-1);
}
/*
* Jump to line n in the file.
*/
public void
jump_back(n)
int n;
{
POSITION pos;
PARG parg;
/*
* Find the position of the specified line.
* If we can seek there, just jump to it.
* If we can't seek, but we're trying to go to line number 1,
* use ch_beg_seek() to get as close as we can.
*/
pos = find_pos(n);
if (pos != NULL_POSITION && ch_seek(pos) == 0)
{
if (show_attn)
set_attnpos(pos);
jump_loc(pos, jump_sline);
} else if (n <= 1 && ch_beg_seek() == 0)
{
jump_loc(ch_tell(), jump_sline);
error("Cannot seek to beginning of file", NULL_PARG);
} else
{
parg.p_int = n;
error("Cannot seek to line number %d", &parg);
}
}
/*
* Repaint the screen.
*/
public void
repaint()
{
struct scrpos scrpos;
/*
* Start at the line currently at the top of the screen
* and redisplay the screen.
*/
get_scrpos(&scrpos);
pos_clear();
jump_loc(scrpos.pos, scrpos.ln);
}
/*
* Jump to a specified percentage into the file.
*/
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)
{
ierror("Determining length of file", NULL_PARG);
ch_end_seek();
}
if ((len = ch_length()) == NULL_POSITION)
{
error("Don't know length of file", NULL_PARG);
return;
}
pos = percent_pos(len, percent);
if (pos >= len)
pos = len-1;
jump_line_loc(pos, jump_sline);
}
/*
* Jump to a specified position in the file.
* Like jump_loc, but the position need not be
* the first character in a line.
*/
public void
jump_line_loc(pos, sline)
POSITION pos;
int sline;
{
int c;
if (ch_seek(pos) == 0)
{
/*
* Back up to the beginning of the line.
*/
while ((c = ch_back_get()) != '\n' && c != EOI)
;
if (c == '\n')
(void) ch_forw_get();
pos = ch_tell();
}
if (show_attn)
set_attnpos(pos);
jump_loc(pos, sline);
}
/*
* Jump to a specified position in the file.
* The position must be the first character in a line.
* Place the target line on a specified line on the screen.
*/
public void
jump_loc(pos, sline)
POSITION pos;
int sline;
{
register int nline;
POSITION tpos;
POSITION bpos;
/*
* Normalize sline.
*/
sline = adjsline(sline);
if ((nline = onscreen(pos)) >= 0)
{
/*
* The line is currently displayed.
* Just scroll there.
*/
nline -= sline;
if (nline > 0)
forw(nline, position(BOTTOM_PLUS_ONE), 1, 0, 0);
else
back(-nline, position(TOP), 1, 0);
if (show_attn)
repaint_hilite(1);
return;
}
/*
* Line is not on screen.
* Seek to the desired location.
*/
if (ch_seek(pos))
{
error("Cannot seek to that file position", NULL_PARG);
return;
}
/*
* See if the desired line is before or after
* the currently displayed screen.
*/
tpos = position(TOP);
bpos = position(BOTTOM_PLUS_ONE);
if (tpos == NULL_POSITION || pos >= tpos)
{
/*
* The desired line is after the current screen.
* Move back in the file far enough so that we can
* call forw() and put the desired line at the
* sline-th line on the screen.
*/
for (nline = 0; nline < sline; nline++)
{
if (bpos != NULL_POSITION && pos <= bpos)
{
/*
* Surprise! The desired line is
* close enough to the current screen
* that we can just scroll there after all.
*/
forw(sc_height-sline+nline-1, bpos, 1, 0, 0);
if (show_attn)
repaint_hilite(1);
return;
}
pos = back_line(pos);
if (pos == NULL_POSITION)
{
/*
* Oops. Ran into the beginning of the file.
* Exit the loop here and rely on forw()
* below to draw the required number of
* blank lines at the top of the screen.
*/
break;
}
}
lastmark();
hit_eof = 0;
squished = 0;
screen_trashed = 0;
forw(sc_height-1, pos, 1, 0, sline-nline);
} else
{
/*
* The desired line is before the current screen.
* Move forward in the file far enough so that we
* can call back() and put the desired line at the
* sline-th line on the screen.
*/
for (nline = sline; nline < sc_height - 1; nline++)
{
pos = forw_line(pos);
if (pos == NULL_POSITION)
{
/*
* Ran into end of file.
* This shouldn't normally happen,
* but may if there is some kind of read error.
*/
break;
}
if (pos >= tpos)
{
/*
* Surprise! The desired line is
* close enough to the current screen
* that we can just scroll there after all.
*/
back(nline+1, tpos, 1, 0);
if (show_attn)
repaint_hilite(1);
return;
}
}
lastmark();
clear();
screen_trashed = 0;
add_back_pos(pos);
back(sc_height-1, pos, 1, 0);
}
}

382
contrib/less/less.h Normal file
View File

@ -0,0 +1,382 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Standard include file for "less".
*/
/*
* Defines for MSDOS_COMPILER.
*/
#define MSOFTC 1 /* Microsoft C */
#define BORLANDC 2 /* Borland C */
#define WIN32C 3 /* Windows (Borland C or Microsoft C) */
#define DJGPPC 4 /* DJGPP C */
/*
* Include the file of compile-time options.
* The <> make cc search for it in -I., not srcdir.
*/
#include <defines.h>
#ifdef _SEQUENT_
/*
* Kludge for Sequent Dynix systems that have sigsetmask, but
* it's not compatible with the way less calls it.
* {{ Do other systems need this? }}
*/
#undef HAVE_SIGSETMASK
#endif
/*
* Language details.
*/
#if HAVE_VOID
#define VOID_POINTER void *
#else
#define VOID_POINTER char *
#define void int
#endif
#if HAVE_CONST
#define constant const
#else
#define constant
#endif
#define public /* PUBLIC FUNCTION */
/* Library function declarations */
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#if HAVE_STDIO_H
#include <stdio.h>
#endif
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_CTYPE_H
#include <ctype.h>
#endif
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if HAVE_STRING_H
#include <string.h>
#endif
#ifdef _OSK
#include <modes.h>
#include <strings.h>
#endif
#if MSDOS_COMPILER==WIN32C
#include <io.h>
#endif
#if MSDOS_COMPILER==DJGPPC
#include <io.h>
#include <sys/exceptn.h>
#include <conio.h>
#include <pc.h>
#endif
#if !HAVE_STDLIB_H
char *getenv();
off_t lseek();
VOID_POINTER calloc();
void free();
#endif
/*
* Simple lowercase test which can be used during option processing
* (before options are parsed which might tell us what charset to use).
*/
#define SIMPLE_IS_UPPER(c) ((c) >= 'A' && (c) <= 'Z')
#define SIMPLE_IS_LOWER(c) ((c) >= 'a' && (c) <= 'z')
#define SIMPLE_TO_UPPER(c) ((c) - 'a' + 'A')
#define SIMPLE_TO_LOWER(c) ((c) - 'A' + 'a')
#if !HAVE_UPPER_LOWER
#define isupper(c) SIMPLE_IS_UPPER(c)
#define islower(c) SIMPLE_IS_LOWER(c)
#define toupper(c) SIMPLE_TO_UPPER(c)
#define tolower(c) SIMPLE_TO_LOWER(c)
#endif
#ifndef NULL
#define NULL 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#define OPT_OFF 0
#define OPT_ON 1
#define OPT_ONPLUS 2
#if !HAVE_MEMCPY
#ifndef memcpy
#define memcpy(to,from,len) bcopy((from),(to),(len))
#endif
#endif
#define BAD_LSEEK ((off_t)-1)
/*
* Special types and constants.
*/
typedef long POSITION;
#define PR_POSITION "%ld"
#define MAX_PRINT_POSITION 20
#define MAX_PRINT_INT 10
#define NULL_POSITION ((POSITION)(-1))
/*
* Flags for open()
*/
#if MSDOS_COMPILER || OS2
#define OPEN_READ (O_RDONLY|O_BINARY)
#else
#ifdef _OSK
#define OPEN_READ (S_IREAD)
#else
#ifdef O_RDONLY
#define OPEN_READ (O_RDONLY)
#else
#define OPEN_READ (0)
#endif
#endif
#endif
#if defined(O_WRONLY) && defined(O_APPEND)
#define OPEN_APPEND (O_APPEND|O_WRONLY)
#else
#ifdef _OSK
#define OPEN_APPEND (S_IWRITE)
#else
#define OPEN_APPEND (1)
#endif
#endif
/*
* Set a file descriptor to binary mode.
*/
#if MSDOS_COMPILER==MSOFTC
#define SET_BINARY(f) _setmode(f, _O_BINARY);
#else
#if MSDOS_COMPILER
#define SET_BINARY(f) setmode(f, O_BINARY)
#else
#define SET_BINARY(f)
#endif
#endif
/*
* Does the shell treat "?" as a metacharacter?
*/
#if MSDOS_COMPILER || OS2 || _OSK
#define SHELL_META_QUEST 0
#else
#define SHELL_META_QUEST 1
#endif
#define SPACES_IN_FILENAMES 1
/*
* An IFILE represents an input file.
*/
#define IFILE VOID_POINTER
#define NULL_IFILE ((IFILE)NULL)
/*
* The structure used to represent a "screen position".
* This consists of a file position, and a screen line number.
* The meaning is that the line starting at the given file
* position is displayed on the ln-th line of the screen.
* (Screen lines before ln are empty.)
*/
struct scrpos
{
POSITION pos;
int ln;
};
typedef union parg
{
char *p_string;
int p_int;
} PARG;
#define NULL_PARG ((PARG *)NULL)
struct textlist
{
char *string;
char *endstring;
};
#define EOI (-1)
#define READ_INTR (-2)
/* 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_SPECIAL 0 /* Do special things for underlining and bold */
#define BS_NORMAL 1 /* \b treated as normal char; actually output */
#define BS_CONTROL 2 /* \b treated as control char; prints as ^H */
/* How should we search? */
#define SRCH_FORW 000001 /* Search forward from current position */
#define SRCH_BACK 000002 /* Search backward from current position */
#define SRCH_NO_MOVE 000004 /* Highlight, but don't move */
#define SRCH_FIND_ALL 000010 /* Find and highlight all matches */
#define SRCH_NO_MATCH 000100 /* Search for non-matching lines */
#define SRCH_PAST_EOF 000200 /* Search past end-of-file, into next file */
#define SRCH_FIRST_FILE 000400 /* Search starting at the first file */
#define SRCH_NO_REGEX 001000 /* Don't use regular expressions */
#define SRCH_REVERSE(t) (((t) & SRCH_FORW) ? \
(((t) & ~SRCH_FORW) | SRCH_BACK) : \
(((t) & ~SRCH_BACK) | SRCH_FORW))
/* */
#define NO_MCA 0
#define MCA_DONE 1
#define MCA_MORE 2
#define CC_OK 0 /* Char was accepted & processed */
#define CC_QUIT 1 /* Char was a request to abort current cmd */
#define CC_ERROR 2 /* Char could not be accepted due to error */
#define CC_PASS 3 /* Char was rejected (internal) */
#define CF_QUIT_ON_ERASE 0001 /* Abort cmd if its entirely erased */
/* Special chars used to tell put_line() to do something special */
#define AT_NORMAL (0)
#define AT_UNDERLINE (1)
#define AT_BOLD (2)
#define AT_BLINK (3)
#define AT_INVIS (4)
#define AT_STANDOUT (5)
#if IS_EBCDIC_HOST
/*
* Long definition for EBCDIC.
* Since the argument is usually a constant, this macro normally compiles
* into a constant.
*/
#define CONTROL(c) ( \
(c)=='[' ? '\047' : \
(c)=='a' ? '\001' : \
(c)=='b' ? '\002' : \
(c)=='c' ? '\003' : \
(c)=='d' ? '\067' : \
(c)=='e' ? '\055' : \
(c)=='f' ? '\056' : \
(c)=='g' ? '\057' : \
(c)=='h' ? '\026' : \
(c)=='i' ? '\005' : \
(c)=='j' ? '\025' : \
(c)=='k' ? '\013' : \
(c)=='l' ? '\014' : \
(c)=='m' ? '\015' : \
(c)=='n' ? '\016' : \
(c)=='o' ? '\017' : \
(c)=='p' ? '\020' : \
(c)=='q' ? '\021' : \
(c)=='r' ? '\022' : \
(c)=='s' ? '\023' : \
(c)=='t' ? '\074' : \
(c)=='u' ? '\075' : \
(c)=='v' ? '\062' : \
(c)=='w' ? '\046' : \
(c)=='x' ? '\030' : \
(c)=='y' ? '\031' : \
(c)=='z' ? '\077' : \
(c)=='A' ? '\001' : \
(c)=='B' ? '\002' : \
(c)=='C' ? '\003' : \
(c)=='D' ? '\067' : \
(c)=='E' ? '\055' : \
(c)=='F' ? '\056' : \
(c)=='G' ? '\057' : \
(c)=='H' ? '\026' : \
(c)=='I' ? '\005' : \
(c)=='J' ? '\025' : \
(c)=='K' ? '\013' : \
(c)=='L' ? '\014' : \
(c)=='M' ? '\015' : \
(c)=='N' ? '\016' : \
(c)=='O' ? '\017' : \
(c)=='P' ? '\020' : \
(c)=='Q' ? '\021' : \
(c)=='R' ? '\022' : \
(c)=='S' ? '\023' : \
(c)=='T' ? '\074' : \
(c)=='U' ? '\075' : \
(c)=='V' ? '\062' : \
(c)=='W' ? '\046' : \
(c)=='X' ? '\030' : \
(c)=='Y' ? '\031' : \
(c)=='Z' ? '\077' : \
(c)=='|' ? '\031' : \
(c)=='\\' ? '\034' : \
(c)=='^' ? '\036' : \
(c)&077)
#else
#define CONTROL(c) ((c)&037)
#endif /* IS_EBCDIC_HOST */
#define ESC CONTROL('[')
#if _OSK_MWC32
#define LSIGNAL(sig,func) os9_signal(sig,func)
#else
#define LSIGNAL(sig,func) signal(sig,func)
#endif
#define S_INTERRUPT 01
#define S_STOP 02
#define S_WINCH 04
#define ABORT_SIGS() (sigs & (S_INTERRUPT|S_STOP))
#define QUIT_OK 0
#define QUIT_ERROR 1
#define QUIT_SAVED_STATUS (-1)
/* filestate flags */
#define CH_CANSEEK 001
#define CH_KEEPOPEN 002
#define CH_POPENED 004
#define CH_HELPFILE 010
#define ch_zero() ((POSITION)0)
#define FAKE_HELPFILE "@/\\less/\\help/\\file/\\@"
#include "funcs.h"

209
contrib/less/less.hlp Normal file
View File

@ -0,0 +1,209 @@
SSUUMMMMAARRYY OOFF LLEESSSS CCOOMMMMAANNDDSS
Commands marked with * may be preceded by a number, _N.
Notes in parentheses indicate the behavior if _N is given.
h H Display this help.
q :q Q :Q ZZ Exit.
---------------------------------------------------------------------------
MMOOVVIINNGG
e ^E j ^N CR * Forward one line (or _N lines).
y ^Y k ^K ^P * Backward one line (or _N lines).
f ^F ^V SPACE * Forward one window (or _N lines).
b ^B ESC-v * Backward one window (or _N lines).
z * Forward one window (and set window to _N).
w * Backward one window (and set window to _N).
ESC-SPACE * Forward one window, but don't stop at end-of-file.
d ^D * Forward one half-window (and set half-window to _N).
u ^U * Backward one half-window (and set half-window to _N).
ESC-( RightArrow * Left 8 character positions (or _N positions).
ESC-) LeftArrow * Right 8 character positions (or _N positions).
F Forward forever; like "tail -f".
r ^R ^L Repaint screen.
R Repaint screen, discarding buffered input.
---------------------------------------------------
Default "window" is the screen height.
Default "half-window" is half of the screen height.
---------------------------------------------------------------------------
SSEEAARRCCHHIINNGG
/_p_a_t_t_e_r_n * Search forward for (_N-th) matching line.
?_p_a_t_t_e_r_n * Search backward for (_N-th) matching line.
n * Repeat previous search (for _N-th occurrence).
N * Repeat previous search in reverse direction.
ESC-n * Repeat previous search, spanning files.
ESC-N * Repeat previous search, reverse dir. & spanning files.
ESC-u Undo (toggle) search highlighting.
---------------------------------------------------
Search patterns may be modified by one or more of:
^N or ! Search for NON-matching lines.
^E or * Search multiple files (pass thru END OF FILE).
^F or @ Start search at FIRST file (for /) or last file (for ?).
^K Highlight matches, but don't move (KEEP position).
^R Don't use REGULAR EXPRESSIONS.
---------------------------------------------------------------------------
JJUUMMPPIINNGG
g < ESC-< * Go to first line in file (or line _N).
G > ESC-> * Go to last line in file (or line _N).
p % * Go to beginning of file (or _N percent into file).
{ ( [ * Find close bracket } ) ].
} ) ] * Find open bracket { ( [.
ESC-^F _<_c_1_> _<_c_2_> * Find close bracket _<_c_2_>.
ESC-^B _<_c_1_> _<_c_2_> * Find open bracket _<_c_1_>
---------------------------------------------------
Each "find close bracket" command goes forward to the close bracket
matching the (_N-th) open bracket in the top line.
Each "find open bracket" command goes backward to the open bracket
matching the (_N-th) close bracket in the bottom line.
m_<_l_e_t_t_e_r_> Mark the current position with <letter>.
'_<_l_e_t_t_e_r_> Go to a previously marked position.
'' Go to the previous position.
^X^X Same as '.
---------------------------------------------------
A mark is any upper-case or lower-case letter.
Certain marks are predefined:
^ means beginning of the file
$ means end of the file
---------------------------------------------------------------------------
CCHHAANNGGIINNGG FFIILLEESS
:e [_f_i_l_e] Examine a new file.
^X^V Same as :e.
:n * Examine the (_N-th) next file from the command line.
:p * Examine the (_N-th) previous file from the command line.
:x * Examine the first (or _N-th) file from the command line.
:d Delete the current file from the command line list.
= ^G :f Print current file name.
---------------------------------------------------------------------------
MMIISSCCEELLLLAANNEEOOUUSS CCOOMMMMAANNDDSS
-_<_f_l_a_g_> Toggle a command line option [see OPTIONS below].
--_<_n_a_m_e_> Toggle a command line option, by name.
__<_f_l_a_g_> Display the setting of a command line option.
___<_n_a_m_e_> Display the setting of an option, by name.
+_c_m_d Execute the less cmd each time a new file is examined.
!_c_o_m_m_a_n_d Execute the shell command with $SHELL.
|XX_c_o_m_m_a_n_d Pipe file between current pos & mark XX to shell command.
v Edit the current file with $VISUAL or $EDITOR.
V Print version number of "less".
---------------------------------------------------------------------------
OOPPTTIIOONNSS
Most options may be changed either on the command line,
or from within less by using the - or -- command.
Options may be given in one of two forms: either a single
character preceded by a -, or a name preceeded by --.
-? ........ --help
Display help (from command line).
-a ........ --search-skip-screen
Forward search skips current screen.
-b [_N] .... --buffers=[_N]
Number of buffers.
-B ........ --auto-buffers
Don't automatically allocate buffers for pipes.
-c -C .... --clear-screen --CLEAR-SCREEN
Repaint by scrolling/clearing.
-d ........ --dumb
Dumb terminal.
-D [_x_n_._n] . --color=_x_n_._n
Set screen colors. (MS-DOS only)
-e -E .... --quit-at-eof --QUIT-AT-EOF
Quit at end of file.
-f ........ --force
Force open non-regular files.
-F ........ --quit-if-one-screen
Quit if entire file fits on first screen.
-g ........ --hilite-search
Highlight only last match for searches.
-G ........ --HILITE-SEARCH
Don't highlight any matches for searches.
-h [_N] .... --max-back-scroll=[_N]
Backward scroll limit.
-i ........ --ignore-case
Ignore case in searches that do not contain uppercase.
-I ........ --IGNORE-CASE
Ignore case in all searches.
-j [_N] .... --jump-target=[_N]
Screen position of target lines.
-k [_f_i_l_e] . --lesskey-file=[_f_i_l_e]
Use a lesskey file.
-m -M .... --long-prompt --LONG-PROMPT
Set prompt style.
-n -N .... --line-numbers --LINE-NUMBERS
Use line numbers.
-o [_f_i_l_e] . --log-file=[_f_i_l_e]
Copy to log file (standard input only).
-O [_f_i_l_e] . --LOG-FILE=[_f_i_l_e]
Copy to log file (unconditionally overwrite).
-p [_p_a_t_t_e_r_n] --pattern=[_p_a_t_t_e_r_n]
Start at pattern (from command line).
-P [_p_r_o_m_p_t] --prompt=[_p_r_o_m_p_t]
Define new prompt.
-q -Q .... --quiet --QUIET --silent --SILENT
Quiet the terminal bell.
-r -R .... --raw-control-chars --RAW-CONTROL-CHARS
Output "raw" control characters.
-s ........ --squeeze-blank-lines
Squeeze multiple blank lines.
-S ........ --chop-long-lines
Chop long lines.
-t [_t_a_g] .. --tag=[_t_a_g]
Find a tag.
-T [_t_a_g_s_f_i_l_e] --tag-file=[_t_a_g_s_f_i_l_e]
Use an alternate tags file.
-u -U .... --underline-special --UNDERLINE-SPECIAL
Change handling of backspaces.
-V ........ --version
Display the version number of "less".
-w ........ --hilite-unread
Highlight first new line after forward-screen.
-W ........ --HILITE-UNREAD
Highlight first new line after any forward movement.
-x [_N] .... --tabs=[_N]
Set tab stops.
-X ........ --no-init
Don't use termcap init/deinit strings.
-y [_N] .... --max-forw-scroll=[_N]
Forward scroll limit.
-z [_N] .... --window=[_N]
Set size of window.
-" [_c[_c]] . --quotes=[_c[_c]]
Set shell quote characters.
-~ ........ --tilde
Don't display tildes after end of file.
---------------------------------------------------------------------------
LLIINNEE EEDDIITTIINNGG
These keys can be used to edit text being entered
on the "command line" at the bottom of the screen.
RightArrow ESC-l Move cursor right one character.
LeftArrow ESC-h Move cursor left one character.
CNTL-RightArrow ESC-RightArrow ESC-w Move cursor right one word.
CNTL-LeftArrow ESC-LeftArrow ESC-b Move cursor left one word.
HOME ESC-0 Move cursor to start of line.
END ESC-$ Move cursor to end of line.
BACKSPACE Delete char to left of cursor.
DELETE ESC-x Delete char under cursor.
CNTL-BACKSPACE ESC-BACKSPACE Delete word to left of cursor.
CNTL-DELETE ESC-DELETE ESC-X Delete word under cursor.
CNTL-U ESC (MS-DOS only) Delete entire line.
UpArrow ESC-k Retrieve previous command line.
DownArrow ESC-j Retrieve next command line.
TAB Complete filename & cycle.
SHIFT-TAB ESC-TAB Complete filename & reverse cycle.
CNTL-L Complete filename, list all.

1914
contrib/less/less.man Normal file

File diff suppressed because it is too large Load Diff

1502
contrib/less/less.nro Normal file

File diff suppressed because it is too large Load Diff

226
contrib/less/lessecho.c Normal file
View File

@ -0,0 +1,226 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* lessecho [-ox] [-cx] [-pn] [-dn] [-a] file ...
* Simply echos its filename arguments on standard output.
* But any argument containing spaces is enclosed in quotes.
*
* -ox Specifies "x" to be the open quote character.
* -cx Specifies "x" to be the close quote character.
* -pn Specifies "n" to be the open quote character, as an integer.
* -dn Specifies "n" to be the close quote character, as an integer.
* -a Specifies that all arguments are to be quoted.
* The default is that only arguments containing spaces are quoted.
*/
#include "less.h"
static char *version = "$Revision: 1.6 $";
static int quote_all = 0;
static char openquote = '"';
static char closequote = '"';
static void
pr_usage()
{
fprintf(stderr,
"usage: lessecho [-ox] [-cx] [-pn] [-dn] [-a] file ...\n");
}
static void
pr_version()
{
char *p;
char buf[10];
char *pbuf = buf;
for (p = version; *p != ' '; p++)
if (*p == '\0')
return;
for (p++; *p != '$' && *p != ' ' && *p != '\0'; p++)
*pbuf++ = *p;
*pbuf = '\0';
printf("%s\n", buf);
}
static void
pr_error(s)
char *s;
{
fprintf(stderr, "%s\n", s);
exit(1);
}
static long
lstrtol(s, radix, pend)
char *s;
int radix;
char **pend;
{
int v;
int neg = 0;
long n = 0;
/* Skip leading white space. */
while (*s == ' ' || *s == '\t')
s++;
/* Check for a leading + or -. */
if (*s == '-')
{
neg = 1;
s++;
} else if (*s == '+')
{
s++;
}
/* Determine radix if caller does not specify. */
if (radix == 0)
{
radix = 10;
if (*s == '0')
{
switch (*++s)
{
case 'x':
radix = 16;
s++;
break;
default:
radix = 8;
break;
}
}
}
/* Parse the digits of the number. */
for (;;)
{
if (*s >= '0' && *s <= '9')
v = *s - '0';
else if (*s >= 'a' && *s <= 'f')
v = *s - 'a' + 10;
else if (*s >= 'A' && *s <= 'F')
v = *s - 'A' + 10;
else
break;
if (v >= radix)
break;
n = n * radix + v;
s++;
}
if (pend != NULL)
{
/* Skip trailing white space. */
while (*s == ' ' || *s == '\t')
s++;
*pend = s;
}
if (neg)
return (-n);
return (n);
}
#if !HAVE_STRCHR
char *
strchr(s, c)
char *s;
int c;
{
for ( ; *s != '\0'; s++)
if (*s == c)
return (s);
if (c == '\0')
return (s);
return (NULL);
}
#endif
int
main(argc, argv)
int argc;
char *argv[];
{
char *arg;
char *s;
int no_more_options;
no_more_options = 0;
while (--argc > 0)
{
arg = *++argv;
if (*arg != '-' || no_more_options)
break;
switch (*++arg)
{
case 'a':
quote_all = 1;
break;
case 'o':
openquote = *++arg;
break;
case 'c':
closequote = *++arg;
break;
case 'p':
openquote = lstrtol(++arg, 0, &s);
if (s == arg)
pr_error("Missing number after -O");
break;
case 'd':
closequote = lstrtol(++arg, 0, &s);
if (s == arg)
pr_error("Missing number after -C");
break;
case '?':
pr_usage();
return (0);
case '-':
if (*++arg == '\0')
{
no_more_options = 1;
break;
}
if (strcmp(arg, "version") == 0)
{
pr_version();
return (0);
}
if (strcmp(arg, "help") == 0)
{
pr_usage();
return (0);
}
pr_error("Invalid option after --");
default:
pr_error("Invalid option letter");
}
}
while (argc-- > 0)
{
arg = *argv++;
if (quote_all || strchr(arg, ' ') != NULL)
printf("%c%s%c", openquote, arg, closequote);
else
printf("%s", arg);
if (argc > 0)
printf(" ");
else
printf("\n");
}
return (0);
}

858
contrib/less/lesskey.c Normal file
View File

@ -0,0 +1,858 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* lesskey [-o output] [input]
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Make a .less file.
* If no input file is specified, standard input is used.
* If no output file is specified, $HOME/.less is used.
*
* The .less file is used to specify (to "less") user-defined
* key bindings. Basically any sequence of 1 to MAX_CMDLEN
* keystrokes may be bound to an existing less function.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* The input file is an ascii file consisting of a
* sequence of lines of the form:
* string <whitespace> action [chars] <newline>
*
* "string" is a sequence of command characters which form
* the new user-defined command. The command
* characters may be:
* 1. The actual character itself.
* 2. A character preceded by ^ to specify a
* control character (e.g. ^X means control-X).
* 3. A backslash followed by one to three octal digits
* to specify a character by its octal value.
* 4. A backslash followed by b, e, n, r or t
* to specify \b, ESC, \n, \r or \t, respectively.
* 5. Any character (other than those mentioned above) preceded
* by a \ to specify the character itself (characters which
* must be preceded by \ include ^, \, and whitespace.
* "action" is the name of a "less" action, from the table below.
* "chars" is an optional sequence of characters which is treated
* as keyboard input after the command is executed.
*
* Blank lines and lines which start with # are ignored,
* except for the special control lines:
* #command Signals the beginning of the command
* keys section.
* #line-edit Signals the beginning of the line-editing
* keys section.
* #env Signals the beginning of the environment
* variable section.
* #stop Stops command parsing in less;
* causes all default keys to be disabled.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* The output file is a non-ascii file, consisting of a header,
* one or more sections, and a trailer.
* Each section begins with a section header, a section length word
* and the section data. Normally there are three sections:
* CMD_SECTION Definition of command keys.
* EDIT_SECTION Definition of editing keys.
* END_SECTION A special section header, with no
* length word or section data.
*
* Section data consists of zero or more byte sequences of the form:
* string <0> <action>
* or
* string <0> <action|A_EXTRA> chars <0>
*
* "string" is the command string.
* "<0>" is one null byte.
* "<action>" is one byte containing the action code (the A_xxx value).
* If action is ORed with A_EXTRA, the action byte is followed
* by the null-terminated "chars" string.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
#include "less.h"
#include "lesskey.h"
#include "cmd.h"
struct cmdname
{
char *cn_name;
int cn_action;
};
struct cmdname cmdnames[] =
{
"back-bracket", A_B_BRACKET,
"back-line", A_B_LINE,
"back-line-force", A_BF_LINE,
"back-screen", A_B_SCREEN,
"back-scroll", A_B_SCROLL,
"back-search", A_B_SEARCH,
"back-window", A_B_WINDOW,
"debug", A_DEBUG,
"display-flag", A_DISP_OPTION,
"display-option", A_DISP_OPTION,
"end", A_GOEND,
"examine", A_EXAMINE,
"first-cmd", A_FIRSTCMD,
"firstcmd", A_FIRSTCMD,
"flush-repaint", A_FREPAINT,
"forw-bracket", A_F_BRACKET,
"forw-forever", A_F_FOREVER,
"forw-line", A_F_LINE,
"forw-line-force", A_FF_LINE,
"forw-screen", A_F_SCREEN,
"forw-screen-force", A_FF_SCREEN,
"forw-scroll", A_F_SCROLL,
"forw-search", A_F_SEARCH,
"forw-window", A_F_WINDOW,
"goto-end", A_GOEND,
"goto-line", A_GOLINE,
"goto-mark", A_GOMARK,
"help", A_HELP,
"index-file", A_INDEX_FILE,
"invalid", A_UINVALID,
"left-scroll", A_LSHIFT,
"next-file", A_NEXT_FILE,
"noaction", A_NOACTION,
"percent", A_PERCENT,
"pipe", A_PIPE,
"prev-file", A_PREV_FILE,
"quit", A_QUIT,
"repaint", A_REPAINT,
"repaint-flush", A_FREPAINT,
"repeat-search", A_AGAIN_SEARCH,
"repeat-search-all", A_T_AGAIN_SEARCH,
"reverse-search", A_REVERSE_SEARCH,
"reverse-search-all", A_T_REVERSE_SEARCH,
"right-scroll", A_RSHIFT,
"set-mark", A_SETMARK,
"shell", A_SHELL,
"status", A_STAT,
"toggle-flag", A_OPT_TOGGLE,
"toggle-option", A_OPT_TOGGLE,
"undo-hilite", A_UNDO_SEARCH,
"version", A_VERSION,
"visual", A_VISUAL,
NULL, 0
};
struct cmdname editnames[] =
{
"back-complete", EC_B_COMPLETE,
"backspace", EC_BACKSPACE,
"delete", EC_DELETE,
"down", EC_DOWN,
"end", EC_END,
"expand", EC_EXPAND,
"forw-complete", EC_F_COMPLETE,
"home", EC_HOME,
"insert", EC_INSERT,
"invalid", EC_UINVALID,
"kill-line", EC_LINEKILL,
"left", EC_LEFT,
"literal", EC_LITERAL,
"right", EC_RIGHT,
"up", EC_UP,
"word-backspace", EC_W_BACKSPACE,
"word-delete", EC_W_DELETE,
"word-left", EC_W_LEFT,
"word-right", EC_W_RIGHT,
NULL, 0
};
struct table
{
struct cmdname *names;
char *pbuffer;
char buffer[MAX_USERCMD];
};
struct table cmdtable;
struct table edittable;
struct table vartable;
struct table *currtable = &cmdtable;
char fileheader[] = {
C0_LESSKEY_MAGIC,
C1_LESSKEY_MAGIC,
C2_LESSKEY_MAGIC,
C3_LESSKEY_MAGIC
};
char filetrailer[] = {
C0_END_LESSKEY_MAGIC,
C1_END_LESSKEY_MAGIC,
C2_END_LESSKEY_MAGIC
};
char cmdsection[1] = { CMD_SECTION };
char editsection[1] = { EDIT_SECTION };
char varsection[1] = { VAR_SECTION };
char endsection[1] = { END_SECTION };
char *infile = NULL;
char *outfile = NULL ;
int linenum;
int errors;
extern char version[];
void
usage()
{
fprintf(stderr, "usage: lesskey [-o output] [input]\n");
exit(1);
}
char *
mkpathname(dirname, filename)
char *dirname;
char *filename;
{
char *pathname;
pathname = calloc(strlen(dirname) + strlen(filename) + 2, sizeof(char));
strcpy(pathname, dirname);
strcat(pathname, PATHNAME_SEP);
strcat(pathname, filename);
return (pathname);
}
/*
* Figure out the name of a default file (in the user's HOME directory).
*/
char *
homefile(filename)
char *filename;
{
char *p;
char *pathname;
if ((p = getenv("HOME")) != NULL && *p != '\0')
pathname = mkpathname(p, filename);
#if OS2
else if ((p = getenv("INIT")) != NULL && *p != '\0')
pathname = mkpathname(p, filename);
#endif
else
{
fprintf(stderr, "cannot find $HOME - using current directory\n");
pathname = mkpathname(".", filename);
}
return (pathname);
}
/*
* Parse command line arguments.
*/
void
parse_args(argc, argv)
int argc;
char **argv;
{
char *arg;
outfile = NULL;
while (--argc > 0)
{
arg = *++argv;
if (arg[0] != '-')
/* Arg does not start with "-"; it's not an option. */
break;
if (arg[1] == '\0')
/* "-" means standard input. */
break;
if (arg[1] == '-' && arg[2] == '\0')
{
/* "--" means end of options. */
argc--;
argv++;
break;
}
switch (arg[1])
{
case '-':
if (strncmp(arg, "--output", 8) == 0)
{
if (arg[8] == '\0')
outfile = &arg[8];
else if (arg[8] == '=')
outfile = &arg[9];
else
usage();
goto opt_o;
}
if (strcmp(arg, "--version") == 0)
{
goto opt_V;
}
usage();
break;
case 'o':
outfile = &argv[0][2];
opt_o:
if (*outfile == '\0')
{
if (--argc <= 0)
usage();
outfile = *(++argv);
}
break;
case 'V':
opt_V:
printf("lesskey version %s\n", version);
exit(0);
default:
usage();
}
}
if (argc > 1)
usage();
/*
* Open the input file, or use DEF_LESSKEYINFILE if none specified.
*/
if (argc > 0)
infile = *argv;
else
infile = homefile(DEF_LESSKEYINFILE);
}
/*
* Initialize data structures.
*/
void
init_tables()
{
cmdtable.names = cmdnames;
cmdtable.pbuffer = cmdtable.buffer;
edittable.names = editnames;
edittable.pbuffer = edittable.buffer;
vartable.names = NULL;
vartable.pbuffer = vartable.buffer;
}
/*
* Parse one character of a string.
*/
char *
tstr(pp)
char **pp;
{
register char *p;
register char ch;
register int i;
static char buf[10];
static char tstr_control_k[] =
{ SK_SPECIAL_KEY, SK_CONTROL_K, 6, 1, 1, 1, '\0' };
p = *pp;
switch (*p)
{
case '\\':
++p;
switch (*p)
{
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
/*
* Parse an octal number.
*/
ch = 0;
i = 0;
do
ch = 8*ch + (*p - '0');
while (*++p >= '0' && *p <= '7' && ++i < 3);
*pp = p;
if (ch == CONTROL('K'))
return tstr_control_k;
buf[0] = ch;
buf[1] = '\0';
return (buf);
case 'b':
*pp = p+1;
return ("\b");
case 'e':
*pp = p+1;
buf[0] = ESC;
buf[1] = '\0';
return (buf);
case 'n':
*pp = p+1;
return ("\n");
case 'r':
*pp = p+1;
return ("\r");
case 't':
*pp = p+1;
return ("\t");
case 'k':
switch (*++p)
{
case 'u': ch = SK_UP_ARROW; break;
case 'd': ch = SK_DOWN_ARROW; break;
case 'r': ch = SK_RIGHT_ARROW; break;
case 'l': ch = SK_LEFT_ARROW; break;
case 'U': ch = SK_PAGE_UP; break;
case 'D': ch = SK_PAGE_DOWN; break;
case 'h': ch = SK_HOME; break;
case 'e': ch = SK_END; break;
case 'x': ch = SK_DELETE; break;
}
*pp = p+1;
buf[0] = SK_SPECIAL_KEY;
buf[1] = ch;
buf[2] = 6;
buf[3] = 1;
buf[4] = 1;
buf[5] = 1;
buf[6] = '\0';
return (buf);
default:
/*
* Backslash followed by any other char
* just means that char.
*/
*pp = p+1;
buf[0] = *p;
buf[1] = '\0';
if (buf[0] == CONTROL('K'))
return tstr_control_k;
return (buf);
}
case '^':
/*
* Carat means CONTROL.
*/
*pp = p+2;
buf[0] = CONTROL(p[1]);
buf[1] = '\0';
if (buf[0] == CONTROL('K'))
return tstr_control_k;
return (buf);
}
*pp = p+1;
buf[0] = *p;
buf[1] = '\0';
if (buf[0] == CONTROL('K'))
return tstr_control_k;
return (buf);
}
/*
* Skip leading spaces in a string.
*/
public char *
skipsp(s)
register char *s;
{
while (*s == ' ' || *s == '\t')
s++;
return (s);
}
/*
* Skip non-space characters in a string.
*/
public char *
skipnsp(s)
register char *s;
{
while (*s != '\0' && *s != ' ' && *s != '\t')
s++;
return (s);
}
/*
* Clean up an input line:
* strip off the trailing newline & any trailing # comment.
*/
char *
clean_line(s)
char *s;
{
register int i;
s = skipsp(s);
for (i = 0; s[i] != '\n' && s[i] != '\r' && s[i] != '\0'; i++)
if (s[i] == '#' && (i == 0 || s[i-1] != '\\'))
break;
s[i] = '\0';
return (s);
}
/*
* Add a byte to the output command table.
*/
void
add_cmd_char(c)
int c;
{
if (currtable->pbuffer >= currtable->buffer + MAX_USERCMD)
{
error("too many commands");
exit(1);
}
*(currtable->pbuffer)++ = c;
}
/*
* Add a string to the output command table.
*/
void
add_cmd_str(s)
char *s;
{
for ( ; *s != '\0'; s++)
add_cmd_char(*s);
}
/*
* See if we have a special "control" line.
*/
int
control_line(s)
char *s;
{
#define PREFIX(str,pat) (strncmp(str,pat,strlen(pat)-1) == 0)
if (PREFIX(s, "#line-edit"))
{
currtable = &edittable;
return (1);
}
if (PREFIX(s, "#command"))
{
currtable = &cmdtable;
return (1);
}
if (PREFIX(s, "#env"))
{
currtable = &vartable;
return (1);
}
if (PREFIX(s, "#stop"))
{
add_cmd_char('\0');
add_cmd_char(A_END_LIST);
return (1);
}
return (0);
}
/*
* Output some bytes.
*/
void
fputbytes(fd, buf, len)
FILE *fd;
char *buf;
int len;
{
while (len-- > 0)
{
fwrite(buf, sizeof(char), 1, fd);
buf++;
}
}
/*
* Output an integer, in special KRADIX form.
*/
void
fputint(fd, val)
FILE *fd;
unsigned int val;
{
char c;
if (val >= KRADIX*KRADIX)
{
fprintf(stderr, "error: integer too big (%d > %d)\n",
val, KRADIX*KRADIX);
exit(1);
}
c = val % KRADIX;
fwrite(&c, sizeof(char), 1, fd);
c = val / KRADIX;
fwrite(&c, sizeof(char), 1, fd);
}
/*
* Find an action, given the name of the action.
*/
int
findaction(actname)
char *actname;
{
int i;
for (i = 0; currtable->names[i].cn_name != NULL; i++)
if (strcmp(currtable->names[i].cn_name, actname) == 0)
return (currtable->names[i].cn_action);
error("unknown action");
return (A_INVALID);
}
void
error(s)
char *s;
{
fprintf(stderr, "line %d: %s\n", linenum, s);
errors++;
}
void
parse_cmdline(p)
char *p;
{
int cmdlen;
char *actname;
int action;
char *s;
char c;
/*
* Parse the command string and store it in the current table.
*/
cmdlen = 0;
do
{
s = tstr(&p);
cmdlen += strlen(s);
if (cmdlen > MAX_CMDLEN)
error("command too long");
else
add_cmd_str(s);
} while (*p != ' ' && *p != '\t' && *p != '\0');
/*
* Terminate the command string with a null byte.
*/
add_cmd_char('\0');
/*
* Skip white space between the command string
* and the action name.
* Terminate the action name with a null byte.
*/
p = skipsp(p);
if (*p == '\0')
{
error("missing action");
return;
}
actname = p;
p = skipnsp(p);
c = *p;
*p = '\0';
/*
* Parse the action name and store it in the current table.
*/
action = findaction(actname);
/*
* See if an extra string follows the action name.
*/
*p = c;
p = skipsp(p);
if (*p == '\0')
{
add_cmd_char(action);
} else
{
/*
* OR the special value A_EXTRA into the action byte.
* Put the extra string after the action byte.
*/
add_cmd_char(action | A_EXTRA);
while (*p != '\0')
add_cmd_str(tstr(&p));
add_cmd_char('\0');
}
}
void
parse_varline(p)
char *p;
{
char *s;
do
{
s = tstr(&p);
add_cmd_str(s);
} while (*p != ' ' && *p != '\t' && *p != '=' && *p != '\0');
/*
* Terminate the variable name with a null byte.
*/
add_cmd_char('\0');
p = skipsp(p);
if (*p++ != '=')
{
error("missing =");
return;
}
add_cmd_char(EV_OK|A_EXTRA);
p = skipsp(p);
while (*p != '\0')
{
s = tstr(&p);
add_cmd_str(s);
}
add_cmd_char('\0');
}
/*
* Parse a line from the lesskey file.
*/
void
parse_line(line)
char *line;
{
char *p;
/*
* See if it is a control line.
*/
if (control_line(line))
return;
/*
* Skip leading white space.
* Replace the final newline with a null byte.
* Ignore blank lines and comments.
*/
p = clean_line(line);
if (*p == '\0')
return;
if (currtable == &vartable)
parse_varline(p);
else
parse_cmdline(p);
}
int
main(argc, argv)
int argc;
char *argv[];
{
FILE *desc;
FILE *out;
char line[200];
#ifdef WIN32
if (getenv("HOME") == NULL)
{
/*
* If there is no HOME environment variable,
* try the concatenation of HOMEDRIVE + HOMEPATH.
*/
char *drive = getenv("HOMEDRIVE");
char *path = getenv("HOMEPATH");
if (drive != NULL && path != NULL)
{
char *env = (char *) calloc(strlen(drive) +
strlen(path) + 6, sizeof(char));
strcpy(env, "HOME=");
strcat(env, drive);
strcat(env, path);
putenv(env);
}
}
#endif /* WIN32 */
/*
* Process command line arguments.
*/
parse_args(argc, argv);
init_tables();
/*
* Open the input file.
*/
if (strcmp(infile, "-") == 0)
desc = stdin;
else if ((desc = fopen(infile, "r")) == NULL)
{
#if HAVE_PERROR
perror(infile);
#else
fprintf(stderr, "Cannot open %s\n", infile);
#endif
usage();
}
/*
* Read and parse the input file, one line at a time.
*/
errors = 0;
linenum = 0;
while (fgets(line, sizeof(line), desc) != NULL)
{
++linenum;
parse_line(line);
}
/*
* Write the output file.
* If no output file was specified, use "$HOME/.less"
*/
if (errors > 0)
{
fprintf(stderr, "%d errors; no output produced\n", errors);
exit(1);
}
if (outfile == NULL)
outfile = getenv("LESSKEY");
if (outfile == NULL)
outfile = homefile(LESSKEYFILE);
if ((out = fopen(outfile, "wb")) == NULL)
{
#if HAVE_PERROR
perror(outfile);
#else
fprintf(stderr, "Cannot open %s\n", outfile);
#endif
exit(1);
}
/* File header */
fputbytes(out, fileheader, sizeof(fileheader));
/* Command key section */
fputbytes(out, cmdsection, sizeof(cmdsection));
fputint(out, cmdtable.pbuffer - cmdtable.buffer);
fputbytes(out, (char *)cmdtable.buffer, cmdtable.pbuffer-cmdtable.buffer);
/* Edit key section */
fputbytes(out, editsection, sizeof(editsection));
fputint(out, edittable.pbuffer - edittable.buffer);
fputbytes(out, (char *)edittable.buffer, edittable.pbuffer-edittable.buffer);
/* Environment variable section */
fputbytes(out, varsection, sizeof(varsection));
fputint(out, vartable.pbuffer - vartable.buffer);
fputbytes(out, (char *)vartable.buffer, vartable.pbuffer-vartable.buffer);
/* File trailer */
fputbytes(out, endsection, sizeof(endsection));
fputbytes(out, filetrailer, sizeof(filetrailer));
return (0);
}

40
contrib/less/lesskey.h Normal file
View File

@ -0,0 +1,40 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Format of a lesskey file:
*
* LESSKEY_MAGIC (4 bytes)
* sections...
* END_LESSKEY_MAGIC (4 bytes)
*
* Each section is:
*
* section_MAGIC (1 byte)
* section_length (2 bytes)
* key table (section_length bytes)
*/
#define C0_LESSKEY_MAGIC '\0'
#define C1_LESSKEY_MAGIC 'M'
#define C2_LESSKEY_MAGIC '+'
#define C3_LESSKEY_MAGIC 'G'
#define CMD_SECTION 'c'
#define EDIT_SECTION 'e'
#define VAR_SECTION 'v'
#define END_SECTION 'x'
#define C0_END_LESSKEY_MAGIC 'E'
#define C1_END_LESSKEY_MAGIC 'n'
#define C2_END_LESSKEY_MAGIC 'd'
/* */
#define KRADIX 64

462
contrib/less/lesskey.man Normal file
View File

@ -0,0 +1,462 @@
LESSKEY(1) LESSKEY(1)
NNAAMMEE
lesskey - specify key bindings for less
SSYYNNOOPPSSIISS
lleesssskkeeyy [[--oo oouuttppuutt]] [[----]] [[iinnppuutt]]
lleesssskkeeyy [[----oouuttppuutt==oouuttppuutt]] [[----]] [[iinnppuutt]]
lleesssskkeeyy --VV
lleesssskkeeyy ----vveerrssiioonn
DDEESSCCRRIIPPTTIIOONN
_L_e_s_s_k_e_y is used to specify a set of key bindings to be
used by _l_e_s_s_. The input file is a text file which
describes the key bindings, If the input file is "-",
standard input is read. If no input file is specified, a
standard filename is used as the name of the input file,
which depends on the system being used: On Unix systems,
$HOME/.lesskey is used; on MS-DOS systems, $HOME/_lesskey
is used; and on OS/2 systems $HOME/lesskey.ini is used, or
$INIT/lesskey.ini if $HOME is undefined. The output file
is a binary file which is used by _l_e_s_s_. If no output file
is specified, and the environment variable LESSKEY is set,
the value of LESSKEY is used as the name of the output
file. Otherwise, a standard filename is used as the name
of the output file, which depends on the system being
used: On Unix and OS-9 systems, $HOME/.less is used; on
MS-DOS systems, $HOME/_less is used; and on OS/2 systems,
$HOME/less.ini is used, or $INIT/less.ini if $HOME is
undefined. If the output file already exists, _l_e_s_s_k_e_y
will overwrite it.
The -V or --version option causes _l_e_s_s_k_e_y to print its
version number and immediately exit. If -V or --version
is present, other options and arguments are ignored.
The input file consists of one or more _s_e_c_t_i_o_n_s_. Each
section starts with a line that identifies the type of
section. Possible sections are:
#command
Defines new command keys.
#line-edit
Defines new line-editing keys.
#env Defines environment variables.
Blank lines and lines which start with a pound sign (#)
are ignored, except for the special section header lines.
CCOOMMMMAANNDD SSEECCTTIIOONN
The command section begins with the line
#command
Version 354: 23 Mar 2000 1
LESSKEY(1) LESSKEY(1)
If the command section is the first section in the file,
this line may be omitted. The command section consists of
lines of the form:
_s_t_r_i_n_g <whitespace> _a_c_t_i_o_n [extra-string] <newline>
Whitespace is any sequence of one or more spaces and/or
tabs. The _s_t_r_i_n_g is the command key(s) which invoke the
action. The _s_t_r_i_n_g may be a single command key, or a
sequence of up to 15 keys. The _a_c_t_i_o_n is the name of the
less action, from the list below. The characters in the
_s_t_r_i_n_g may appear literally, or be prefixed by a caret to
indicate a control key. A backslash followed by one to
three octal digits may be used to specify a character by
its octal value. A backslash followed by certain charac-
ters specifies input characters as follows:
\b BACKSPACE
\e ESCAPE
\n NEWLINE
\r RETURN
\t TAB
\ku UP ARROW
\kd DOWN ARROW
\kr RIGHT ARROW
\kl LEFT ARROW
\kU PAGE UP
\kD PAGE DOWN
\kh HOME
\ke END
\kx DELETE
A backslash followed by any other character indicates that
character is to be taken literally. Characters which must
be preceded by backslash include caret, space, tab and the
backslash itself.
An action may be followed by an "extra" string. When such
a command is entered while running _l_e_s_s_, the action is
performed, and then the extra string is parsed, just as if
it were typed in to _l_e_s_s_. This feature can be used in
Version 354: 23 Mar 2000 2
LESSKEY(1) LESSKEY(1)
certain cases to extend the functionality of a command.
For example, see the "{" and ":t" commands in the example
below. The extra string has a special meaning for the
"quit" action: when _l_e_s_s quits, first character of the
extra string is used as its exit status.
EEXXAAMMPPLLEE
The following input file describes the set of default com-
mand keys used by less:
#command
\r forw-line
\n forw-line
e forw-line
j forw-line
\kd forw-line
^E forw-line
^N forw-line
k back-line
y back-line
^Y back-line
^K back-line
^P back-line
J forw-line-force
K back-line-force
Y back-line-force
d forw-scroll
^D forw-scroll
u back-scroll
^U back-scroll
\40 forw-screen
f forw-screen
^F forw-screen
^V forw-screen
\kD forw-screen
b back-screen
^B back-screen
\ev back-screen
\kU back-screen
z forw-window
w back-window
\e\40 forw-screen-force
F forw-forever
R repaint-flush
r repaint
^R repaint
^L repaint
\eu undo-hilite
g goto-line
< goto-line
\e< goto-line
p percent
% percent
Version 354: 23 Mar 2000 3
LESSKEY(1) LESSKEY(1)
\e[ left-scroll
\e] right-scroll
\e( left-scroll
\e) right-scroll
{ forw-bracket {}
} back-bracket {}
( forw-bracket ()
) back-bracket ()
[ forw-bracket []
] back-bracket []
\e^F forw-bracket
\e^B back-bracket
G goto-end
\e> goto-end
> goto-end
= status
^G status
:f status
/ forw-search
? back-search
\e/ forw-search *
\e? back-search *
n repeat-search
\en repeat-search-all
N reverse-search
\eN reverse-search-all
m set-mark
' goto-mark
^X^X goto-mark
E examine
:e examine
^X^V examine
:n next-file
:p prev-file
:x index-file
- toggle-option
:t toggle-option t
s toggle-option o
_ display-option
| pipe
v visual
! shell
+ firstcmd
H help
h help
V version
q quit
Q quit
:q quit
:Q quit
ZZ quit
Version 354: 23 Mar 2000 4
LESSKEY(1) LESSKEY(1)
PPRREECCEEDDEENNCCEE
Commands specified by _l_e_s_s_k_e_y take precedence over the
default commands. A default command key may be disabled
by including it in the input file with the action
"invalid". Alternatively, a key may be defined to do
nothing by using the action "noaction". "noaction" is
similar to "invalid", but _l_e_s_s will give an error beep for
an "invalid" command, but not for a "noaction" command.
In addition, ALL default commands may be disabled by
adding this control line to the input file:
#stop
This will cause all default commands to be ignored. The
#stop line should be the last line in that section of the
file.
Be aware that #stop can be dangerous. Since all default
commands are disabled, you must provide sufficient com-
mands before the #stop line to enable all necessary
actions. For example, failure to provide a "quit" command
can lead to frustration.
LLIINNEE EEDDIITTIINNGG SSEECCTTIIOONN
The line-editing section begins with the line:
#line-edit
This section specifies new key bindings for the line edit-
ing commands, in a manner similar to the way key bindings
for ordinary commands are specified in the #command sec-
tion. The line-editing section consists of a list of keys
and actions, one per line as in the example below.
EEXXAAMMPPLLEE
The following input file describes the set of default
line-editing keys used by less:
#line-edit
\t forw-complete
\17 back-complete
\e\t back-complete
^L expand
^V literal
^A literal
\el right
\kr right
\eh left
\kl left
\eb word-left
\e\kl word-left
\ew word-right
Version 354: 23 Mar 2000 5
LESSKEY(1) LESSKEY(1)
\e\kr word-right
\ei insert
\ex delete
\kx delete
\eX word-delete
\ekx word-delete
\e\b word-backspace
\e0 home
\kh home
\e$ end
\ke end
\ek up
\ku up
\ej down
LLEESSSS EENNVVIIRROONNMMEENNTT VVAARRIIAABBLLEESS
The environment variable section begins with the line
#env
Following this line is a list of environment variable
assignments. Each line consists of an environment vari-
able name, an equals sign (=) and the value to be assigned
to the environment variable. White space before and after
the equals sign is ignored. Variables assigned in this
way are visible only to _l_e_s_s_. If a variable is specified
in the system environment and also in a lesskey file, the
value in the lesskey file takes precedence. Although the
lesskey file can be used to override variables set in the
environment, the main purpose of assigning variables in
the lesskey file is simply to have all _l_e_s_s configuration
information stored in one file.
EEXXAAMMPPLLEE
The following input file sets the -i option whenever _l_e_s_s
is run, and specifies the character set to be "latin1":
#env
LESS = -i
LESSCHARSET = latin1
SSEEEE AALLSSOO
less(1)
WWAARRNNIINNGGSS
It is not possible to specify special keys, such as upar-
row, in a keyboard-independent manner. The only way to
specify such keys is to specify the escape sequence which
Version 354: 23 Mar 2000 6
LESSKEY(1) LESSKEY(1)
a particular keyboard sends when such a keys is pressed.
On MS-DOS and OS/2 systems, certain keys send a sequence
of characters which start with a NUL character (0). This
NUL character should be represented as \340 in a lesskey
file.
CCOOPPYYRRIIGGHHTT
Copyright (C) 2000 Mark Nudelman
lesskey is part of the GNU project and is free software;
you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option)
any later version.
lesskey is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied war-
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PUR-
POSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public
License along with lesskey; see the file COPYING. If not,
write to the Free Software Foundation, 59 Temple Place,
Suite 330, Boston, MA 02111-1307, USA.
AAUUTTHHOORR
Mark Nudelman <marknu@flash.net>
Send bug reports or comments to the above address or to
bug-less@gnu.org.
Version 354: 23 Mar 2000 7

369
contrib/less/lesskey.nro Normal file
View File

@ -0,0 +1,369 @@
.TH LESSKEY 1 "Version 354: 23 Mar 2000"
.SH NAME
lesskey \- specify key bindings for less
.SH SYNOPSIS
.B "lesskey [-o output] [--] [input]"
.br
.B "lesskey [--output=output] [--] [input]"
.br
.B "lesskey -V"
.br
.B "lesskey --version"
.SH DESCRIPTION
.I Lesskey
is used to specify a set of key bindings to be used by
.I less.
The input file is a text file which describes the key bindings,
If the input file is "-", standard input is read.
If no input file is specified, a standard filename is used
as the name of the input file, which depends on the system being used:
On Unix systems, $HOME/.lesskey is used;
on MS-DOS systems, $HOME/_lesskey is used;
and on OS/2 systems $HOME/lesskey.ini is used,
or $INIT/lesskey.ini if $HOME is undefined.
The output file is a binary file which is used by
.I less.
If no output file is specified,
and the environment variable LESSKEY is set,
the value of LESSKEY is used as the name of the output file.
Otherwise, a standard filename is used as the name of the output file,
which depends on the system being used:
On Unix and OS-9 systems, $HOME/.less is used;
on MS-DOS systems, $HOME/_less is used;
and on OS/2 systems, $HOME/less.ini is used,
or $INIT/less.ini if $HOME is undefined.
If the output file already exists,
.I lesskey
will overwrite it.
.PP
The -V or --version option causes
.I lesskey
to print its version number and immediately exit.
If -V or --version is present, other options and arguments are ignored.
.PP
The input file consists of one or more
.I sections.
Each section starts with a line that identifies the type of section.
Possible sections are:
.IP #command
Defines new command keys.
.IP #line-edit
Defines new line-editing keys.
.IP #env
Defines environment variables.
.PP
Blank lines and lines which start with a pound sign (#) are ignored,
except for the special section header lines.
.SH "COMMAND SECTION"
The command section begins with the line
.sp
#command
.sp
If the command section is the first section in the file,
this line may be omitted.
The command section consists of lines of the form:
.sp
\fIstring\fP <whitespace> \fIaction\fP [extra-string] <newline>
.sp
Whitespace is any sequence of one or more spaces and/or tabs.
The \fIstring\fP is the command key(s) which invoke the action.
The \fIstring\fP may be a single command key, or a sequence of up to 15 keys.
The \fIaction\fP is the name of the less action, from the list below.
The characters in the \fIstring\fP may appear literally, or be
prefixed by a caret to indicate a control key.
A backslash followed by one to three octal digits may be used to
specify a character by its octal value.
A backslash followed by certain characters specifies input
characters as follows:
.IP \eb
BACKSPACE
.IP \ee
ESCAPE
.IP \en
NEWLINE
.IP \er
RETURN
.IP \et
TAB
.IP \eku
UP ARROW
.IP \ekd
DOWN ARROW
.IP \ekr
RIGHT ARROW
.IP \ekl
LEFT ARROW
.IP \ekU
PAGE UP
.IP \ekD
PAGE DOWN
.IP \ekh
HOME
.IP \eke
END
.IP \ekx
DELETE
.PP
A backslash followed by any other character indicates that character is
to be taken literally.
Characters which must be preceded by backslash include
caret, space, tab and the backslash itself.
.PP
An action may be followed by an "extra" string.
When such a command is entered while running
.I less,
the action is performed, and then the extra
string is parsed, just as if it were typed in to
.I less.
This feature can be used in certain cases to extend
the functionality of a command.
For example, see the "{" and ":t" commands in the example below.
The extra string has a special meaning for the "quit" action:
when
.I less
quits, first character of the extra string is used as its exit status.
.SH EXAMPLE
The following input file describes the set of
default command keys used by less:
.sp
.nf
#command
\er forw-line
\en forw-line
e forw-line
j forw-line
\ekd forw-line
^E forw-line
^N forw-line
k back-line
y back-line
^Y back-line
^K back-line
^P back-line
J forw-line-force
K back-line-force
Y back-line-force
d forw-scroll
^D forw-scroll
u back-scroll
^U back-scroll
\e40 forw-screen
f forw-screen
^F forw-screen
^V forw-screen
\ekD forw-screen
b back-screen
^B back-screen
\eev back-screen
\ekU back-screen
z forw-window
w back-window
\ee\e40 forw-screen-force
F forw-forever
R repaint-flush
r repaint
^R repaint
^L repaint
\eeu undo-hilite
g goto-line
< goto-line
\ee< goto-line
p percent
% percent
\ee[ left-scroll
\ee] right-scroll
\ee( left-scroll
\ee) right-scroll
{ forw-bracket {}
} back-bracket {}
( forw-bracket ()
) back-bracket ()
[ forw-bracket []
] back-bracket []
\ee^F forw-bracket
\ee^B back-bracket
G goto-end
\ee> goto-end
> goto-end
= status
^G status
:f status
/ forw-search
? back-search
\ee/ forw-search *
\ee? back-search *
n repeat-search
\een repeat-search-all
N reverse-search
\eeN reverse-search-all
m set-mark
' goto-mark
^X^X goto-mark
E examine
:e examine
^X^V examine
:n next-file
:p prev-file
:x index-file
- toggle-option
:t toggle-option t
s toggle-option o
_ display-option
| pipe
v visual
! shell
+ firstcmd
H help
h help
V version
q quit
Q quit
:q quit
:Q quit
ZZ quit
.fi
.sp
.SH PRECEDENCE
Commands specified by
.I lesskey
take precedence over the default commands.
A default command key may be disabled by including it in the
input file with the action "invalid".
Alternatively, a key may be defined
to do nothing by using the action "noaction".
"noaction" is similar to "invalid", but
.I less
will give an error beep for an "invalid" command,
but not for a "noaction" command.
In addition, ALL default commands may be disabled by
adding this control line to the input file:
.sp
#stop
.sp
This will cause all default commands to be ignored.
The #stop line should be the last line in that section of the file.
.PP
Be aware that #stop can be dangerous.
Since all default commands are disabled,
you must provide sufficient commands before the #stop line
to enable all necessary actions.
For example, failure to provide a "quit" command can lead to frustration.
.SH "LINE EDITING SECTION"
The line-editing section begins with the line:
.sp
#line-edit
.sp
This section specifies new key bindings for the line editing commands,
in a manner similar to the way key bindings for
ordinary commands are specified in the #command section.
The line-editing section consists of a list of keys and actions,
one per line as in the example below.
.SH EXAMPLE
The following input file describes the set of
default line-editing keys used by less:
.sp
.nf
#line-edit
\et forw-complete
\e17 back-complete
\ee\et back-complete
^L expand
^V literal
^A literal
\eel right
\ekr right
\eeh left
\ekl left
\eeb word-left
\ee\ekl word-left
\eew word-right
\ee\ekr word-right
\eei insert
\eex delete
\ekx delete
\eeX word-delete
\eekx word-delete
\ee\eb word-backspace
\ee0 home
\ekh home
\ee$ end
\eke end
\eek up
\eku up
\eej down
.fi
.sp
.SH "LESS ENVIRONMENT VARIABLES"
The environment variable section begins with the line
.sp
#env
.sp
Following this line is a list of environment variable assignments.
Each line consists of an environment variable name, an equals sign (=)
and the value to be assigned to the environment variable.
White space before and after the equals sign is ignored.
Variables assigned in this way are visible only to
.I less.
If a variable is specified in the system environment and also in a
lesskey file, the value in the lesskey file takes precedence.
Although the lesskey file can be used to override variables set in the
environment, the main purpose of assigning variables in the lesskey file
is simply to have all
.I less
configuration information stored in one file.
.SH EXAMPLE
The following input file sets the -i option whenever
.I less
is run, and specifies the character set to be "latin1":
.sp
.nf
#env
LESS = -i
LESSCHARSET = latin1
.fi
.sp
.SH "SEE ALSO"
less(1)
.SH WARNINGS
It is not possible to specify special keys, such as uparrow,
in a keyboard-independent manner.
The only way to specify such keys is to specify the escape sequence
which a particular keyboard sends when such a keys is pressed.
.PP
On MS-DOS and OS/2 systems, certain keys send a sequence of characters
which start with a NUL character (0).
This NUL character should be represented as \e340 in a lesskey file.
.SH COPYRIGHT
Copyright (C) 2000 Mark Nudelman
.PP
lesskey is part of the GNU project and is free software;
you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation;
either version 2, or (at your option) any later version.
.PP
lesskey is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
.PP
You should have received a copy of the GNU General Public License
along with lesskey; see the file COPYING.
If not, write to the Free Software Foundation, 59 Temple Place,
Suite 330, Boston, MA 02111-1307, USA.
.SH AUTHOR
.PP
Mark Nudelman <marknu@flash.net>
.br
Send bug reports or comments to the above address or to bug-less@gnu.org.

95
contrib/less/lglob.h Normal file
View File

@ -0,0 +1,95 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Macros to define the method of doing filename "globbing".
* There are three possible mechanisms:
* 1. GLOB_LIST
* This defines a function that returns a list of matching filenames.
* 2. GLOB_NAME
* This defines a function that steps thru the list of matching
* filenames, returning one name each time it is called.
* 3. GLOB_STRING
* This defines a function that returns the complete list of
* matching filenames as a single space-separated string.
*/
#if OS2
#define DECL_GLOB_LIST(list) char **list; char **pp;
#define GLOB_LIST(filename,list) list = _fnexplode(filename)
#define GLOB_LIST_FAILED(list) list == NULL
#define SCAN_GLOB_LIST(list,p) pp = list; *pp != NULL; pp++
#define INIT_GLOB_LIST(list,p) p = *pp
#define GLOB_LIST_DONE(list) _fnexplodefree(list)
#else
#if MSDOS_COMPILER==DJGPPC
#define DECL_GLOB_LIST(list) glob_t list; int i;
#define GLOB_LIST(filename,list) glob(filename,GLOB_NOCHECK,0,&list)
#define GLOB_LIST_FAILED(list) 0
#define SCAN_GLOB_LIST(list,p) i = 0; i < list.gl_pathc; i++
#define INIT_GLOB_LIST(list,p) p = list.gl_pathv[i]
#define GLOB_LIST_DONE(list) globfree(&list)
#else
#if MSDOS_COMPILER==MSOFTC || MSDOS_COMPILER==BORLANDC
#define GLOB_FIRST_NAME(filename,fndp,h) h = _dos_findfirst(filename, ~_A_VOLID, fndp)
#define GLOB_FIRST_FAILED(handle) ((handle) != 0)
#define GLOB_NEXT_NAME(handle,fndp) _dos_findnext(fndp)
#define GLOB_NAME_DONE(handle)
#define GLOB_NAME name
#define DECL_GLOB_NAME(fnd,drive,dir,fname,ext,handle) \
struct find_t fnd; \
char drive[_MAX_DRIVE]; \
char dir[_MAX_DIR]; \
char fname[_MAX_FNAME]; \
char ext[_MAX_EXT]; \
int handle;
#else
#if MSDOS_COMPILER==WIN32C && defined(_MSC_VER)
#define GLOB_FIRST_NAME(filename,fndp,h) h = _findfirst(filename, fndp)
#define GLOB_FIRST_FAILED(handle) ((handle) == -1)
#define GLOB_NEXT_NAME(handle,fndp) _findnext(handle, fndp)
#define GLOB_NAME_DONE(handle) _findclose(handle)
#define GLOB_NAME name
#define DECL_GLOB_NAME(fnd,drive,dir,fname,ext,handle) \
struct _finddata_t fnd; \
char drive[_MAX_DRIVE]; \
char dir[_MAX_DIR]; \
char fname[_MAX_FNAME]; \
char ext[_MAX_EXT]; \
long handle;
#else
#if MSDOS_COMPILER==WIN32C && !defined(_MSC_VER) /* Borland C for Windows */
#define GLOB_FIRST_NAME(filename,fndp,h) h = findfirst(filename, fndp, ~FA_LABEL)
#define GLOB_FIRST_FAILED(handle) ((handle) != 0)
#define GLOB_NEXT_NAME(handle,fndp) findnext(fndp)
#define GLOB_NAME_DONE(handle)
#define GLOB_NAME ff_name
#define DECL_GLOB_NAME(fnd,drive,dir,fname,ext,handle) \
struct ffblk fnd; \
char drive[MAXDRIVE]; \
char dir[MAXDIR]; \
char fname[MAXFILE]; \
char ext[MAXEXT]; \
int handle;
#endif
#endif
#endif
#endif
#endif

696
contrib/less/line.c Normal file
View File

@ -0,0 +1,696 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Routines to manipulate the "line buffer".
* The line buffer holds a line of output as it is being built
* in preparation for output to the screen.
*/
#include "less.h"
#define IS_CONT(c) (((c) & 0xC0) == 0x80)
/* Buffer which holds the current output line */
public char linebuf[LINEBUF_SIZE];
public int size_linebuf = sizeof(linebuf);
public int cshift; /* Current left-shift of output line buffer */
public int hshift; /* Desired left-shift of output line buffer */
static char attr[LINEBUF_SIZE]; /* Extension of linebuf to hold attributes */
static int curr; /* Index into linebuf */
static int column; /* Printable length, accounting for
backspaces, etc. */
static int overstrike; /* Next char should overstrike previous char */
static int is_null_line; /* There is no current line */
static char pendc;
static POSITION pendpos;
static char *end_ansi_chars;
static int do_append();
extern int bs_mode;
extern int tabstop;
extern int linenums;
extern int ctldisp;
extern int twiddle;
extern int binattr;
extern int auto_wrap, ignaw;
extern int bo_s_width, bo_e_width;
extern int ul_s_width, ul_e_width;
extern int bl_s_width, bl_e_width;
extern int so_s_width, so_e_width;
extern int sc_width, sc_height;
extern int utf_mode;
/*
* Initialize from environment variables.
*/
public void
init_line()
{
end_ansi_chars = lgetenv("LESSANSIENDCHARS");
if (end_ansi_chars == NULL || *end_ansi_chars == '\0')
end_ansi_chars = "m";
}
/*
* Rewind the line buffer.
*/
public void
prewind()
{
curr = 0;
column = 0;
overstrike = 0;
is_null_line = 0;
pendc = '\0';
}
/*
* Insert the line number (of the given position) into the line buffer.
*/
public void
plinenum(pos)
POSITION pos;
{
register int lno;
register int i;
register int n;
/*
* We display the line number at the start of each line
* only if the -N option is set.
*/
if (linenums != OPT_ONPLUS)
return;
/*
* Get the line number and put it in the current line.
* {{ Note: since find_linenum calls forw_raw_line,
* it may seek in the input file, requiring the caller
* of plinenum to re-seek if necessary. }}
*/
lno = find_linenum(pos);
sprintf(&linebuf[curr], "%6d", lno);
n = strlen(&linebuf[curr]);
column += n;
for (i = 0; i < n; i++)
attr[curr++] = 0;
/*
* Append enough spaces to bring us to the next tab stop.
* {{ We could avoid this at the cost of adding some
* complication to the tab stop logic in pappend(). }}
*/
if (tabstop == 0)
tabstop = 1;
do
{
linebuf[curr] = ' ';
attr[curr++] = AT_NORMAL;
column++;
} while (((column + cshift) % tabstop) != 0);
}
/*
*
*/
static int
utf_len(char *s, int len)
{
int ulen = 0;
while (*s != '\0' && len > 0)
{
if (!IS_CONT(*s))
len--;
s++;
ulen++;
}
while (IS_CONT(*s))
{
s++;
ulen++;
}
return (ulen);
}
/*
* Shift the input line left.
* This means discarding N printable chars at the start of the buffer.
*/
static void
pshift(shift)
int shift;
{
int i;
int real_shift;
if (shift > column)
shift = column;
if (shift > curr)
shift = curr;
if (!utf_mode)
real_shift = shift;
else
{
real_shift = utf_len(linebuf, shift);
if (real_shift > curr)
real_shift = curr;
}
for (i = 0; i < curr - real_shift; i++)
{
linebuf[i] = linebuf[i + real_shift];
attr[i] = attr[i + real_shift];
}
column -= shift;
curr -= real_shift;
cshift += shift;
}
/*
* Return the printing width of the start (enter) sequence
* for a given character attribute.
*/
static int
attr_swidth(a)
int a;
{
switch (a)
{
case AT_BOLD: return (bo_s_width);
case AT_UNDERLINE: return (ul_s_width);
case AT_BLINK: return (bl_s_width);
case AT_STANDOUT: return (so_s_width);
}
return (0);
}
/*
* Return the printing width of the end (exit) sequence
* for a given character attribute.
*/
static int
attr_ewidth(a)
int a;
{
switch (a)
{
case AT_BOLD: return (bo_e_width);
case AT_UNDERLINE: return (ul_e_width);
case AT_BLINK: return (bl_e_width);
case AT_STANDOUT: return (so_e_width);
}
return (0);
}
/*
* Return the printing width of a given character and attribute,
* if the character were added to the current position in the line buffer.
* Adding a character with a given attribute may cause an enter or exit
* attribute sequence to be inserted, so this must be taken into account.
*/
static int
pwidth(c, a)
int c;
int a;
{
register int w;
if (utf_mode && IS_CONT(c))
return (0);
if (c == '\b')
/*
* Backspace moves backwards one position.
*/
return (-1);
if (control_char(c))
/*
* Control characters do unpredicatable things,
* so we don't even try to guess; say it doesn't move.
* This can only happen if the -r flag is in effect.
*/
return (0);
/*
* Other characters take one space,
* plus the width of any attribute enter/exit sequence.
*/
w = 1;
if (curr > 0 && attr[curr-1] != a)
w += attr_ewidth(attr[curr-1]);
if (a && (curr == 0 || attr[curr-1] != a))
w += attr_swidth(a);
return (w);
}
/*
* Delete the previous character in the line buffer.
*/
static void
backc()
{
curr--;
column -= pwidth(linebuf[curr], attr[curr]);
}
/*
* Are we currently within a recognized ANSI escape sequence?
*/
static int
in_ansi_esc_seq()
{
int i;
/*
* Search backwards for either an ESC (which means we ARE in a seq);
* or an end char (which means we're NOT in a seq).
*/
for (i = curr-1; i >= 0; i--)
{
if (linebuf[i] == ESC)
return (1);
if (strchr(end_ansi_chars, linebuf[i]) != NULL)
return (0);
}
return (0);
}
/*
* Append a character and attribute to the line buffer.
*/
static int
storec(c, a, pos)
int c;
int a;
POSITION pos;
{
register int w;
#if HILITE_SEARCH
if (is_hilited(pos, pos+1, 0))
/*
* This character should be highlighted.
* Override the attribute passed in.
*/
a = AT_STANDOUT;
#endif
if (ctldisp == OPT_ONPLUS && in_ansi_esc_seq())
w = 0;
else
w = pwidth(c, a);
if (ctldisp != OPT_ON && column + w + attr_ewidth(a) > sc_width)
/*
* Won't fit on screen.
*/
return (1);
if (curr >= sizeof(linebuf)-2)
/*
* Won't fit in line buffer.
*/
return (1);
/*
* Special handling for "magic cookie" terminals.
* If an attribute enter/exit sequence has a printing width > 0,
* and the sequence is adjacent to a space, delete the space.
* We just mark the space as invisible, to avoid having too
* many spaces deleted.
* {{ Note that even if the attribute width is > 1, we
* delete only one space. It's not worth trying to do more.
* It's hardly worth doing this much. }}
*/
if (curr > 0 && a != AT_NORMAL &&
linebuf[curr-1] == ' ' && attr[curr-1] == AT_NORMAL &&
attr_swidth(a) > 0)
{
/*
* We are about to append an enter-attribute sequence
* just after a space. Delete the space.
*/
attr[curr-1] = AT_INVIS;
column--;
} else if (curr > 0 && attr[curr-1] != AT_NORMAL &&
attr[curr-1] != AT_INVIS && c == ' ' && a == AT_NORMAL &&
attr_ewidth(attr[curr-1]) > 0)
{
/*
* We are about to append a space just after an
* exit-attribute sequence. Delete the space.
*/
a = AT_INVIS;
column--;
}
/* End of magic cookie handling. */
linebuf[curr] = c;
attr[curr] = a;
column += w;
return (0);
}
/*
* Append a character to the line buffer.
* Expand tabs into spaces, handle underlining, boldfacing, etc.
* Returns 0 if ok, 1 if couldn't fit in buffer.
*/
public int
pappend(c, pos)
register int c;
POSITION pos;
{
int r;
if (pendc)
{
if (do_append(pendc, pendpos))
/*
* Oops. We've probably lost the char which
* was in pendc, since caller won't back up.
*/
return (1);
pendc = '\0';
}
if (c == '\r' && bs_mode == BS_SPECIAL)
{
/*
* Don't put the CR into the buffer until we see
* the next char. If the next char is a newline,
* discard the CR.
*/
pendc = c;
pendpos = pos;
return (0);
}
r = do_append(c, pos);
/*
* If we need to shift the line, do it.
* But wait until we get to at least the middle of the screen,
* so shifting it doesn't affect the chars we're currently
* pappending. (Bold & underline can get messed up otherwise.)
*/
if (cshift < hshift && column > sc_width / 2)
pshift(hshift - cshift);
return (r);
}
static int
do_append(c, pos)
int c;
POSITION pos;
{
register char *s;
register int a;
#define STOREC(c,a) \
if (storec((c),(a),pos)) return (1); else curr++
if (c == '\b')
{
switch (bs_mode)
{
case BS_NORMAL:
STOREC(c, AT_NORMAL);
break;
case BS_CONTROL:
goto do_control_char;
case BS_SPECIAL:
if (curr == 0)
break;
backc();
overstrike = 1;
break;
}
} else if (overstrike)
{
/*
* Overstrike the character at the current position
* in the line buffer. This will cause either
* underline (if a "_" is overstruck),
* bold (if an identical character is overstruck),
* or just deletion of the character in the buffer.
*/
overstrike = 0;
if ((char)c == linebuf[curr])
STOREC(linebuf[curr], AT_BOLD);
else if (c == '_')
STOREC(linebuf[curr], AT_UNDERLINE);
else if (linebuf[curr] == '_')
STOREC(c, AT_UNDERLINE);
else if (control_char(c))
goto do_control_char;
else
STOREC(c, AT_NORMAL);
} else if (c == '\t')
{
/*
* Expand a tab into spaces.
*/
if (tabstop == 0)
tabstop = 1;
switch (bs_mode)
{
case BS_CONTROL:
goto do_control_char;
case BS_NORMAL:
case BS_SPECIAL:
do
{
STOREC(' ', AT_NORMAL);
} while (((column + cshift) % tabstop) != 0);
break;
}
} else if (control_char(c))
{
do_control_char:
if (ctldisp == OPT_ON || (ctldisp == OPT_ONPLUS && c == ESC))
{
/*
* Output as a normal character.
*/
STOREC(c, AT_NORMAL);
} else
{
/*
* Convert to printable representation.
*/
s = prchar(c);
a = binattr;
/*
* Make sure we can get the entire representation
* of the character on this line.
*/
if (column + (int) strlen(s) +
attr_swidth(a) + attr_ewidth(a) > sc_width)
return (1);
for ( ; *s != 0; s++)
STOREC(*s, a);
}
} else
{
STOREC(c, AT_NORMAL);
}
return (0);
}
/*
* Terminate the line in the line buffer.
*/
public void
pdone(endline)
int endline;
{
if (pendc && (pendc != '\r' || !endline))
/*
* If we had a pending character, put it in the buffer.
* But discard a pending CR if we are at end of line
* (that is, discard the CR in a CR/LF sequence).
*/
(void) do_append(pendc, pendpos);
/*
* Make sure we've shifted the line, if we need to.
*/
if (cshift < hshift)
pshift(hshift - cshift);
/*
* Add a newline if necessary,
* and append a '\0' to the end of the line.
*/
if (column < sc_width || !auto_wrap || ignaw || ctldisp == OPT_ON)
{
linebuf[curr] = '\n';
attr[curr] = AT_NORMAL;
curr++;
}
linebuf[curr] = '\0';
attr[curr] = AT_NORMAL;
/*
* If we are done with this line, reset the current shift.
*/
if (endline)
cshift = 0;
}
/*
* Get a character from the current line.
* Return the character as the function return value,
* and the character attribute in *ap.
*/
public int
gline(i, ap)
register int i;
register int *ap;
{
char *s;
if (is_null_line)
{
/*
* If there is no current line, we pretend the line is
* either "~" or "", depending on the "twiddle" flag.
*/
*ap = AT_BOLD;
s = (twiddle) ? "~\n" : "\n";
return (s[i]);
}
*ap = attr[i];
return (linebuf[i] & 0377);
}
/*
* Indicate that there is no current line.
*/
public void
null_line()
{
is_null_line = 1;
cshift = 0;
}
/*
* Analogous to forw_line(), but deals with "raw lines":
* lines which are not split for screen width.
* {{ This is supposed to be more efficient than forw_line(). }}
*/
public POSITION
forw_raw_line(curr_pos, linep)
POSITION curr_pos;
char **linep;
{
register char *p;
register int c;
POSITION new_pos;
if (curr_pos == NULL_POSITION || ch_seek(curr_pos) ||
(c = ch_forw_get()) == EOI)
return (NULL_POSITION);
p = linebuf;
for (;;)
{
if (c == '\n' || c == EOI)
{
new_pos = ch_tell();
break;
}
if (p >= &linebuf[sizeof(linebuf)-1])
{
/*
* Overflowed the input buffer.
* Pretend the line ended here.
* {{ The line buffer is supposed to be big
* enough that this never happens. }}
*/
new_pos = ch_tell() - 1;
break;
}
*p++ = c;
c = ch_forw_get();
}
*p = '\0';
if (linep != NULL)
*linep = linebuf;
return (new_pos);
}
/*
* Analogous to back_line(), but deals with "raw lines".
* {{ This is supposed to be more efficient than back_line(). }}
*/
public POSITION
back_raw_line(curr_pos, linep)
POSITION curr_pos;
char **linep;
{
register char *p;
register int c;
POSITION new_pos;
if (curr_pos == NULL_POSITION || curr_pos <= ch_zero() ||
ch_seek(curr_pos-1))
return (NULL_POSITION);
p = &linebuf[sizeof(linebuf)];
*--p = '\0';
for (;;)
{
c = ch_back_get();
if (c == '\n')
{
/*
* This is the newline ending the previous line.
* We have hit the beginning of the line.
*/
new_pos = ch_tell() + 1;
break;
}
if (c == EOI)
{
/*
* We have hit the beginning of the file.
* This must be the first line in the file.
* This must, of course, be the beginning of the line.
*/
new_pos = ch_zero();
break;
}
if (p <= linebuf)
{
/*
* Overflowed the input buffer.
* Pretend the line ended here.
*/
new_pos = ch_tell() + 1;
break;
}
*--p = c;
}
if (linep != NULL)
*linep = p;
return (new_pos);
}

454
contrib/less/linenum.c Normal file
View File

@ -0,0 +1,454 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Code to handle displaying line numbers.
*
* Finding the line number of a given file position is rather tricky.
* We don't want to just start at the beginning of the file and
* count newlines, because that is slow for large files (and also
* wouldn't work if we couldn't get to the start of the file; e.g.
* if input is a long pipe).
*
* So we use the function add_lnum to cache line numbers.
* We try to be very clever and keep only the more interesting
* line numbers when we run out of space in our table. A line
* number is more interesting than another when it is far from
* other line numbers. For example, we'd rather keep lines
* 100,200,300 than 100,101,300. 200 is more interesting than
* 101 because 101 can be derived very cheaply from 100, while
* 200 is more expensive to derive from 100.
*
* The function currline() returns the line number of a given
* position in the file. As a side effect, it calls add_lnum
* to cache the line number. Therefore currline is occasionally
* called to make sure we cache line numbers often enough.
*/
#include "less.h"
/*
* Structure to keep track of a line number and the associated file position.
* A doubly-linked circular list of line numbers is kept ordered by line number.
*/
struct linenum
{
struct linenum *next; /* Link to next in the list */
struct linenum *prev; /* Line to previous in the list */
POSITION pos; /* File position */
POSITION gap; /* Gap between prev and next */
int line; /* Line number */
};
/*
* "gap" needs some explanation: the gap of any particular line number
* is the distance between the previous one and the next one in the list.
* ("Distance" means difference in file position.) In other words, the
* gap of a line number is the gap which would be introduced if this
* line number were deleted. It is used to decide which one to replace
* when we have a new one to insert and the table is full.
*/
#define NPOOL 50 /* Size of line number pool */
#define LONGTIME (2) /* In seconds */
public int lnloop = 0; /* Are we in the line num loop? */
static struct linenum anchor; /* Anchor of the list */
static struct linenum *freelist; /* Anchor of the unused entries */
static struct linenum pool[NPOOL]; /* The pool itself */
static struct linenum *spare; /* We always keep one spare entry */
extern int linenums;
extern int sigs;
extern int sc_height;
/*
* Initialize the line number structures.
*/
public void
clr_linenum()
{
register struct linenum *p;
/*
* Put all the entries on the free list.
* Leave one for the "spare".
*/
for (p = pool; p < &pool[NPOOL-2]; p++)
p->next = p+1;
pool[NPOOL-2].next = NULL;
freelist = pool;
spare = &pool[NPOOL-1];
/*
* Initialize the anchor.
*/
anchor.next = anchor.prev = &anchor;
anchor.gap = 0;
anchor.pos = (POSITION)0;
anchor.line = 1;
}
/*
* Calculate the gap for an entry.
*/
static void
calcgap(p)
register struct linenum *p;
{
/*
* Don't bother to compute a gap for the anchor.
* Also don't compute a gap for the last one in the list.
* The gap for that last one should be considered infinite,
* but we never look at it anyway.
*/
if (p == &anchor || p->next == &anchor)
return;
p->gap = p->next->pos - p->prev->pos;
}
/*
* Add a new line number to the cache.
* The specified position (pos) should be the file position of the
* FIRST character in the specified line.
*/
public void
add_lnum(lno, pos)
int lno;
POSITION pos;
{
register struct linenum *p;
register struct linenum *new;
register struct linenum *nextp;
register struct linenum *prevp;
register POSITION mingap;
/*
* Find the proper place in the list for the new one.
* The entries are sorted by position.
*/
for (p = anchor.next; p != &anchor && p->pos < pos; p = p->next)
if (p->line == lno)
/* We already have this one. */
return;
nextp = p;
prevp = p->prev;
if (freelist != NULL)
{
/*
* We still have free (unused) entries.
* Use one of them.
*/
new = freelist;
freelist = freelist->next;
} else
{
/*
* No free entries.
* Use the "spare" entry.
*/
new = spare;
spare = NULL;
}
/*
* Fill in the fields of the new entry,
* and insert it into the proper place in the list.
*/
new->next = nextp;
new->prev = prevp;
new->pos = pos;
new->line = lno;
nextp->prev = new;
prevp->next = new;
/*
* Recalculate gaps for the new entry and the neighboring entries.
*/
calcgap(new);
calcgap(nextp);
calcgap(prevp);
if (spare == NULL)
{
/*
* We have used the spare entry.
* Scan the list to find the one with the smallest
* gap, take it out and make it the spare.
* We should never remove the last one, so stop when
* we get to p->next == &anchor. This also avoids
* looking at the gap of the last one, which is
* not computed by calcgap.
*/
mingap = anchor.next->gap;
for (p = anchor.next; p->next != &anchor; p = p->next)
{
if (p->gap <= mingap)
{
spare = p;
mingap = p->gap;
}
}
spare->next->prev = spare->prev;
spare->prev->next = spare->next;
}
}
/*
* If we get stuck in a long loop trying to figure out the
* line number, print a message to tell the user what we're doing.
*/
static void
longloopmessage()
{
ierror("Calculating line numbers", NULL_PARG);
/*
* Set the lnloop flag here, so if the user interrupts while
* we are calculating line numbers, the signal handler will
* turn off line numbers (linenums=0).
*/
lnloop = 1;
}
static int loopcount;
#if HAVE_TIME
static long startime;
#endif
static void
longish()
{
#if HAVE_TIME
if (loopcount >= 0 && ++loopcount > 100)
{
loopcount = 0;
if (get_time() >= startime + LONGTIME)
{
longloopmessage();
loopcount = -1;
}
}
#else
if (loopcount >= 0 && ++loopcount > LONGLOOP)
{
longloopmessage();
loopcount = -1;
}
#endif
}
/*
* Find the line number associated with a given position.
* Return 0 if we can't figure it out.
*/
public int
find_linenum(pos)
POSITION pos;
{
register struct linenum *p;
register int lno;
POSITION cpos;
if (!linenums)
/*
* We're not using line numbers.
*/
return (0);
if (pos == NULL_POSITION)
/*
* Caller doesn't know what he's talking about.
*/
return (0);
if (pos <= ch_zero())
/*
* Beginning of file is always line number 1.
*/
return (1);
/*
* Find the entry nearest to the position we want.
*/
for (p = anchor.next; p != &anchor && p->pos < pos; p = p->next)
continue;
if (p->pos == pos)
/* Found it exactly. */
return (p->line);
/*
* This is the (possibly) time-consuming part.
* We start at the line we just found and start
* reading the file forward or backward till we
* get to the place we want.
*
* First decide whether we should go forward from the
* previous one or backwards from the next one.
* The decision is based on which way involves
* traversing fewer bytes in the file.
*/
flush();
#if HAVE_TIME
startime = get_time();
#endif
if (p == &anchor || pos - p->prev->pos < p->pos - pos)
{
/*
* Go forward.
*/
p = p->prev;
if (ch_seek(p->pos))
return (0);
loopcount = 0;
for (lno = p->line, cpos = p->pos; cpos < pos; lno++)
{
/*
* Allow a signal to abort this loop.
*/
cpos = forw_raw_line(cpos, (char **)NULL);
if (ABORT_SIGS() || cpos == NULL_POSITION)
return (0);
longish();
}
lnloop = 0;
/*
* We might as well cache it.
*/
add_lnum(lno, cpos);
/*
* If the given position is not at the start of a line,
* make sure we return the correct line number.
*/
if (cpos > pos)
lno--;
} else
{
/*
* Go backward.
*/
if (ch_seek(p->pos))
return (0);
loopcount = 0;
for (lno = p->line, cpos = p->pos; cpos > pos; lno--)
{
/*
* Allow a signal to abort this loop.
*/
cpos = back_raw_line(cpos, (char **)NULL);
if (ABORT_SIGS() || cpos == NULL_POSITION)
return (0);
longish();
}
lnloop = 0;
/*
* We might as well cache it.
*/
add_lnum(lno, cpos);
}
return (lno);
}
/*
* Find the position of a given line number.
* Return NULL_POSITION if we can't figure it out.
*/
public POSITION
find_pos(lno)
int lno;
{
register struct linenum *p;
POSITION cpos;
int clno;
if (lno <= 1)
/*
* Line number 1 is beginning of file.
*/
return (ch_zero());
/*
* Find the entry nearest to the line number we want.
*/
for (p = anchor.next; p != &anchor && p->line < lno; p = p->next)
continue;
if (p->line == lno)
/* Found it exactly. */
return (p->pos);
flush();
if (p == &anchor || lno - p->prev->line < p->line - lno)
{
/*
* Go forward.
*/
p = p->prev;
if (ch_seek(p->pos))
return (NULL_POSITION);
for (clno = p->line, cpos = p->pos; clno < lno; clno++)
{
/*
* Allow a signal to abort this loop.
*/
cpos = forw_raw_line(cpos, (char **)NULL);
if (ABORT_SIGS() || cpos == NULL_POSITION)
return (NULL_POSITION);
}
} else
{
/*
* Go backward.
*/
if (ch_seek(p->pos))
return (NULL_POSITION);
for (clno = p->line, cpos = p->pos; clno > lno; clno--)
{
/*
* Allow a signal to abort this loop.
*/
cpos = back_raw_line(cpos, (char **)NULL);
if (ABORT_SIGS() || cpos == NULL_POSITION)
return (NULL_POSITION);
}
}
/*
* We might as well cache it.
*/
add_lnum(clno, cpos);
return (cpos);
}
/*
* Return the line number of the "current" line.
* The argument "where" tells which line is to be considered
* the "current" line (e.g. TOP, BOTTOM, MIDDLE, etc).
*/
public int
currline(where)
int where;
{
POSITION pos;
POSITION len;
int lnum;
pos = position(where);
len = ch_length();
while (pos == NULL_POSITION && where >= 0 && where < sc_height)
pos = position(++where);
if (pos == NULL_POSITION)
pos = len;
lnum = find_linenum(pos);
if (pos == len)
lnum--;
return (lnum);
}

510
contrib/less/lsystem.c Normal file
View File

@ -0,0 +1,510 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Routines to execute other programs.
* Necessarily very OS dependent.
*/
#include <signal.h>
#include "less.h"
#include "position.h"
#if MSDOS_COMPILER
#include <dos.h>
#ifdef _MSC_VER
#include <direct.h>
#define setdisk(n) _chdrive((n)+1)
#else
#include <dir.h>
#endif
#endif
extern int screen_trashed;
extern IFILE curr_ifile;
#if HAVE_SYSTEM
/*
* Pass the specified command to a shell to be executed.
* Like plain "system()", but handles resetting terminal modes, etc.
*/
public void
lsystem(cmd, donemsg)
char *cmd;
char *donemsg;
{
register int inp;
#if HAVE_SHELL
register char *shell;
register char *p;
#endif
IFILE save_ifile;
#if MSDOS_COMPILER
char cwd[FILENAME_MAX+1];
#endif
/*
* Print the command which is to be executed,
* unless the command starts with a "-".
*/
if (cmd[0] == '-')
cmd++;
else
{
clear_bot();
putstr("!");
putstr(cmd);
putstr("\n");
}
#if MSDOS_COMPILER
/*
* Working directory is global on MSDOS.
* The child might change the working directory, so we
* must save and restore CWD across calls to "system",
* or else we won't find our file when we return and
* try to "reedit_ifile" it.
*/
getcwd(cwd, FILENAME_MAX);
#endif
/*
* Close the current input file.
*/
save_ifile = save_curr_ifile();
(void) edit_ifile(NULL_IFILE);
/*
* De-initialize the terminal and take out of raw mode.
*/
deinit();
flush(); /* Make sure the deinit chars get out */
raw_mode(0);
#if MSDOS_COMPILER==WIN32C
close_getchr();
#endif
/*
* Restore signals to their defaults.
*/
init_signals(0);
#if HAVE_DUP
/*
* Force standard input to be the user's terminal
* (the normal standard input), even if less's standard input
* is coming from a pipe.
*/
inp = dup(0);
close(0);
if (open("/dev/tty", OPEN_READ) < 0)
dup(inp);
#endif
/*
* Pass the command to the system to be executed.
* If we have a SHELL environment variable, use
* <$SHELL -c "command"> instead of just <command>.
* If the command is empty, just invoke a shell.
*/
#if HAVE_SHELL
p = NULL;
if ((shell = lgetenv("SHELL")) != NULL && *shell != '\0')
{
if (*cmd == '\0')
p = save(shell);
else
{
char *esccmd;
if ((esccmd = esc_metachars(cmd)) == NULL)
{
p = (char *) ecalloc(strlen(shell) +
strlen(cmd) + 7, sizeof(char));
sprintf(p, "%s -c \"%s\"", shell, cmd);
} else
{
p = (char *) ecalloc(strlen(shell) +
strlen(esccmd) + 5, sizeof(char));
sprintf(p, "%s -c %s", shell, esccmd);
free(esccmd);
}
}
}
if (p == NULL)
{
if (*cmd == '\0')
p = save("sh");
else
p = save(cmd);
}
system(p);
free(p);
#else
#if MSDOS_COMPILER==DJGPPC
/*
* Make stdin of the child be in cooked mode.
*/
setmode(0, O_TEXT);
/*
* We don't need to catch signals of the child (it
* also makes trouble with some DPMI servers).
*/
__djgpp_exception_toggle();
system(cmd);
__djgpp_exception_toggle();
#else
system(cmd);
#endif
#endif
#if HAVE_DUP
/*
* Restore standard input, reset signals, raw mode, etc.
*/
close(0);
dup(inp);
close(inp);
#endif
#if MSDOS_COMPILER==WIN32C
open_getchr();
#endif
init_signals(1);
raw_mode(1);
if (donemsg != NULL)
{
putstr(donemsg);
putstr(" (press RETURN)");
get_return();
putchr('\n');
flush();
}
init();
screen_trashed = 1;
#if MSDOS_COMPILER
/*
* Restore the previous directory (possibly
* changed by the child program we just ran).
*/
chdir(cwd);
#if MSDOS_COMPILER != DJGPPC
/*
* Some versions of chdir() don't change to the drive
* which is part of CWD. (DJGPP does this in chdir.)
*/
if (cwd[1] == ':')
{
if (cwd[0] >= 'a' && cwd[0] <= 'z')
setdisk(cwd[0] - 'a');
else if (cwd[0] >= 'A' && cwd[0] <= 'Z')
setdisk(cwd[0] - 'A');
}
#endif
#endif
/*
* Reopen the current input file.
*/
reedit_ifile(save_ifile);
#if defined(SIGWINCH) || defined(SIGWIND)
/*
* Since we were ignoring window change signals while we executed
* the system command, we must assume the window changed.
* Warning: this leaves a signal pending (in "sigs"),
* so psignals() should be called soon after lsystem().
*/
winch(0);
#endif
}
#endif
#if PIPEC
/*
* Pipe a section of the input file into the given shell command.
* The section to be piped is the section "between" the current
* position and the position marked by the given letter.
*
* If the mark is after the current screen, the section between
* the top line displayed and the mark is piped.
* If the mark is before the current screen, the section between
* the mark and the bottom line displayed is piped.
* If the mark is on the current screen, or if the mark is ".",
* the whole current screen is piped.
*/
public int
pipe_mark(c, cmd)
int c;
char *cmd;
{
POSITION mpos, tpos, bpos;
/*
* mpos = the marked position.
* tpos = top of screen.
* bpos = bottom of screen.
*/
mpos = markpos(c);
if (mpos == NULL_POSITION)
return (-1);
tpos = position(TOP);
if (tpos == NULL_POSITION)
tpos = ch_zero();
bpos = position(BOTTOM);
if (c == '.')
return (pipe_data(cmd, tpos, bpos));
else if (mpos <= tpos)
return (pipe_data(cmd, mpos, bpos));
else if (bpos == NULL_POSITION)
return (pipe_data(cmd, tpos, bpos));
else
return (pipe_data(cmd, tpos, mpos));
}
/*
* Create a pipe to the given shell command.
* Feed it the file contents between the positions spos and epos.
*/
public int
pipe_data(cmd, spos, epos)
char *cmd;
POSITION spos;
POSITION epos;
{
register FILE *f;
register int c;
extern FILE *popen();
/*
* This is structured much like lsystem().
* Since we're running a shell program, we must be careful
* to perform the necessary deinitialization before running
* the command, and reinitialization after it.
*/
if (ch_seek(spos) != 0)
{
error("Cannot seek to start position", NULL_PARG);
return (-1);
}
if ((f = popen(cmd, "w")) == NULL)
{
error("Cannot create pipe", NULL_PARG);
return (-1);
}
clear_bot();
putstr("!");
putstr(cmd);
putstr("\n");
deinit();
flush();
raw_mode(0);
init_signals(0);
#if MSDOS_COMPILER==WIN32C
close_getchr();
#endif
#ifdef SIGPIPE
LSIGNAL(SIGPIPE, SIG_IGN);
#endif
c = EOI;
while (epos == NULL_POSITION || spos++ <= epos)
{
/*
* Read a character from the file and give it to the pipe.
*/
c = ch_forw_get();
if (c == EOI)
break;
if (putc(c, f) == EOF)
break;
}
/*
* Finish up the last line.
*/
while (c != '\n' && c != EOI )
{
c = ch_forw_get();
if (c == EOI)
break;
if (putc(c, f) == EOF)
break;
}
pclose(f);
#ifdef SIGPIPE
LSIGNAL(SIGPIPE, SIG_DFL);
#endif
#if MSDOS_COMPILER==WIN32C
open_getchr();
#endif
init_signals(1);
raw_mode(1);
init();
screen_trashed = 1;
#if defined(SIGWINCH) || defined(SIGWIND)
/* {{ Probably don't need this here. }} */
winch(0);
#endif
return (0);
}
#endif
#ifdef _OSK
/*
* Popen, and Pclose, for OS-9.
*
* Based on code copyright (c) 1988 by Wolfgang Ocker, Puchheim,
* Ulli Dessauer, Germering and
* Reimer Mellin, Muenchen
* (W-Germany)
*
* These functions can be copied and distributed freely for any
* non-commercial purposes. It can only be incorporated into
* commercial software with the written permission of the authors.
*
* TOP-specific code stripped out and adapted for less by M.Gregorie, 1996
*
* address: Wolfgang Ocker
* Lochhauserstrasse 35a
* D-8039 Puchheim
* West Germany
*
* e-mail: weo@altger.UUCP, ud@altger.UUCP, ram@altger.UUCP
* pyramid!tmpmbx!recco!weo
* pyramid!tmpmbx!nitmar!ud
* pyramid!tmpmbx!ramsys!ram
*
* Martin Gregorie
* 10 Sadlers Mead
* Harlow
* Essex, CM18 6HG
* U.K.
*
* gregorie@logica.com
*/
#include <strings.h>
#include <errno.h>
extern char **environ;
extern char *getenv();
extern int os9forkc();
static int pids[_NFILE] = { 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 };
/*
* p o p e n
*/
FILE *popen(name, mode)
char *name;
char *mode;
{
int fd, fd2, fdsav, pid;
static char *argv[] = {NULL, NULL, NULL };
static char cmd[200];
static char cmd_path[200];
char *cp;
char *shell;
FILE *r;
if ((shell = getenv("SHELL")) == NULL)
return(NULL);
cp = name;
while (*cp == ' ')
cp++;
strcpy(cmd_path, cp);
if (cp = index(cmd_path, ' '))
*cp++ = '\0';
strcpy(cmd, "ex ");
strcat(cmd, cmd_path);
if (cp)
{
strcat(cmd, " ");
strcat(cmd, cp);
}
argv[0] = shell;
argv[1] = cmd;
/*
mode is "r" (stdout) or "w" (stdin)
*/
switch(mode[0])
{
case 'w': fd = 0;
break;
case 'r': fd = 1;
break;
default: return(NULL);
}
if (fd == 1)
fflush(stdout);
fdsav = dup(fd);
close(fd);
creat("/pipe", S_IWRITE+S_IREAD);
pid = os9exec(os9forkc, argv[0], argv, environ, 0, 0, 3);
fd2 = dup(fd);
close(fd);
dup(fdsav);
close(fdsav);
if (pid > 0)
{
pids[fd2] = pid;
r = fdopen(fd2, mode);
}
else
{
close(fd2);
r = NULL;
}
return(r);
}
/*
* p c l o s e
*/
int pclose(fp)
FILE *fp;
{
unsigned int status;
int pid;
int fd,
i;
fd = fileno(fp);
if (pids[fd] == 0)
return(-1);
fflush(fp);
fclose(fp);
while ((pid = wait(&status)) != -1)
if (pid == pids[fd])
break;
else
for (i = 0; i < _NFILE; i++)
if (pids[i] == pid)
{
pids[i] = 0;
break;
}
if (pid == -1)
status = -1;
pids[fd] = 0;
return(status);
}
#endif /* _OSK */

370
contrib/less/main.c Normal file
View File

@ -0,0 +1,370 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Entry point, initialization, miscellaneous routines.
*/
#include "less.h"
public char * every_first_cmd = NULL;
public int new_file;
public int is_tty;
public IFILE curr_ifile = NULL_IFILE;
public IFILE old_ifile = NULL_IFILE;
public struct scrpos initial_scrpos;
public int any_display = FALSE;
public POSITION start_attnpos = NULL_POSITION;
public POSITION end_attnpos = NULL_POSITION;
public int wscroll;
public char * progname;
public int quitting;
public int secure;
public int dohelp;
#if LOGFILE
public int logfile = -1;
public int force_logfile = FALSE;
public char * namelogfile = NULL;
#endif
#if EDITOR
public char * editor;
public char * editproto;
#endif
#if TAGS
extern char * tagoption;
extern int jump_sline;
#endif
extern int missing_cap;
extern int know_dumb;
/*
* Entry point.
*/
int
main(argc, argv)
int argc;
char *argv[];
{
IFILE ifile;
char *s;
#ifdef __EMX__
_response(&argc, &argv);
_wildcard(&argc, &argv);
#endif
progname = *argv++;
argc--;
secure = 0;
s = lgetenv("LESSSECURE");
if (s != NULL && *s != '\0')
secure = 1;
#ifdef WIN32
if (getenv("HOME") == NULL)
{
/*
* If there is no HOME environment variable,
* try the concatenation of HOMEDRIVE + HOMEPATH.
*/
char *drive = getenv("HOMEDRIVE");
char *path = getenv("HOMEPATH");
if (drive != NULL && path != NULL)
{
char *env = (char *) ecalloc(strlen(drive) +
strlen(path) + 6, sizeof(char));
strcpy(env, "HOME=");
strcat(env, drive);
strcat(env, path);
putenv(env);
}
}
#endif /* WIN32 */
/*
* Process command line arguments and LESS environment arguments.
* Command line arguments override environment arguments.
*/
is_tty = isatty(1);
get_term();
init_cmds();
init_prompt();
init_charset();
init_line();
init_option();
s = lgetenv("LESS");
if (s != NULL)
scan_option(save(s));
#define isoptstring(s) (((s)[0] == '-' || (s)[0] == '+') && (s)[1] != '\0')
while (argc > 0 && (isoptstring(*argv) || isoptpending()))
{
s = *argv++;
argc--;
if (strcmp(s, "--") == 0)
break;
scan_option(s);
}
#undef isoptstring
if (isoptpending())
{
/*
* Last command line option was a flag requiring a
* following string, but there was no following string.
*/
nopendopt();
quit(QUIT_OK);
}
#if EDITOR
editor = lgetenv("VISUAL");
if (editor == NULL || *editor == '\0')
{
editor = lgetenv("EDITOR");
if (editor == NULL || *editor == '\0')
editor = EDIT_PGM;
}
editproto = lgetenv("LESSEDIT");
if (editproto == NULL || *editproto == '\0')
editproto = "%E ?lm+%lm. %f";
#endif
/*
* Call get_ifile with all the command line filenames
* to "register" them with the ifile system.
*/
ifile = NULL_IFILE;
if (dohelp)
ifile = get_ifile(FAKE_HELPFILE, ifile);
while (argc-- > 0)
{
#if (MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC) || OS2
/*
* Because the "shell" doesn't expand filename patterns,
* treat each argument as a filename pattern rather than
* a single filename.
* Expand the pattern and iterate over the expanded list.
*/
struct textlist tlist;
char *gfilename;
char *filename;
gfilename = lglob(*argv++);
init_textlist(&tlist, gfilename);
filename = NULL;
while ((filename = forw_textlist(&tlist, filename)) != NULL)
ifile = get_ifile(filename, ifile);
free(gfilename);
#else
ifile = get_ifile(*argv++, ifile);
#endif
}
/*
* Set up terminal, etc.
*/
if (!is_tty)
{
/*
* Output is not a tty.
* Just copy the input file(s) to output.
*/
SET_BINARY(1);
if (nifile() == 0)
{
if (edit_stdin() == 0)
cat_file();
} else if (edit_first() == 0)
{
do {
cat_file();
} while (edit_next(1) == 0);
}
quit(QUIT_OK);
}
if (missing_cap && !know_dumb)
error("WARNING: terminal is not fully functional", NULL_PARG);
init_mark();
raw_mode(1);
open_getchr();
init_signals(1);
/*
* Select the first file to examine.
*/
#if TAGS
if (tagoption != NULL)
{
/*
* A -t option was given.
* Verify that no filenames were also given.
* Edit the file selected by the "tags" search,
* and search for the proper line in the file.
*/
if (nifile() > 0)
{
error("No filenames allowed with -t option", NULL_PARG);
quit(QUIT_ERROR);
}
findtag(tagoption);
if (edit_tagfile()) /* Edit file which contains the tag */
quit(QUIT_ERROR);
/*
* Search for the line which contains the tag.
* Set up initial_scrpos so we display that line.
*/
initial_scrpos.pos = tagsearch();
if (initial_scrpos.pos == NULL_POSITION)
quit(QUIT_ERROR);
initial_scrpos.ln = jump_sline;
} else
#endif
if (nifile() == 0)
{
if (edit_stdin()) /* Edit standard input */
quit(QUIT_ERROR);
} else
{
if (edit_first()) /* Edit first valid file in cmd line */
quit(QUIT_ERROR);
}
init();
commands();
quit(QUIT_OK);
/*NOTREACHED*/
}
/*
* Copy a string to a "safe" place
* (that is, to a buffer allocated by calloc).
*/
public char *
save(s)
char *s;
{
register char *p;
p = (char *) ecalloc(strlen(s)+1, sizeof(char));
strcpy(p, s);
return (p);
}
/*
* Allocate memory.
* Like calloc(), but never returns an error (NULL).
*/
public VOID_POINTER
ecalloc(count, size)
int count;
unsigned int size;
{
register VOID_POINTER p;
p = (VOID_POINTER) calloc(count, size);
if (p != NULL)
return (p);
error("Cannot allocate memory", NULL_PARG);
quit(QUIT_ERROR);
/*NOTREACHED*/
}
/*
* Skip leading spaces in a string.
*/
public char *
skipsp(s)
register char *s;
{
while (*s == ' ' || *s == '\t')
s++;
return (s);
}
/*
* See how many characters of two strings are identical.
* If uppercase is true, the first string must begin with an uppercase
* character; the remainder of the first string may be either case.
*/
public int
sprefix(ps, s, uppercase)
char *ps;
char *s;
int uppercase;
{
register int c;
register int sc;
register int len = 0;
for ( ; *s != '\0'; s++, ps++)
{
c = *ps;
if (uppercase)
{
if (len == 0 && SIMPLE_IS_LOWER(c))
return (-1);
if (SIMPLE_IS_UPPER(c))
c = SIMPLE_TO_LOWER(c);
}
sc = *s;
if (len > 0 && SIMPLE_IS_UPPER(sc))
sc = SIMPLE_TO_LOWER(sc);
if (c != sc)
break;
len++;
}
return (len);
}
/*
* Exit the program.
*/
public void
quit(status)
int status;
{
static int save_status;
/*
* Put cursor at bottom left corner, clear the line,
* reset the terminal modes, and exit.
*/
if (status < 0)
status = save_status;
else
save_status = status;
quitting = 1;
edit((char*)NULL);
if (any_display && is_tty)
clear_bot();
deinit();
flush();
raw_mode(0);
#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
/*
* If we don't close 2, we get some garbage from
* 2's buffer when it flushes automatically.
* I cannot track this one down RB
* The same bug shows up if we use ^C^C to abort.
*/
close(2);
#endif
close_getchr();
exit(status);
}

258
contrib/less/mark.c Normal file
View File

@ -0,0 +1,258 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
#include "less.h"
extern IFILE curr_ifile;
extern int sc_height;
extern int jump_sline;
/*
* A mark is an ifile (input file) plus a position within the file.
*/
struct mark {
IFILE m_ifile;
struct scrpos m_scrpos;
};
/*
* The table of marks.
* Each mark is identified by a lowercase or uppercase letter.
* The final one is lmark, for the "last mark"; addressed by the apostrophe.
*/
#define NMARKS ((2*26)+1) /* a-z, A-Z, lastmark */
#define LASTMARK (NMARKS-1)
static struct mark marks[NMARKS];
/*
* Initialize the mark table to show no marks are set.
*/
public void
init_mark()
{
int i;
for (i = 0; i < NMARKS; i++)
marks[i].m_scrpos.pos = NULL_POSITION;
}
/*
* See if a mark letter is valid (between a and z).
*/
static struct mark *
getumark(c)
int c;
{
if (c >= 'a' && c <= 'z')
return (&marks[c-'a']);
if (c >= 'A' && c <= 'Z')
return (&marks[c-'A'+26]);
error("Invalid mark letter", NULL_PARG);
return (NULL);
}
/*
* Get the mark structure identified by a character.
* The mark struct may come either from the mark table
* or may be constructed on the fly for certain characters like ^, $.
*/
static struct mark *
getmark(c)
int c;
{
register struct mark *m;
static struct mark sm;
switch (c)
{
case '^':
/*
* Beginning of the current file.
*/
m = &sm;
m->m_scrpos.pos = ch_zero();
m->m_scrpos.ln = 0;
m->m_ifile = curr_ifile;
break;
case '$':
/*
* End of the current file.
*/
if (ch_end_seek())
{
error("Cannot seek to end of file", NULL_PARG);
return (NULL);
}
m = &sm;
m->m_scrpos.pos = ch_tell();
m->m_scrpos.ln = sc_height-1;
m->m_ifile = curr_ifile;
break;
case '.':
/*
* Current position in the current file.
*/
m = &sm;
get_scrpos(&m->m_scrpos);
m->m_ifile = curr_ifile;
break;
case '\'':
/*
* The "last mark".
*/
m = &marks[LASTMARK];
break;
default:
/*
* Must be a user-defined mark.
*/
m = getumark(c);
if (m == NULL)
break;
if (m->m_scrpos.pos == NULL_POSITION)
{
error("Mark not set", NULL_PARG);
return (NULL);
}
break;
}
return (m);
}
/*
* Is a mark letter is invalid?
*/
public int
badmark(c)
int c;
{
return (getmark(c) == NULL);
}
/*
* Set a user-defined mark.
*/
public void
setmark(c)
int c;
{
register struct mark *m;
struct scrpos scrpos;
m = getumark(c);
if (m == NULL)
return;
get_scrpos(&scrpos);
m->m_scrpos = scrpos;
m->m_ifile = curr_ifile;
}
/*
* Set lmark (the mark named by the apostrophe).
*/
public void
lastmark()
{
struct scrpos scrpos;
if (ch_getflags() & CH_HELPFILE)
return;
get_scrpos(&scrpos);
if (scrpos.pos == NULL_POSITION)
return;
marks[LASTMARK].m_scrpos = scrpos;
marks[LASTMARK].m_ifile = curr_ifile;
}
/*
* Go to a mark.
*/
public void
gomark(c)
int c;
{
register struct mark *m;
struct scrpos scrpos;
m = getmark(c);
if (m == NULL)
return;
/*
* If we're trying to go to the lastmark and
* it has not been set to anything yet,
* set it to the beginning of the current file.
*/
if (m == &marks[LASTMARK] && m->m_scrpos.pos == NULL_POSITION)
{
m->m_ifile = curr_ifile;
m->m_scrpos.pos = ch_zero();
m->m_scrpos.ln = jump_sline;
}
/*
* If we're using lmark, we must save the screen position now,
* because if we call edit_ifile() below, lmark will change.
* (We save the screen position even if we're not using lmark.)
*/
scrpos = m->m_scrpos;
if (m->m_ifile != curr_ifile)
{
/*
* Not in the current file; edit the correct file.
*/
if (edit_ifile(m->m_ifile))
return;
}
jump_loc(scrpos.pos, scrpos.ln);
}
/*
* Return the position associated with a given mark letter.
*
* We don't return which screen line the position
* is associated with, but this doesn't matter much,
* because it's always the first non-blank line on the screen.
*/
public POSITION
markpos(c)
int c;
{
register struct mark *m;
m = getmark(c);
if (m == NULL)
return (NULL_POSITION);
if (m->m_ifile != curr_ifile)
{
error("Mark not in current file", NULL_PARG);
return (NULL_POSITION);
}
return (m->m_scrpos.pos);
}
/*
* Clear the marks associated with a specified ifile.
*/
public void
unmark(ifile)
IFILE ifile;
{
int i;
for (i = 0; i < NMARKS; i++)
if (marks[i].m_ifile == ifile)
marks[i].m_scrpos.pos = NULL_POSITION;
}

9
contrib/less/mkfuncs.awk Normal file
View File

@ -0,0 +1,9 @@
BEGIN { FS="("; state = 0 }
/^ public/ { ftype = $0; state = 1 }
{ if (state == 1)
state = 2
else if (state == 2)
{ print ftype,$1,"();"; state = 0 }
}

69
contrib/less/mkhelp.c Normal file
View File

@ -0,0 +1,69 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Silly little program to generate the help.c source file
* from the less.hlp text file.
* help.c just contains a char array whose contents are
* the contents of less.hlp.
*/
#include <stdio.h>
int
main(argc, argv)
int argc;
char *argv[];
{
int ch;
int prevch;
printf("/* This file was generated by mkhelp from less.hlp */\n");
printf("#include \"less.h\"\n");
printf("constant char helpdata[] = {\n");
ch = 0;
while (prevch = ch, (ch = getchar()) != EOF)
{
switch (ch)
{
case '\'':
printf("'\\'',");
break;
case '\\':
printf("'\\\\',");
break;
case '\b':
printf("'\\b',");
break;
case '\t':
printf("'\\t',");
break;
case '\n':
if (prevch != '\r')
printf("'\\n',\n");
break;
case '\r':
if (prevch != '\n')
printf("'\\n',\n");
break;
default:
if (ch >= ' ' && ch < 0x7f)
printf("'%c',", ch);
else
printf("0x%02x,", ch);
break;
}
}
/* Add an extra null char to avoid having a trailing comma. */
printf(" 0 };\n");
printf("constant int size_helpdata = sizeof(helpdata) - 1;\n");
return (0);
}

32
contrib/less/mkinstalldirs Executable file
View File

@ -0,0 +1,32 @@
#!/bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Last modified: 1994-03-25
# Public domain
errstatus=0
for file in ${1+"$@"} ; do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d in ${1+"$@"} ; do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp" 1>&2
mkdir "$pathcomp" || errstatus=$?
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# mkinstalldirs ends here

530
contrib/less/optfunc.c Normal file
View File

@ -0,0 +1,530 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Handling functions for command line options.
*
* Most options are handled by the generic code in option.c.
* But all string options, and a few non-string options, require
* special handling specific to the particular option.
* This special processing is done by the "handling functions" in this file.
*
* Each handling function is passed a "type" and, if it is a string
* option, the string which should be "assigned" to the option.
* The type may be one of:
* INIT The option is being initialized from the command line.
* TOGGLE The option is being changed from within the program.
* QUERY The setting of the option is merely being queried.
*/
#include "less.h"
#include "option.h"
extern int nbufs;
extern int cbufs;
extern int pr_type;
extern int plusoption;
extern int swindow;
extern int sc_height;
extern int secure;
extern int dohelp;
extern int any_display;
extern char openquote;
extern char closequote;
extern char *prproto[];
extern char *eqproto;
extern char *hproto;
extern IFILE curr_ifile;
extern char version[];
#if LOGFILE
extern char *namelogfile;
extern int force_logfile;
extern int logfile;
#endif
#if TAGS
public char *tagoption = NULL;
extern char *tags;
extern int jump_sline;
#endif
#if MSDOS_COMPILER
extern int nm_fg_color, nm_bg_color;
extern int bo_fg_color, bo_bg_color;
extern int ul_fg_color, ul_bg_color;
extern int so_fg_color, so_bg_color;
extern int bl_fg_color, bl_bg_color;
#endif
#if LOGFILE
/*
* Handler for -o option.
*/
public void
opt_o(type, s)
int type;
char *s;
{
PARG parg;
if (secure)
{
error("log file support is not available", NULL_PARG);
return;
}
switch (type)
{
case INIT:
namelogfile = s;
break;
case TOGGLE:
if (ch_getflags() & CH_CANSEEK)
{
error("Input is not a pipe", NULL_PARG);
return;
}
if (logfile >= 0)
{
error("Log file is already in use", NULL_PARG);
return;
}
s = skipsp(s);
namelogfile = lglob(s);
use_logfile(namelogfile);
sync_logfile();
break;
case QUERY:
if (logfile < 0)
error("No log file", NULL_PARG);
else
{
parg.p_string = unquote_file(namelogfile);
error("Log file \"%s\"", &parg);
free(parg.p_string);
}
break;
}
}
/*
* Handler for -O option.
*/
public void
opt__O(type, s)
int type;
char *s;
{
force_logfile = TRUE;
opt_o(type, s);
}
#endif
/*
* Handlers for -l option.
*/
public void
opt_l(type, s)
int type;
char *s;
{
int err;
int n;
char *t;
switch (type)
{
case INIT:
t = s;
n = getnum(&t, 'l', &err);
if (err || n <= 0)
{
error("Line number is required after -l", NULL_PARG);
return;
}
plusoption = TRUE;
ungetsc(s);
break;
}
}
#if USERFILE
public void
opt_k(type, s)
int type;
char *s;
{
PARG parg;
switch (type)
{
case INIT:
if (lesskey(s, 0))
{
parg.p_string = unquote_file(s);
error("Cannot use lesskey file \"%s\"", &parg);
free(parg.p_string);
}
break;
}
}
#endif
#if TAGS
/*
* Handler for -t option.
*/
public void
opt_t(type, s)
int type;
char *s;
{
IFILE save_ifile;
POSITION pos;
switch (type)
{
case INIT:
tagoption = s;
/* Do the rest in main() */
break;
case TOGGLE:
if (secure)
{
error("tags support is not available", NULL_PARG);
break;
}
findtag(skipsp(s));
save_ifile = save_curr_ifile();
if (edit_tagfile())
break;
if ((pos = tagsearch()) == NULL_POSITION)
{
reedit_ifile(save_ifile);
break;
}
unsave_ifile(save_ifile);
jump_loc(pos, jump_sline);
break;
}
}
/*
* Handler for -T option.
*/
public void
opt__T(type, s)
int type;
char *s;
{
PARG parg;
switch (type)
{
case INIT:
tags = s;
break;
case TOGGLE:
s = skipsp(s);
tags = lglob(s);
break;
case QUERY:
parg.p_string = unquote_file(tags);
error("Tags file \"%s\"", &parg);
free(parg.p_string);
break;
}
}
#endif
/*
* Handler for -p option.
*/
public void
opt_p(type, s)
int type;
register char *s;
{
switch (type)
{
case INIT:
/*
* Unget a search command for the specified string.
* {{ This won't work if the "/" command is
* changed or invalidated by a .lesskey file. }}
*/
plusoption = TRUE;
ungetsc(s);
ungetsc("/");
break;
}
}
/*
* Handler for -P option.
*/
public void
opt__P(type, s)
int type;
register char *s;
{
register char **proto;
PARG parg;
switch (type)
{
case INIT:
case TOGGLE:
/*
* Figure out which prototype string should be changed.
*/
switch (*s)
{
case 's': proto = &prproto[PR_SHORT]; s++; break;
case 'm': proto = &prproto[PR_MEDIUM]; s++; break;
case 'M': proto = &prproto[PR_LONG]; s++; break;
case '=': proto = &eqproto; s++; break;
case 'h': proto = &hproto; s++; break;
default: proto = &prproto[PR_SHORT]; break;
}
free(*proto);
*proto = save(s);
break;
case QUERY:
parg.p_string = prproto[pr_type];
error("%s", &parg);
break;
}
}
/*
* Handler for the -b option.
*/
/*ARGSUSED*/
public void
opt_b(type, s)
int type;
char *s;
{
switch (type)
{
case TOGGLE:
case QUERY:
/*
* Allocate the new number of buffers.
*/
cbufs = ch_nbuf(cbufs);
break;
case INIT:
break;
}
}
/*
* Handler for the -i option.
*/
/*ARGSUSED*/
public void
opt_i(type, s)
int type;
char *s;
{
switch (type)
{
case TOGGLE:
chg_caseless();
break;
case QUERY:
case INIT:
break;
}
}
/*
* Handler for the -V option.
*/
/*ARGSUSED*/
public void
opt__V(type, s)
int type;
char *s;
{
switch (type)
{
case TOGGLE:
case QUERY:
dispversion();
break;
case INIT:
/*
* Force output to stdout per GNU standard for --version output.
*/
any_display = 1;
putstr("less ");
putstr(version);
putstr("\nCopyright (C) 2000 Mark Nudelman\n\n");
putstr("less comes with NO WARRANTY, to the extent permitted by law.\n");
putstr("For information about the terms of redistribution,\n");
putstr("see the file named README in the less distribution.\n");
quit(QUIT_OK);
break;
}
}
#if MSDOS_COMPILER
/*
* Parse an MSDOS color descriptor.
*/
static void
colordesc(s, fg_color, bg_color)
char *s;
int *fg_color;
int *bg_color;
{
int fg, bg;
int err;
fg = getnum(&s, 'D', &err);
if (err)
{
error("Missing fg color in -D", NULL_PARG);
return;
}
if (*s != '.')
bg = 0;
else
{
s++;
bg = getnum(&s, 'D', &err);
if (err)
{
error("Missing fg color in -D", NULL_PARG);
return;
}
}
if (*s != '\0')
error("Extra characters at end of -D option", NULL_PARG);
*fg_color = fg;
*bg_color = bg;
}
/*
* Handler for the -D option.
*/
/*ARGSUSED*/
public void
opt_D(type, s)
int type;
char *s;
{
switch (type)
{
case INIT:
case TOGGLE:
switch (*s++)
{
case 'n':
colordesc(s, &nm_fg_color, &nm_bg_color);
break;
case 'd':
colordesc(s, &bo_fg_color, &bo_bg_color);
break;
case 'u':
colordesc(s, &ul_fg_color, &ul_bg_color);
break;
case 'k':
colordesc(s, &bl_fg_color, &bl_bg_color);
break;
case 's':
colordesc(s, &so_fg_color, &so_bg_color);
break;
default:
error("-D must be followed by n, d, u, k or s", NULL_PARG);
break;
}
if (type == TOGGLE)
{
so_enter();
so_exit();
}
break;
case QUERY:
break;
}
}
#endif
/*
* Handler for the -" option.
*/
public void
opt_quote(type, s)
int type;
register char *s;
{
char buf[3];
PARG parg;
switch (type)
{
case INIT:
case TOGGLE:
if (s[1] != '\0' && s[2] != '\0')
{
error("-\" must be followed by 1 or 2 chars", NULL_PARG);
return;
}
openquote = s[0];
if (s[1] == '\0')
closequote = openquote;
else
closequote = s[1];
break;
case QUERY:
buf[0] = openquote;
buf[1] = closequote;
buf[2] = '\0';
parg.p_string = buf;
error("quotes %s", &parg);
break;
}
}
/*
* "-?" means display a help message.
* If from the command line, exit immediately.
*/
/*ARGSUSED*/
public void
opt_query(type, s)
int type;
char *s;
{
switch (type)
{
case QUERY:
case TOGGLE:
error("Use \"h\" for help", NULL_PARG);
break;
case INIT:
dohelp = 1;
}
}
/*
* Get the "screen window" size.
*/
public int
get_swindow()
{
if (swindow > 0)
return (swindow);
return (sc_height + swindow);
}

610
contrib/less/option.c Normal file
View File

@ -0,0 +1,610 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* 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, toggled via the "-" command,
* or queried via the "_" command.
*/
#include "less.h"
#include "option.h"
static struct option *pendopt;
public int plusoption = FALSE;
static char *propt();
static char *optstring();
static int flip_triple();
extern int screen_trashed;
extern char *every_first_cmd;
/*
* Scan an argument (either from the command line or from the
* LESS environment variable) and process it.
*/
public void
scan_option(s)
char *s;
{
register struct option *o;
register int optc;
char *optname;
char *printopt;
char *str;
int set_default;
int lc;
int err;
PARG parg;
if (s == NULL)
return;
/*
* If we have a pending option which requires an argument,
* handle it now.
* This happens if the previous option was, for example, "-P"
* without a following string. In that case, the current
* option is simply the argument for the previous option.
*/
if (pendopt != NULL)
{
switch (pendopt->otype & OTYPE)
{
case STRING:
(*pendopt->ofunc)(INIT, s);
break;
case NUMBER:
printopt = propt(pendopt->oletter);
*(pendopt->ovar) = getnum(&s, printopt, (int*)NULL);
break;
}
pendopt = NULL;
return;
}
set_default = FALSE;
optname = NULL;
while (*s != '\0')
{
/*
* Check some special cases first.
*/
switch (optc = *s++)
{
case ' ':
case '\t':
case END_OPTION_STRING:
continue;
case '-':
/*
* "--" indicates an option name instead of a letter.
*/
if (*s == '-')
{
optname = ++s;
break;
}
/*
* "-+" means set these options back to their defaults.
* (They may have been set otherwise by previous
* options.)
*/
set_default = (*s == '+');
if (set_default)
s++;
continue;
case '+':
/*
* An option prefixed by a "+" is ungotten, so
* that it is interpreted as less commands
* processed at the start of the first input file.
* "++" means process the commands at the start of
* EVERY input file.
*/
plusoption = TRUE;
if (*s == '+')
every_first_cmd = save(++s);
else
ungetsc(s);
s = optstring(s, propt('+'));
continue;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
/*
* Special "more" compatibility form "-<number>"
* instead of -z<number> to set the scrolling
* window size.
*/
s--;
optc = 'z';
break;
}
/*
* Not a special case.
* Look up the option letter in the option table.
*/
err = 0;
if (optname == NULL)
{
printopt = propt(optc);
lc = SIMPLE_IS_LOWER(optc);
o = findopt(optc);
} else
{
printopt = optname;
lc = SIMPLE_IS_LOWER(optname[0]);
o = findopt_name(&optname, NULL, &err);
s = optname;
optname = NULL;
if (*s == '\0' || *s == ' ')
{
/*
* The option name matches exactly.
*/
;
} else if (*s == '=')
{
/*
* The option name is followed by "=value".
*/
if (o != NULL &&
(o->otype & OTYPE) != STRING &&
(o->otype & OTYPE) != NUMBER)
{
parg.p_string = printopt;
error("The %s option should not be followed by =",
&parg);
quit(QUIT_ERROR);
}
s++;
} else
{
/*
* The specified name is longer than the
* real option name.
*/
o = NULL;
}
}
if (o == NULL)
{
parg.p_string = printopt;
if (err == OPT_AMBIG)
error("%s is an ambiguous abbreviation (\"less --help\" for help)",
&parg);
else
error("There is no %s option (\"less --help\" for help)",
&parg);
quit(QUIT_ERROR);
}
str = NULL;
switch (o->otype & OTYPE)
{
case BOOL:
if (set_default)
*(o->ovar) = o->odefault;
else
*(o->ovar) = ! o->odefault;
break;
case TRIPLE:
if (set_default)
*(o->ovar) = o->odefault;
else
*(o->ovar) = flip_triple(o->odefault, lc);
break;
case STRING:
if (*s == '\0')
{
/*
* Set pendopt and return.
* We will get the string next time
* scan_option is called.
*/
pendopt = o;
return;
}
/*
* Don't do anything here.
* All processing of STRING options is done by
* the handling function.
*/
str = s;
s = optstring(s, printopt);
break;
case NUMBER:
if (*s == '\0')
{
pendopt = o;
return;
}
*(o->ovar) = getnum(&s, printopt, (int*)NULL);
break;
}
/*
* If the option has a handling function, call it.
*/
if (o->ofunc != NULL)
(*o->ofunc)(INIT, str);
}
}
/*
* Toggle command line flags from within the program.
* Used by the "-" and "_" commands.
* how_toggle may be:
* OPT_NO_TOGGLE just report the current setting, without changing it.
* OPT_TOGGLE invert the current setting
* OPT_UNSET set to the default value
* OPT_SET set to the inverse of the default value
*/
public void
toggle_option(c, s, how_toggle)
int c;
char *s;
int how_toggle;
{
register struct option *o;
register int num;
int no_prompt;
int err;
PARG parg;
no_prompt = (how_toggle & OPT_NO_PROMPT);
how_toggle &= ~OPT_NO_PROMPT;
/*
* Look up the option letter in the option table.
*/
o = findopt(c);
if (o == NULL)
{
parg.p_string = propt(c);
error("There is no %s option", &parg);
return;
}
if (how_toggle == OPT_TOGGLE && (o->otype & NO_TOGGLE))
{
parg.p_string = propt(c);
error("Cannot change the %s option", &parg);
return;
}
if (how_toggle == OPT_NO_TOGGLE && (o->otype & NO_QUERY))
{
parg.p_string = propt(c);
error("Cannot query the %s option", &parg);
return;
}
/*
* Check for something which appears to be a do_toggle
* (because the "-" command was used), but really is not.
* This could be a string option with no string, or
* a number option with no number.
*/
switch (o->otype & OTYPE)
{
case STRING:
case NUMBER:
if (how_toggle == OPT_TOGGLE && *s == '\0')
how_toggle = OPT_NO_TOGGLE;
break;
}
#if HILITE_SEARCH
if (how_toggle != OPT_NO_TOGGLE && (o->otype & HL_REPAINT))
repaint_hilite(0);
#endif
/*
* Now actually toggle (change) the variable.
*/
if (how_toggle != OPT_NO_TOGGLE)
{
switch (o->otype & OTYPE)
{
case BOOL:
/*
* Boolean.
*/
switch (how_toggle)
{
case OPT_TOGGLE:
*(o->ovar) = ! *(o->ovar);
break;
case OPT_UNSET:
*(o->ovar) = o->odefault;
break;
case OPT_SET:
*(o->ovar) = ! o->odefault;
break;
}
break;
case TRIPLE:
/*
* Triple:
* If user gave the lower case letter, then switch
* to 1 unless already 1, in which case make it 0.
* If user gave the upper case letter, then switch
* to 2 unless already 2, in which case make it 0.
*/
switch (how_toggle)
{
case OPT_TOGGLE:
*(o->ovar) = flip_triple(*(o->ovar),
islower(c));
break;
case OPT_UNSET:
*(o->ovar) = o->odefault;
break;
case OPT_SET:
*(o->ovar) = flip_triple(o->odefault,
islower(c));
break;
}
break;
case STRING:
/*
* String: don't do anything here.
* The handling function will do everything.
*/
switch (how_toggle)
{
case OPT_SET:
case OPT_UNSET:
error("Cannot use \"-+\" or \"--\" for a string option",
NULL_PARG);
return;
}
break;
case NUMBER:
/*
* Number: set the variable to the given number.
*/
switch (how_toggle)
{
case OPT_TOGGLE:
num = getnum(&s, '\0', &err);
if (!err)
*(o->ovar) = num;
break;
case OPT_UNSET:
*(o->ovar) = o->odefault;
break;
case OPT_SET:
error("Can't use \"-!\" for a numeric option",
NULL_PARG);
return;
}
break;
}
}
/*
* Call the handling function for any special action
* specific to this option.
*/
if (o->ofunc != NULL)
(*o->ofunc)((how_toggle==OPT_NO_TOGGLE) ? QUERY : TOGGLE, s);
#if HILITE_SEARCH
if (how_toggle != OPT_NO_TOGGLE && (o->otype & HL_REPAINT))
chg_hilite();
#endif
if (!no_prompt)
{
/*
* Print a message describing the new setting.
*/
switch (o->otype & OTYPE)
{
case BOOL:
case TRIPLE:
/*
* Print the odesc message.
*/
error(o->odesc[*(o->ovar)], NULL_PARG);
break;
case NUMBER:
/*
* The message is in odesc[1] and has a %d for
* the value of the variable.
*/
parg.p_int = *(o->ovar);
error(o->odesc[1], &parg);
break;
case STRING:
/*
* Message was already printed by the handling function.
*/
break;
}
}
if (how_toggle != OPT_NO_TOGGLE && (o->otype & REPAINT))
screen_trashed = TRUE;
}
/*
* "Toggle" a triple-valued option.
*/
static int
flip_triple(val, lc)
int val;
int lc;
{
if (lc)
return ((val == OPT_ON) ? OPT_OFF : OPT_ON);
else
return ((val == OPT_ONPLUS) ? OPT_OFF : OPT_ONPLUS);
}
/*
* Return a string suitable for printing as the "name" of an option.
* For example, if the option letter is 'x', just return "-x".
*/
static char *
propt(c)
int c;
{
static char buf[8];
sprintf(buf, "-%s", prchar(c));
return (buf);
}
/*
* Determine if an option is a single character option (BOOL or TRIPLE),
* or if it a multi-character option (NUMBER).
*/
public int
single_char_option(c)
int c;
{
register struct option *o;
o = findopt(c);
if (o == NULL)
return (TRUE);
return ((o->otype & (BOOL|TRIPLE|NOVAR|NO_TOGGLE)) != 0);
}
/*
* Return the prompt to be used for a given option letter.
* Only string and number valued options have prompts.
*/
public char *
opt_prompt(c)
int c;
{
register struct option *o;
o = findopt(c);
if (o == NULL || (o->otype & (STRING|NUMBER)) == 0)
return (NULL);
return (o->odesc[0]);
}
/*
* Return whether or not there is a string option pending;
* that is, if the previous option was a string-valued option letter
* (like -P) without a following string.
* In that case, the current option is taken to be the string for
* the previous option.
*/
public int
isoptpending()
{
return (pendopt != NULL);
}
/*
* Print error message about missing string.
*/
static void
nostring(printopt)
char *printopt;
{
PARG parg;
parg.p_string = printopt;
error("Value is required after %s", &parg);
}
/*
* Print error message if a STRING type option is not followed by a string.
*/
public void
nopendopt()
{
nostring(propt(pendopt->oletter));
}
/*
* Scan to end of string or to an END_OPTION_STRING character.
* In the latter case, replace the char with a null char.
* Return a pointer to the remainder of the string, if any.
*/
static char *
optstring(s, printopt)
char *s;
char *printopt;
{
register char *p;
if (*s == '\0')
{
nostring(printopt);
quit(QUIT_ERROR);
}
for (p = s; *p != '\0'; p++)
if (*p == END_OPTION_STRING)
{
*p = '\0';
return (p+1);
}
return (p);
}
/*
* 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.
*/
public int
getnum(sp, printopt, errp)
char **sp;
char *printopt;
int *errp;
{
register char *s;
register int n;
register int neg;
PARG parg;
s = skipsp(*sp);
neg = FALSE;
if (*s == '-')
{
neg = TRUE;
s++;
}
if (*s < '0' || *s > '9')
{
if (errp != NULL)
{
*errp = TRUE;
return (-1);
}
parg.p_string = printopt;
error("Number is required after %s", &parg);
quit(QUIT_ERROR);
}
n = 0;
while (*s >= '0' && *s <= '9')
n = 10 * n + *s++ - '0';
*sp = s;
if (errp != NULL)
*errp = FALSE;
if (neg)
n = -n;
return (n);
}

62
contrib/less/option.h Normal file
View File

@ -0,0 +1,62 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
#define END_OPTION_STRING ('$')
/*
* 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 STRING 010 /* String-valued option */
#define NOVAR 020 /* No associated variable */
#define REPAINT 040 /* Repaint screen after toggling option */
#define NO_TOGGLE 0100 /* Option cannot be toggled with "-" cmd */
#define HL_REPAINT 0200 /* Repaint hilites after toggling option */
#define NO_QUERY 0400 /* Option cannot be queried with "_" cmd */
#define OTYPE (BOOL|TRIPLE|NUMBER|STRING|NOVAR)
/*
* Argument to a handling function tells what type of activity:
*/
#define INIT 0 /* Initialization (from command line) */
#define QUERY 1 /* Query (from _ or - command) */
#define TOGGLE 2 /* Change value (from - command) */
/* Flag to toggle_option to specify how to "toggle" */
#define OPT_NO_TOGGLE 0
#define OPT_TOGGLE 1
#define OPT_UNSET 2
#define OPT_SET 3
#define OPT_NO_PROMPT 0100
/* Error code from findopt_name */
#define OPT_AMBIG 1
struct optname
{
char *oname; /* Long (GNU-style) option name */
struct optname *onext; /* List of synonymous option names */
};
struct option
{
char oletter; /* The controlling letter (a-z) */
struct optname *onames; /* Long (GNU-style) option name */
int otype; /* Type of the option */
int odefault; /* Default value */
int *ovar; /* Pointer to the associated variable */
void (*ofunc)(); /* Pointer to special handling function */
char *odesc[3]; /* Description of each value */
};

436
contrib/less/opttbl.c Normal file
View File

@ -0,0 +1,436 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* The option table.
*/
#include "less.h"
#include "option.h"
/*
* Variables controlled by command line options.
*/
public int quiet; /* Should we suppress the audible bell? */
public int how_search; /* Where should forward searches start? */
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 quit_if_one_screen; /* Quit if EOF on first screen */
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 forw_scroll; /* Repaint screen on forward movement */
public int caseless; /* Do "caseless" searches */
public int linenums; /* Use line numbers */
public int cbufs; /* Current number of buffers */
public int autobuf; /* Automatically allocate buffers as needed */
public int ctldisp; /* Send control chars to screen untranslated */
public int force_open; /* Open the file even if not regular file */
public int swindow; /* Size of scrolling window */
public int jump_sline; /* Screen line of "jump target" */
public int chopline; /* Truncate displayed lines at screen width */
public int no_init; /* Disable sending ti/te termcap strings */
public int twiddle; /* Show tildes after EOF */
public int show_attn; /* Hilite first unread line */
#if HILITE_SEARCH
public int hilite_search; /* Highlight matched search patterns? */
#endif
/*
* Long option names.
*/
static struct optname a_optname = { "search-skip-screen", NULL };
static struct optname b_optname = { "buffers", NULL };
static struct optname B__optname = { "auto-buffers", NULL };
static struct optname c_optname = { "clear-screen", NULL };
static struct optname d_optname = { "dumb", NULL };
#if MSDOS_COMPILER
static struct optname D__optname = { "color", NULL };
#endif
static struct optname e_optname = { "quit-at-eof", NULL };
static struct optname f_optname = { "force", NULL };
static struct optname F__optname = { "quit-if-one-screen", NULL };
#if HILITE_SEARCH
static struct optname g_optname = { "hilite-search", NULL };
#endif
static struct optname h_optname = { "max-back-scroll", NULL };
static struct optname i_optname = { "ignore-case", NULL };
static struct optname j_optname = { "jump-target", NULL };
#if USERFILE
static struct optname k_optname = { "lesskey-file", NULL };
#endif
static struct optname m_optname = { "long-prompt", NULL };
static struct optname n_optname = { "line-numbers", NULL };
#if LOGFILE
static struct optname o_optname = { "log-file", NULL };
static struct optname O__optname = { "LOG-FILE", NULL };
#endif
static struct optname p_optname = { "pattern", NULL };
static struct optname P__optname = { "prompt", NULL };
static struct optname q2_optname = { "silent", NULL };
static struct optname q_optname = { "quiet", &q2_optname };
static struct optname r_optname = { "raw-control-chars", NULL };
static struct optname s_optname = { "squeeze-blank-lines", NULL };
static struct optname S__optname = { "chop-long-lines", NULL };
#if TAGS
static struct optname t_optname = { "tag", NULL };
static struct optname T__optname = { "tag-file", NULL };
#endif
static struct optname u_optname = { "underline-special", NULL };
static struct optname V__optname = { "version", NULL };
static struct optname w_optname = { "hilite-unread", NULL };
static struct optname x_optname = { "tabs", NULL };
static struct optname X__optname = { "no-init", NULL };
static struct optname y_optname = { "max-forw-scroll", NULL };
static struct optname z_optname = { "window", NULL };
static struct optname quote_optname = { "quotes", NULL };
static struct optname tilde_optname = { "tilde", NULL };
static struct optname query_optname = { "help", NULL };
/*
* Table of all options and their semantics.
*/
static struct option option[] =
{
{ 'a', &a_optname,
BOOL, OPT_OFF, &how_search, NULL,
"Search includes displayed screen",
"Search skips displayed screen",
NULL
},
{ 'b', &b_optname,
NUMBER, 10, &cbufs, opt_b,
"Buffers: ",
"%d buffers",
NULL
},
{ 'B', &B__optname,
BOOL, OPT_ON, &autobuf, NULL,
"Don't automatically allocate buffers",
"Automatically allocate buffers when needed",
NULL
},
{ 'c', &c_optname,
TRIPLE, OPT_OFF, &top_scroll, NULL,
"Repaint by scrolling from bottom of screen",
"Repaint by clearing each line",
"Repaint by painting from top of screen"
},
{ 'd', &d_optname,
BOOL|NO_TOGGLE, OPT_OFF, &know_dumb, NULL,
"Assume intelligent terminal",
"Assume dumb terminal",
NULL
},
#if MSDOS_COMPILER
{ 'D', &D__optname,
STRING|REPAINT|NO_QUERY, 0, NULL, opt_D,
"color desc: ", NULL, NULL
},
#endif
{ 'e', &e_optname,
TRIPLE, OPT_OFF, &quit_at_eof, NULL,
"Don't quit at end-of-file",
"Quit at end-of-file",
"Quit immediately at end-of-file"
},
{ 'f', &f_optname,
BOOL, OPT_OFF, &force_open, NULL,
"Open only regular files",
"Open even non-regular files",
NULL
},
{ 'F', &F__optname,
BOOL, OPT_OFF, &quit_if_one_screen, NULL,
"Don't quit if end-of-file on first screen",
"Quit if end-of-file on first screen",
NULL
},
#if HILITE_SEARCH
{ 'g', &g_optname,
TRIPLE|HL_REPAINT, OPT_ONPLUS, &hilite_search, NULL,
"Don't highlight search matches",
"Highlight matches for previous search only",
"Highlight all matches for previous search pattern",
},
#endif
{ 'h', &h_optname,
NUMBER, -1, &back_scroll, NULL,
"Backwards scroll limit: ",
"Backwards scroll limit is %d lines",
NULL
},
{ 'i', &i_optname,
TRIPLE|HL_REPAINT, OPT_OFF, &caseless, opt_i,
"Case is significant in searches",
"Ignore case in searches",
"Ignore case in searches and in patterns"
},
{ 'j', &j_optname,
NUMBER, 1, &jump_sline, NULL,
"Target line: ",
"Position target at screen line %d",
NULL
},
#if USERFILE
{ 'k', &k_optname,
STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_k,
NULL, NULL, NULL
},
#endif
{ 'l', NULL,
STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_l,
NULL, NULL, NULL
},
{ 'm', &m_optname,
TRIPLE, OPT_OFF, &pr_type, NULL,
"Short prompt",
"Medium prompt",
"Long prompt"
},
{ 'n', &n_optname,
TRIPLE|REPAINT, OPT_ON, &linenums, NULL,
"Don't use line numbers",
"Use line numbers",
"Constantly display line numbers"
},
#if LOGFILE
{ 'o', &o_optname,
STRING, 0, NULL, opt_o,
"log file: ", NULL, NULL
},
{ 'O', &O__optname,
STRING, 0, NULL, opt__O,
"Log file: ", NULL, NULL
},
#endif
{ 'p', &p_optname,
STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_p,
NULL, NULL, NULL
},
{ 'P', &P__optname,
STRING, 0, NULL, opt__P,
"prompt: ", NULL, NULL
},
{ 'q', &q_optname,
TRIPLE, OPT_OFF, &quiet, NULL,
"Ring the bell for errors AND at eof/bof",
"Ring the bell for errors but not at eof/bof",
"Never ring the bell"
},
{ 'r', &r_optname,
TRIPLE|REPAINT, OPT_OFF, &ctldisp, NULL,
"Display control characters as ^X",
"Display control characters directly",
"Display control characters directly, processing ANSI sequences"
},
{ 's', &s_optname,
BOOL|REPAINT, OPT_OFF, &squeeze, NULL,
"Display all blank lines",
"Squeeze multiple blank lines",
NULL
},
{ 'S', &S__optname,
BOOL|REPAINT, OPT_OFF, &chopline, NULL,
"Fold long lines",
"Chop long lines",
NULL
},
#if TAGS
{ 't', &t_optname,
STRING|NO_QUERY, 0, NULL, opt_t,
"tag: ", NULL, NULL
},
{ 'T', &T__optname,
STRING, 0, NULL, opt__T,
"tags file: ", NULL, NULL
},
#endif
{ 'u', &u_optname,
TRIPLE|REPAINT, OPT_OFF, &bs_mode, NULL,
"Display underlined text in underline mode",
"Backspaces cause overstrike",
"Print backspace as ^H"
},
{ 'V', &V__optname,
NOVAR, 0, NULL, opt__V,
NULL, NULL, NULL
},
{ 'w', &w_optname,
TRIPLE|REPAINT, OPT_OFF, &show_attn, NULL,
"Don't highlight first unread line",
"Highlight first unread line after forward-screen",
"Highlight first unread line after any forward movement",
},
{ 'x', &x_optname,
NUMBER|REPAINT, 8, &tabstop, NULL,
"Tab stops: ",
"Tab stops every %d spaces",
NULL
},
{ 'X', &X__optname,
BOOL|NO_TOGGLE, OPT_OFF, &no_init, NULL,
"Send init/deinit strings to terminal",
"Don't use init/deinit strings",
NULL
},
{ 'y', &y_optname,
NUMBER, -1, &forw_scroll, NULL,
"Forward scroll limit: ",
"Forward scroll limit is %d lines",
NULL
},
{ 'z', &z_optname,
NUMBER, -1, &swindow, NULL,
"Scroll window size: ",
"Scroll window size is %d lines",
NULL
},
{ '"', &quote_optname,
STRING, 0, NULL, opt_quote,
"quotes: ", NULL, NULL
},
{ '~', &tilde_optname,
BOOL|REPAINT, OPT_ON, &twiddle, NULL,
"Don't show tildes after end of file",
"Show tildes after end of file",
NULL
},
{ '?', &query_optname,
NOVAR, 0, NULL, opt_query,
NULL, NULL, NULL
},
{ '\0', NULL, NOVAR, 0, NULL, NULL, NULL, NULL, NULL }
};
/*
* Initialize each option to its default value.
*/
public void
init_option()
{
register struct option *o;
for (o = option; o->oletter != '\0'; o++)
{
/*
* Set each variable to its default.
*/
if (o->ovar != NULL)
*(o->ovar) = o->odefault;
}
}
/*
* Find an option in the option table, given its option letter.
*/
public struct option *
findopt(c)
int c;
{
register struct option *o;
for (o = option; o->oletter != '\0'; o++)
{
if (o->oletter == c)
return (o);
if ((o->otype & TRIPLE) && toupper(o->oletter) == c)
return (o);
}
return (NULL);
}
/*
* Find an option in the option table, given its option name.
* p_optname is the (possibly partial) name to look for, and
* is updated to point after the matched name.
* p_oname if non-NULL is set to point to the full option name.
*/
public struct option *
findopt_name(p_optname, p_oname, p_err)
char **p_optname;
char **p_oname;
int *p_err;
{
char *optname = *p_optname;
register struct option *o;
register struct optname *oname;
register int len;
int uppercase;
struct option *maxo = NULL;
struct optname *maxoname = NULL;
int maxlen = 0;
int ambig = 0;
int exact = 0;
/*
* Check all options.
*/
for (o = option; o->oletter != '\0'; o++)
{
/*
* Check all names for this option.
*/
for (oname = o->onames; oname != NULL; oname = oname->onext)
{
/*
* Try normal match first (uppercase == 0),
* then, then if it's a TRIPLE option,
* try uppercase match (uppercase == 1).
*/
for (uppercase = 0; uppercase <= 1; uppercase++)
{
len = sprefix(optname, oname->oname, uppercase);
if (!exact && len == maxlen)
/*
* Already had a partial match,
* and now there's another one that
* matches the same length.
*/
ambig = 1;
else if (len > maxlen)
{
/*
* Found a better match than
* the one we had.
*/
maxo = o;
maxoname = oname;
maxlen = len;
ambig = 0;
exact = (len == strlen(oname->oname));
}
if (!(o->otype & TRIPLE))
break;
}
}
}
if (ambig)
{
/*
* Name matched more than one option.
*/
if (p_err != NULL)
*p_err = OPT_AMBIG;
return (NULL);
}
*p_optname = optname + maxlen;
if (p_oname != NULL)
*p_oname = maxoname->oname;
return (maxo);
}

312
contrib/less/os.c Normal file
View File

@ -0,0 +1,312 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Operating system dependent routines.
*
* Most of the stuff in here is based on Unix, but an attempt
* has been made to make things work on other operating systems.
* This will sometimes result in a loss of functionality, unless
* someone rewrites code specifically for the new operating system.
*
* The makefile provides defines to decide whether various
* Unix features are present.
*/
#include "less.h"
#include <signal.h>
#include <setjmp.h>
#if HAVE_TIME_H
#include <time.h>
#endif
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#if HAVE_VALUES_H
#include <values.h>
#endif
#if HAVE_LIMITS_H
#include <limits.h>
#endif
#if HAVE_TIME_T
#define time_type time_t
#else
#define time_type long
#endif
/*
* BSD setjmp() saves (and longjmp() restores) the signal mask.
* This costs a system call or two per setjmp(), so if possible we clear the
* signal mask with sigsetmask(), and use _setjmp()/_longjmp() instead.
* On other systems, setjmp() doesn't affect the signal mask and so
* _setjmp() does not exist; we just use setjmp().
*/
#if HAVE__SETJMP && HAVE_SIGSETMASK
#define SET_JUMP _setjmp
#define LONG_JUMP _longjmp
#else
#define SET_JUMP setjmp
#define LONG_JUMP longjmp
#endif
public int reading;
static jmp_buf read_label;
extern int sigs;
/*
* Like read() system call, but is deliberately interruptible.
* A call to intread() from a signal handler will interrupt
* any pending iread().
*/
public int
iread(fd, buf, len)
int fd;
char *buf;
unsigned int len;
{
register int n;
#if MSDOS_COMPILER==WIN32C
if (ABORT_SIGS())
return (READ_INTR);
#else
#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
if (kbhit())
{
int c;
c = getch();
if (c == '\003')
return (READ_INTR);
ungetch(c);
}
#endif
#endif
if (SET_JUMP(read_label))
{
/*
* We jumped here from intread.
*/
reading = 0;
#if HAVE_SIGSETMASK
sigsetmask(0);
#else
#ifdef _OSK
sigmask(~0);
#endif
#endif
return (READ_INTR);
}
flush();
reading = 1;
#if MSDOS_COMPILER==DJGPPC
if (isatty(fd))
{
/*
* Don't try reading from a TTY until a character is
* available, because that makes some background programs
* believe DOS is busy in a way that prevents those
* programs from working while "less" waits.
*/
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
if (select(fd+1, &readfds, 0, 0, 0) == -1)
return (-1);
}
#endif
n = read(fd, buf, len);
#if 1
/*
* This is a kludge to workaround a problem on some systems
* where terminating a remote tty connection causes read() to
* start returning 0 forever, instead of -1.
*/
{
extern int ignore_eoi;
if (!ignore_eoi)
{
static int consecutive_nulls = 0;
if (n == 0)
consecutive_nulls++;
else
consecutive_nulls = 0;
if (consecutive_nulls > 20)
quit(QUIT_ERROR);
}
}
#endif
reading = 0;
if (n < 0)
return (-1);
return (n);
}
/*
* Interrupt a pending iread().
*/
public void
intread()
{
LONG_JUMP(read_label, 1);
}
/*
* Return the current time.
*/
#if HAVE_TIME
public long
get_time()
{
time_type t;
time(&t);
return (t);
}
#endif
#if !HAVE_STRERROR
/*
* Local version of strerror, if not available from the system.
*/
static char *
strerror(err)
int err;
{
#if HAVE_SYS_ERRLIST
static char buf[16];
extern char *sys_errlist[];
extern int sys_nerr;
if (err < sys_nerr)
return sys_errlist[err];
sprintf(buf, "Error %d", err);
return buf;
#else
return ("cannot open");
#endif
}
#endif
/*
* errno_message: Return an error message based on the value of "errno".
*/
public char *
errno_message(filename)
char *filename;
{
register char *p;
register char *m;
#if HAVE_ERRNO
#if MUST_DEFINE_ERRNO
extern int errno;
#endif
p = strerror(errno);
#else
p = "cannot open";
#endif
m = (char *) ecalloc(strlen(filename) + strlen(p) + 3, sizeof(char));
sprintf(m, "%s: %s", filename, p);
return (m);
}
/*
* Return the largest possible number that can fit in a long.
*/
static long
get_maxlong()
{
#ifdef LONG_MAX
return (LONG_MAX);
#else
#ifdef MAXLONG
return (MAXLONG);
#else
long n, n2;
/*
* Keep doubling n until we overflow.
* {{ This actually only returns the largest power of two that
* can fit in a long, but percentage() doesn't really need
* it any more accurate than that. }}
*/
n2 = 128; /* Hopefully no maxlong is less than 128! */
do {
n = n2;
n2 *= 2;
} while (n2 / 2 == n);
return (n);
#endif
#endif
}
/*
* Return the ratio of two POSITIONS, as a percentage.
* {{ Assumes a POSITION is a long int. }}
*/
public int
percentage(num, den)
POSITION num, den;
{
if (num <= get_maxlong() / 100)
return ((100 * num) / den);
else
return (num / (den / 100));
}
/*
* Return the specified percentage of a POSITION.
* {{ Assumes a POSITION is a long int. }}
*/
public POSITION
percent_pos(pos, percent)
POSITION pos;
int percent;
{
if (pos <= get_maxlong() / 100)
return ((percent * pos) / 100);
else
return (percent * (pos / 100));
}
#ifdef _OSK_MWC32
/*
* This implements an ANSI-style intercept setup for Microware C 3.2
*/
public int
os9_signal(type, handler)
int type;
RETSIGTYPE (*handler)();
{
intercept(handler);
}
#include <sgstat.h>
public int
isatty(f)
int f;
{
struct sgbuf sgbuf;
if (_gs_opt(f, &sgbuf) < 0)
return -1;
return (sgbuf.sg_class == 0);
}
#endif

461
contrib/less/output.c Normal file
View File

@ -0,0 +1,461 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* High level routines dealing with the output to the screen.
*/
#include "less.h"
#if MSDOS_COMPILER==WIN32C
#include "windows.h"
#endif
public int errmsgs; /* Count of messages displayed by error() */
public int need_clr;
public int final_attr;
extern int sigs;
extern int sc_width;
extern int so_s_width, so_e_width;
extern int screen_trashed;
extern int any_display;
extern int is_tty;
/*
* Display the line which is in the line buffer.
*/
public void
put_line()
{
register int c;
register int i;
int a;
int curr_attr;
if (ABORT_SIGS())
{
/*
* Don't output if a signal is pending.
*/
screen_trashed = 1;
return;
}
curr_attr = AT_NORMAL;
for (i = 0; (c = gline(i, &a)) != '\0'; i++)
{
if (a != curr_attr)
{
/*
* Changing attributes.
* Display the exit sequence for the old attribute
* and the enter sequence for the new one.
*/
switch (curr_attr)
{
case AT_UNDERLINE: ul_exit(); break;
case AT_BOLD: bo_exit(); break;
case AT_BLINK: bl_exit(); break;
case AT_STANDOUT: so_exit(); break;
}
switch (a)
{
case AT_UNDERLINE: ul_enter(); break;
case AT_BOLD: bo_enter(); break;
case AT_BLINK: bl_enter(); break;
case AT_STANDOUT: so_enter(); break;
}
curr_attr = a;
}
if (curr_attr == AT_INVIS)
continue;
if (c == '\b')
putbs();
else
putchr(c);
}
switch (curr_attr)
{
case AT_UNDERLINE: ul_exit(); break;
case AT_BOLD: bo_exit(); break;
case AT_BLINK: bl_exit(); break;
case AT_STANDOUT: so_exit(); break;
}
final_attr = curr_attr;
}
static char obuf[OUTBUF_SIZE];
static char *ob = obuf;
/*
* Flush buffered output.
*
* If we haven't displayed any file data yet,
* output messages on error output (file descriptor 2),
* otherwise output on standard output (file descriptor 1).
*
* This has the desirable effect of producing all
* error messages on error output if standard output
* is directed to a file. It also does the same if
* we never produce any real output; for example, if
* the input file(s) cannot be opened. If we do
* eventually produce output, code in edit() makes
* sure these messages can be seen before they are
* overwritten or scrolled away.
*/
public void
flush()
{
register int n;
register int fd;
n = ob - obuf;
if (n == 0)
return;
#if MSDOS_COMPILER==WIN32C
if (is_tty && any_display)
{
char *p;
char *op;
DWORD nwritten = 0;
CONSOLE_SCREEN_BUFFER_INFO scr;
DWORD nchars;
COORD cpos;
WORD nm_attr;
int olen;
extern HANDLE con_out;
extern int nm_fg_color;
extern int nm_bg_color;
#define MAKEATTR(fg,bg) ((WORD)((fg)|((bg)<<4)))
*ob = '\0';
olen = ob - obuf;
/*
* To avoid color problems, if we're scrolling the screen,
* we write only up to the char that causes the scroll,
* (a newline or a char in the last column), then fill
* the bottom line with the "normal" attribute, then
* write the rest.
* When Windows scrolls, it takes the attributes for the
* new line from the first char of the (previously)
* bottom line.
*
* {{ This still doesn't work correctly in all cases! }}
*/
nm_attr = MAKEATTR(nm_fg_color, nm_bg_color);
for (op = obuf; *op != '\0'; )
{
GetConsoleScreenBufferInfo(con_out, &scr);
/* Find the next newline. */
p = strchr(op, '\n');
if (p == NULL &&
scr.dwCursorPosition.X + olen >= sc_width)
{
/*
* No newline, but writing in the
* last column causes scrolling.
*/
p = op + sc_width - scr.dwCursorPosition.X - 1;
}
if (scr.dwCursorPosition.Y != scr.srWindow.Bottom ||
p == NULL)
{
/* Write the entire buffer. */
WriteConsole(con_out, op, olen,
&nwritten, NULL);
op += olen;
} else
{
/* Write only up to the scrolling char. */
WriteConsole(con_out, op, p - op + 1,
&nwritten, NULL);
cpos.X = 0;
cpos.Y = scr.dwCursorPosition.Y;
FillConsoleOutputAttribute(con_out, nm_attr,
sc_width, cpos, &nchars);
olen -= p - op + 1;
op = p + 1;
}
}
ob = obuf;
return;
}
#else
#if MSDOS_COMPILER==MSOFTC
if (is_tty && any_display)
{
*ob = '\0';
_outtext(obuf);
ob = obuf;
return;
}
#else
#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
if (is_tty && any_display)
{
*ob = '\0';
cputs(obuf);
ob = obuf;
return;
}
#endif
#endif
#endif
fd = (any_display) ? 1 : 2;
if (write(fd, obuf, n) != n)
screen_trashed = 1;
ob = obuf;
}
/*
* Output a character.
*/
public int
putchr(c)
int c;
{
if (need_clr)
{
need_clr = 0;
clear_bot();
}
#if MSDOS_COMPILER
if (c == '\n' && is_tty)
{
/* remove_top(1); */
putchr('\r');
}
#else
#ifdef _OSK
if (c == '\n' && is_tty) /* In OS-9, '\n' == 0x0D */
putchr(0x0A);
#endif
#endif
/*
* Some versions of flush() write to *ob, so we must flush
* when we are still one char from the end of obuf.
*/
if (ob >= &obuf[sizeof(obuf)-1])
flush();
*ob++ = c;
return (c);
}
/*
* Output a string.
*/
public void
putstr(s)
register char *s;
{
while (*s != '\0')
putchr(*s++);
}
/*
* Output an integer in a given radix.
*/
static int
iprintnum(num, radix)
int num;
int radix;
{
register char *s;
int r;
int neg;
char buf[10];
neg = (num < 0);
if (neg)
num = -num;
s = buf;
do
{
*s++ = (num % radix) + '0';
} while ((num /= radix) != 0);
if (neg)
*s++ = '-';
r = s - buf;
while (s > buf)
putchr(*--s);
return (r);
}
/*
* This function implements printf-like functionality
* using a more portable argument list mechanism than printf's.
*/
static int
less_printf(fmt, parg)
register char *fmt;
PARG *parg;
{
register char *s;
register int n;
register int col;
col = 0;
while (*fmt != '\0')
{
if (*fmt != '%')
{
putchr(*fmt++);
col++;
} else
{
++fmt;
switch (*fmt++) {
case 's':
s = parg->p_string;
parg++;
while (*s != '\0')
{
putchr(*s++);
col++;
}
break;
case 'd':
n = parg->p_int;
parg++;
col += iprintnum(n, 10);
break;
}
}
}
return (col);
}
/*
* Get a RETURN.
* If some other non-trivial char is pressed, unget it, so it will
* become the next command.
*/
public void
get_return()
{
int c;
#if ONLY_RETURN
while ((c = getchr()) != '\n' && c != '\r')
bell();
#else
c = getchr();
if (c != '\n' && c != '\r' && c != ' ' && c != READ_INTR)
ungetcc(c);
#endif
}
/*
* Output a message in the lower left corner of the screen
* and wait for carriage return.
*/
public void
error(fmt, parg)
char *fmt;
PARG *parg;
{
int col = 0;
static char return_to_continue[] = " (press RETURN)";
errmsgs++;
if (any_display && is_tty)
{
clear_bot();
so_enter();
col += so_s_width;
}
col += less_printf(fmt, parg);
if (!(any_display && is_tty))
{
putchr('\n');
return;
}
putstr(return_to_continue);
so_exit();
col += sizeof(return_to_continue) + so_e_width;
get_return();
lower_left();
if (col >= sc_width)
/*
* Printing the message has probably scrolled the screen.
* {{ Unless the terminal doesn't have auto margins,
* in which case we just hammered on the right margin. }}
*/
screen_trashed = 1;
flush();
}
static char intr_to_abort[] = "... (interrupt to abort)";
/*
* Output a message in the lower left corner of the screen
* and don't wait for carriage return.
* Usually used to warn that we are beginning a potentially
* time-consuming operation.
*/
public void
ierror(fmt, parg)
char *fmt;
PARG *parg;
{
clear_bot();
so_enter();
(void) less_printf(fmt, parg);
putstr(intr_to_abort);
so_exit();
flush();
need_clr = 1;
}
/*
* Output a message in the lower left corner of the screen
* and return a single-character response.
*/
public int
query(fmt, parg)
char *fmt;
PARG *parg;
{
register int c;
int col = 0;
if (any_display && is_tty)
clear_bot();
(void) less_printf(fmt, parg);
c = getchr();
if (!(any_display && is_tty))
{
putchr('\n');
return (c);
}
lower_left();
if (col >= sc_width)
screen_trashed = 1;
flush();
return (c);
}

34
contrib/less/pckeys.h Normal file
View File

@ -0,0 +1,34 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Definitions of keys on the PC.
* Special (non-ASCII) keys on the PC send a two-byte sequence,
* where the first byte is 0 and the second is as defined below.
*/
#define PCK_SHIFT_TAB '\017'
#define PCK_ALT_E '\022'
#define PCK_CAPS_LOCK '\072'
#define PCK_F1 '\073'
#define PCK_NUM_LOCK '\105'
#define PCK_HOME '\107'
#define PCK_UP '\110'
#define PCK_PAGEUP '\111'
#define PCK_LEFT '\113'
#define PCK_RIGHT '\115'
#define PCK_END '\117'
#define PCK_DOWN '\120'
#define PCK_PAGEDOWN '\121'
#define PCK_INSERT '\122'
#define PCK_DELETE '\123'
#define PCK_CTL_LEFT '\163'
#define PCK_CTL_RIGHT '\164'
#define PCK_CTL_DELETE '\223'

232
contrib/less/position.c Normal file
View File

@ -0,0 +1,232 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Routines dealing with the "position" table.
* This is a table which tells the position (in the input file) of the
* first char on each currently displayed line.
*
* {{ The position table is scrolled by moving all the entries.
* Would be better to have a circular table
* and just change a couple of pointers. }}
*/
#include "less.h"
#include "position.h"
static POSITION *table = NULL; /* The position table */
static int table_size;
extern int sc_width, sc_height;
/*
* Return the starting file position of a line displayed on the screen.
* The line may be specified as a line number relative to the top
* of the screen, but is usually one of these special cases:
* the top (first) line on the screen
* the second line on the screen
* the bottom line on the screen
* the line after the bottom line on the screen
*/
public POSITION
position(where)
int where;
{
switch (where)
{
case BOTTOM:
where = sc_height - 2;
break;
case BOTTOM_PLUS_ONE:
where = sc_height - 1;
break;
case MIDDLE:
where = (sc_height - 1) / 2;
}
return (table[where]);
}
/*
* Add a new file position to the bottom of the position table.
*/
public void
add_forw_pos(pos)
POSITION pos;
{
register int i;
/*
* Scroll the position table up.
*/
for (i = 1; i < sc_height; i++)
table[i-1] = table[i];
table[sc_height - 1] = pos;
}
/*
* Add a new file position to the top of the position table.
*/
public void
add_back_pos(pos)
POSITION pos;
{
register int i;
/*
* Scroll the position table down.
*/
for (i = sc_height - 1; i > 0; i--)
table[i] = table[i-1];
table[0] = pos;
}
/*
* Initialize the position table, done whenever we clear the screen.
*/
public void
pos_clear()
{
register int i;
for (i = 0; i < sc_height; i++)
table[i] = NULL_POSITION;
}
/*
* Allocate or reallocate the position table.
*/
public void
pos_init()
{
struct scrpos scrpos;
if (sc_height <= table_size)
return;
/*
* If we already have a table, remember the first line in it
* before we free it, so we can copy that line to the new table.
*/
if (table != NULL)
{
get_scrpos(&scrpos);
free((char*)table);
} else
scrpos.pos = NULL_POSITION;
table = (POSITION *) ecalloc(sc_height, sizeof(POSITION));
table_size = sc_height;
pos_clear();
if (scrpos.pos != NULL_POSITION)
table[scrpos.ln-1] = scrpos.pos;
}
/*
* See if the byte at a specified position is currently on the screen.
* Check the position table to see if the position falls within its range.
* Return the position table entry if found, -1 if not.
*/
public int
onscreen(pos)
POSITION pos;
{
register int i;
if (pos < table[0])
return (-1);
for (i = 1; i < sc_height; i++)
if (pos < table[i])
return (i-1);
return (-1);
}
/*
* See if the entire screen is empty.
*/
public int
empty_screen()
{
return (empty_lines(0, sc_height-1));
}
public int
empty_lines(s, e)
int s;
int e;
{
register int i;
for (i = s; i <= e; i++)
if (table[i] != NULL_POSITION)
return (0);
return (1);
}
/*
* Get the current screen position.
* The screen position consists of both a file position and
* a screen line number where the file position is placed on the screen.
* Normally the screen line number is 0, but if we are positioned
* such that the top few lines are empty, we may have to set
* the screen line to a number > 0.
*/
public void
get_scrpos(scrpos)
struct scrpos *scrpos;
{
register int i;
/*
* Find the first line on the screen which has something on it,
* and return the screen line number and the file position.
*/
for (i = 0; i < sc_height; i++)
if (table[i] != NULL_POSITION)
{
scrpos->ln = i+1;
scrpos->pos = table[i];
return;
}
/*
* The screen is empty.
*/
scrpos->pos = NULL_POSITION;
}
/*
* Adjust a screen line number to be a simple positive integer
* in the range { 0 .. sc_height-2 }.
* (The bottom line, sc_height-1, is reserved for prompts, etc.)
* The given "sline" may be in the range { 1 .. sc_height-1 }
* to refer to lines relative to the top of the screen (starting from 1),
* or it may be in { -1 .. -(sc_height-1) } to refer to lines
* relative to the bottom of the screen.
*/
public int
adjsline(sline)
int sline;
{
/*
* Negative screen line number means
* relative to the bottom of the screen.
*/
if (sline < 0)
sline += sc_height;
/*
* Can't be less than 1 or greater than sc_height-1.
*/
if (sline <= 0)
sline = 1;
if (sline >= sc_height)
sline = sc_height - 1;
/*
* Return zero-based line number, not one-based.
*/
return (sline-1);
}

19
contrib/less/position.h Normal file
View File

@ -0,0 +1,19 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Include file for interfacing to position.c modules.
*/
#define TOP (0)
#define TOP_PLUS_ONE (1)
#define BOTTOM (-1)
#define BOTTOM_PLUS_ONE (-2)
#define MIDDLE (-3)

521
contrib/less/prompt.c Normal file
View File

@ -0,0 +1,521 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Prompting and other messages.
* There are three flavors of prompts, SHORT, MEDIUM and LONG,
* selected by the -m/-M options.
* There is also the "equals message", printed by the = command.
* A prompt is a message composed of various pieces, such as the
* name of the file being viewed, the percentage into the file, etc.
*/
#include "less.h"
#include "position.h"
extern int pr_type;
extern int hit_eof;
extern int new_file;
extern int sc_width;
extern int so_s_width, so_e_width;
extern int linenums;
extern int hshift;
extern int sc_height;
extern int jump_sline;
extern IFILE curr_ifile;
#if EDITOR
extern char *editor;
extern char *editproto;
#endif
/*
* Prototypes for the three flavors of prompts.
* These strings are expanded by pr_expand().
*/
static constant char s_proto[] =
"?n?f%f .?m(file %i of %m) ..?e(END) ?x- Next\\: %x..%t";
static constant char m_proto[] =
"?n?f%f .?m(file %i of %m) ..?e(END) ?x- Next\\: %x.:?pB%pB\\%:byte %bB?s/%s...%t";
static constant char M_proto[] =
"?f%f .?n?m(file %i of %m) ..?ltlines %lt-%lb?L/%L. :byte %bB?s/%s. .?e(END) ?x- Next\\: %x.:?pB%pB\\%..%t";
static constant char e_proto[] =
"?f%f .?m(file %i of %m) .?ltlines %lt-%lb?L/%L. .byte %bB?s/%s. ?e(END) :?pB%pB\\%..%t";
static constant char h_proto[] =
"HELP -- ?eEND -- Press g to see it again:Press RETURN for more., or q when done";
public char *prproto[3];
public char constant *eqproto = e_proto;
public char constant *hproto = h_proto;
static char message[PROMPT_SIZE];
static char *mp;
/*
* Initialize the prompt prototype strings.
*/
public void
init_prompt()
{
prproto[0] = save(s_proto);
prproto[1] = save(m_proto);
prproto[2] = save(M_proto);
eqproto = save(e_proto);
hproto = save(h_proto);
}
/*
* Append a string to the end of the message.
*/
static void
ap_str(s)
char *s;
{
int len;
len = strlen(s);
if (mp + len >= message + PROMPT_SIZE)
len = message + PROMPT_SIZE - mp - 1;
strncpy(mp, s, len);
mp += len;
*mp = '\0';
}
/*
* Append a character to the end of the message.
*/
static void
ap_char(c)
char c;
{
char buf[2];
buf[0] = c;
buf[1] = '\0';
ap_str(buf);
}
/*
* Append a POSITION (as a decimal integer) to the end of the message.
*/
static void
ap_pos(pos)
POSITION pos;
{
char buf[MAX_PRINT_POSITION];
sprintf(buf, PR_POSITION, pos);
ap_str(buf);
}
/*
* Append an integer to the end of the message.
*/
static void
ap_int(n)
int n;
{
char buf[MAX_PRINT_INT];
sprintf(buf, "%d", n);
ap_str(buf);
}
/*
* Append a question mark to the end of the message.
*/
static void
ap_quest()
{
ap_str("?");
}
/*
* Return the "current" byte offset in the file.
*/
static POSITION
curr_byte(where)
int where;
{
POSITION pos;
pos = position(where);
while (pos == NULL_POSITION && where >= 0 && where < sc_height)
pos = position(++where);
if (pos == NULL_POSITION)
pos = ch_length();
return (pos);
}
/*
* Return the value of a prototype conditional.
* A prototype string may include conditionals which consist of a
* question mark followed by a single letter.
* Here we decode that letter and return the appropriate boolean value.
*/
static int
cond(c, where)
char c;
int where;
{
POSITION len;
switch (c)
{
case 'a': /* Anything in the message yet? */
return (mp > message);
case 'b': /* Current byte offset known? */
return (curr_byte(where) != NULL_POSITION);
case 'c':
return (hshift != 0);
case 'e': /* At end of file? */
return (hit_eof);
case 'f': /* Filename known? */
return (strcmp(get_filename(curr_ifile), "-") != 0);
case 'l': /* Line number known? */
case 'd': /* Same as l */
return (linenums);
case 'L': /* Final line number known? */
case 'D': /* Same as L */
return (linenums && ch_length() != NULL_POSITION);
case 'm': /* More than one file? */
return (nifile() > 1);
case 'n': /* First prompt in a new file? */
return (new_file);
case 'p': /* Percent into file (bytes) known? */
return (curr_byte(where) != NULL_POSITION &&
ch_length() > 0);
case 'P': /* Percent into file (lines) known? */
return (currline(where) != 0 &&
(len = ch_length()) > 0 &&
find_linenum(len) != 0);
case 's': /* Size of file known? */
case 'B':
return (ch_length() != NULL_POSITION);
case 'x': /* Is there a "next" file? */
return (next_ifile(curr_ifile) != NULL_IFILE);
}
return (0);
}
/*
* Decode a "percent" prototype character.
* A prototype string may include various "percent" escapes;
* that is, a percent sign followed by a single letter.
* Here we decode that letter and take the appropriate action,
* usually by appending something to the message being built.
*/
static void
protochar(c, where, iseditproto)
int c;
int where;
int iseditproto;
{
POSITION pos;
POSITION len;
int n;
IFILE h;
char *s;
char *escs;
switch (c)
{
case 'b': /* Current byte offset */
pos = curr_byte(where);
if (pos != NULL_POSITION)
ap_pos(pos);
else
ap_quest();
break;
case 'c':
ap_int(hshift);
break;
case 'd': /* Current page number */
n = currline(where);
if (n > 0 && sc_height > 1)
ap_int(((n - 1) / (sc_height - 1)) + 1);
else
ap_quest();
break;
case 'D': /* Last page number */
len = ch_length();
if (len == NULL_POSITION || len == ch_zero() ||
(n = find_linenum(len)) <= 0)
ap_quest();
else
ap_int(((n - 1) / (sc_height - 1)) + 1);
break;
#if EDITOR
case 'E': /* Editor name */
ap_str(editor);
break;
#endif
case 'f': /* File name */
s = unquote_file(get_filename(curr_ifile));
/*
* If we are expanding editproto then we escape metachars.
* This allows us to run the editor on files with funny names.
*/
if (iseditproto && (escs = esc_metachars(s)) != NULL)
{
free(s);
s = escs;
}
ap_str(s);
free(s);
break;
case 'i': /* Index into list of files */
ap_int(get_index(curr_ifile));
break;
case 'l': /* Current line number */
n = currline(where);
if (n != 0)
ap_int(n);
else
ap_quest();
break;
case 'L': /* Final line number */
len = ch_length();
if (len == NULL_POSITION || len == ch_zero() ||
(n = find_linenum(len)) <= 0)
ap_quest();
else
ap_int(n-1);
break;
case 'm': /* Number of files */
ap_int(nifile());
break;
case 'p': /* Percent into file (bytes) */
pos = curr_byte(where);
len = ch_length();
if (pos != NULL_POSITION && len > 0)
ap_int(percentage(pos,len));
else
ap_quest();
break;
case 'P': /* Percent into file (lines) */
pos = (POSITION) currline(where);
if (pos == 0 ||
(len = ch_length()) == NULL_POSITION || len == ch_zero() ||
(n = find_linenum(len)) <= 0)
ap_quest();
else
ap_int(percentage(pos, (POSITION)n));
break;
case 's': /* Size of file */
case 'B':
len = ch_length();
if (len != NULL_POSITION)
ap_pos(len);
else
ap_quest();
break;
case 't': /* Truncate trailing spaces in the message */
while (mp > message && mp[-1] == ' ')
mp--;
break;
case 'x': /* Name of next file */
h = next_ifile(curr_ifile);
if (h != NULL_IFILE)
{
s = unquote_file(get_filename(h));
ap_str(s);
free(s);
} else
ap_quest();
break;
}
}
/*
* Skip a false conditional.
* When a false condition is found (either a false IF or the ELSE part
* of a true IF), this routine scans the prototype string to decide
* where to resume parsing the string.
* We must keep track of nested IFs and skip them properly.
*/
static char *
skipcond(p)
register char *p;
{
register int iflevel;
/*
* We came in here after processing a ? or :,
* so we start nested one level deep.
*/
iflevel = 1;
for (;;) switch (*++p)
{
case '?':
/*
* Start of a nested IF.
*/
iflevel++;
break;
case ':':
/*
* Else.
* If this matches the IF we came in here with,
* then we're done.
*/
if (iflevel == 1)
return (p);
break;
case '.':
/*
* Endif.
* If this matches the IF we came in here with,
* then we're done.
*/
if (--iflevel == 0)
return (p);
break;
case '\\':
/*
* Backslash escapes the next character.
*/
++p;
break;
case '\0':
/*
* Whoops. Hit end of string.
* This is a malformed conditional, but just treat it
* as if all active conditionals ends here.
*/
return (p-1);
}
/*NOTREACHED*/
}
/*
* Decode a char that represents a position on the screen.
*/
static char *
wherechar(p, wp)
char *p;
int *wp;
{
switch (*p)
{
case 'b': case 'd': case 'l': case 'p': case 'P':
switch (*++p)
{
case 't': *wp = TOP; break;
case 'm': *wp = MIDDLE; break;
case 'b': *wp = BOTTOM; break;
case 'B': *wp = BOTTOM_PLUS_ONE; break;
case 'j': *wp = adjsline(jump_sline); break;
default: *wp = TOP; p--; break;
}
}
return (p);
}
/*
* Construct a message based on a prototype string.
*/
public char *
pr_expand(proto, maxwidth)
char *proto;
int maxwidth;
{
register char *p;
register int c;
int where;
mp = message;
if (*proto == '\0')
return ("");
for (p = proto; *p != '\0'; p++)
{
switch (*p)
{
default: /* Just put the character in the message */
ap_char(*p);
break;
case '\\': /* Backslash escapes the next character */
p++;
ap_char(*p);
break;
case '?': /* Conditional (IF) */
if ((c = *++p) == '\0')
--p;
else
{
where = 0;
p = wherechar(p, &where);
if (!cond(c, where))
p = skipcond(p);
}
break;
case ':': /* ELSE */
p = skipcond(p);
break;
case '.': /* ENDIF */
break;
case '%': /* Percent escape */
if ((c = *++p) == '\0')
--p;
else
{
where = 0;
p = wherechar(p, &where);
protochar(c, where,
#if EDITOR
(proto == editproto));
#else
0);
#endif
}
break;
}
}
new_file = 0;
if (mp == message)
return (NULL);
if (maxwidth > 0 && mp >= message + maxwidth)
{
/*
* Message is too long.
* Return just the final portion of it.
*/
return (mp - maxwidth);
}
return (message);
}
/*
* Return a message suitable for printing by the "=" command.
*/
public char *
eq_message()
{
return (pr_expand(eqproto, 0));
}
/*
* Return a prompt.
* This depends on the prompt type (SHORT, MEDIUM, LONG), etc.
* If we can't come up with an appropriate prompt, return NULL
* and the caller will prompt with a colon.
*/
public char *
pr_string()
{
if (ch_getflags() & CH_HELPFILE)
return (pr_expand(hproto, sc_width-so_s_width-so_e_width-2));
return (pr_expand(prproto[pr_type], sc_width-so_s_width-so_e_width-2));
}

1250
contrib/less/regexp.c Normal file

File diff suppressed because it is too large Load Diff

34
contrib/less/regexp.h Normal file
View File

@ -0,0 +1,34 @@
/*
* Definitions etc. for regexp(3) routines.
*
* Caveat: this is V8 regexp(3) [actually, a reimplementation thereof],
* not the System V one.
*/
#ifndef _REGEXP
#define _REGEXP 1
#define NSUBEXP 10
typedef struct regexp {
char *startp[NSUBEXP];
char *endp[NSUBEXP];
char regstart; /* Internal use only. */
char reganch; /* Internal use only. */
char *regmust; /* Internal use only. */
int regmlen; /* Internal use only. */
char program[1]; /* Unwarranted chumminess with compiler. */
} regexp;
#if defined(__STDC__) || defined(__cplusplus)
# define _ANSI_ARGS_(x) x
#else
# define _ANSI_ARGS_(x) ()
#endif
extern regexp *regcomp _ANSI_ARGS_((char *exp));
extern int regexec _ANSI_ARGS_((regexp *prog, char *string));
extern int regexec2 _ANSI_ARGS_((regexp *prog, char *string, int notbol));
extern void regsub _ANSI_ARGS_((regexp *prog, char *source, char *dest));
extern void regerror _ANSI_ARGS_((char *msg));
#endif /* REGEXP */

2286
contrib/less/screen.c Normal file

File diff suppressed because it is too large Load Diff

1359
contrib/less/search.c Normal file

File diff suppressed because it is too large Load Diff

270
contrib/less/signal.c Normal file
View File

@ -0,0 +1,270 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Routines dealing with signals.
*
* A signal usually merely causes a bit to be set in the "signals" word.
* At some convenient time, the mainline code checks to see if any
* signals need processing by calling psignal().
* If we happen to be reading from a file [in iread()] at the time
* the signal is received, we call intread to interrupt the iread.
*/
#include "less.h"
#include <signal.h>
/*
* "sigs" contains bits indicating signals which need to be processed.
*/
public int sigs;
extern int sc_width, sc_height;
extern int screen_trashed;
extern int lnloop;
extern int linenums;
extern int wscroll;
extern int reading;
/*
* Interrupt signal handler.
*/
/* ARGSUSED*/
static RETSIGTYPE
u_interrupt(type)
int type;
{
#if OS2
LSIGNAL(SIGINT, SIG_ACK);
#endif
LSIGNAL(SIGINT, u_interrupt);
sigs |= S_INTERRUPT;
#if MSDOS_COMPILER==DJGPPC
/*
* If a keyboard has been hit, it must be Ctrl-C
* (as opposed to Ctrl-Break), so consume it.
* (Otherwise, Less will beep when it sees Ctrl-C from keyboard.)
*/
if (kbhit())
getkey();
#endif
if (reading)
intread();
}
#ifdef SIGTSTP
/*
* "Stop" (^Z) signal handler.
*/
/* ARGSUSED*/
static RETSIGTYPE
stop(type)
int type;
{
LSIGNAL(SIGTSTP, stop);
sigs |= S_STOP;
if (reading)
intread();
}
#endif
#ifdef SIGWINCH
/*
* "Window" change handler
*/
/* ARGSUSED*/
public RETSIGTYPE
winch(type)
int type;
{
LSIGNAL(SIGWINCH, winch);
sigs |= S_WINCH;
if (reading)
intread();
}
#else
#ifdef SIGWIND
/*
* "Window" change handler
*/
/* ARGSUSED*/
public RETSIGTYPE
winch(type)
int type;
{
LSIGNAL(SIGWIND, winch);
sigs |= S_WINCH;
if (reading)
intread();
}
#endif
#endif
#if MSDOS_COMPILER==WIN32C
/*
* Handle CTRL-C and CTRL-BREAK keys.
*/
#include "windows.h"
static BOOL WINAPI
wbreak_handler(dwCtrlType)
DWORD dwCtrlType;
{
switch (dwCtrlType)
{
case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
sigs |= S_INTERRUPT;
return (TRUE);
default:
break;
}
return (FALSE);
}
#endif
/*
* Set up the signal handlers.
*/
public void
init_signals(on)
int on;
{
if (on)
{
/*
* Set signal handlers.
*/
(void) LSIGNAL(SIGINT, u_interrupt);
#if MSDOS_COMPILER==WIN32C
SetConsoleCtrlHandler(wbreak_handler, TRUE);
#endif
#ifdef SIGTSTP
(void) LSIGNAL(SIGTSTP, stop);
#endif
#ifdef SIGWINCH
(void) LSIGNAL(SIGWINCH, winch);
#else
#ifdef SIGWIND
(void) LSIGNAL(SIGWIND, winch);
#endif
#ifdef SIGQUIT
(void) LSIGNAL(SIGQUIT, SIG_IGN);
#endif
#endif
} else
{
/*
* Restore signals to defaults.
*/
(void) LSIGNAL(SIGINT, SIG_DFL);
#if MSDOS_COMPILER==WIN32C
SetConsoleCtrlHandler(wbreak_handler, FALSE);
#endif
#ifdef SIGTSTP
(void) LSIGNAL(SIGTSTP, SIG_DFL);
#endif
#ifdef SIGWINCH
(void) LSIGNAL(SIGWINCH, SIG_IGN);
#endif
#ifdef SIGWIND
(void) LSIGNAL(SIGWIND, SIG_IGN);
#endif
#ifdef SIGQUIT
(void) LSIGNAL(SIGQUIT, SIG_DFL);
#endif
}
}
/*
* Process any signals we have received.
* A received signal cause a bit to be set in "sigs".
*/
public void
psignals()
{
register int tsignals;
if ((tsignals = sigs) == 0)
return;
sigs = 0;
#ifdef SIGTSTP
if (tsignals & S_STOP)
{
/*
* Clean up the terminal.
*/
#ifdef SIGTTOU
LSIGNAL(SIGTTOU, SIG_IGN);
#endif
clear_bot();
deinit();
flush();
raw_mode(0);
#ifdef SIGTTOU
LSIGNAL(SIGTTOU, SIG_DFL);
#endif
LSIGNAL(SIGTSTP, SIG_DFL);
kill(getpid(), SIGTSTP);
/*
* ... Bye bye. ...
* Hopefully we'll be back later and resume here...
* Reset the terminal and arrange to repaint the
* screen when we get back to the main command loop.
*/
LSIGNAL(SIGTSTP, stop);
raw_mode(1);
init();
screen_trashed = 1;
tsignals |= S_WINCH;
}
#endif
#ifdef S_WINCH
if (tsignals & S_WINCH)
{
int old_width, old_height;
/*
* Re-execute scrsize() to read the new window size.
*/
old_width = sc_width;
old_height = sc_height;
get_term();
if (sc_width != old_width || sc_height != old_height)
{
wscroll = (sc_height + 1) / 2;
screen_trashed = 1;
}
}
#endif
if (tsignals & S_INTERRUPT)
{
bell();
/*
* {{ You may wish to replace the bell() with
* error("Interrupt", NULL_PARG); }}
*/
/*
* If we were interrupted while in the "calculating
* line numbers" loop, turn off line numbers.
*/
if (lnloop)
{
lnloop = 0;
if (linenums == 2)
screen_trashed = 1;
linenums = 0;
error("Line numbers turned off", NULL_PARG);
}
}
}

231
contrib/less/tags.c Normal file
View File

@ -0,0 +1,231 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
#include "less.h"
#define WHITESP(c) ((c)==' ' || (c)=='\t')
#if TAGS
public char *tags = "tags";
static char *tagfile;
static char *tagpattern;
static int taglinenum;
static int tagendline;
extern int linenums;
extern int sigs;
extern int jump_sline;
/*
* Find a tag in the "tags" file.
* Sets "tagfile" to the name of the file containing the tag,
* and "tagpattern" to the search pattern which should be used
* to find the tag.
*/
public void
findtag(tag)
register char *tag;
{
char *p;
char *q;
register FILE *f;
register int taglen;
int search_char;
int err;
char tline[TAGLINE_SIZE];
p = unquote_file(tags);
f = fopen(p, "r");
free(p);
if (f == NULL)
{
error("No tags file", NULL_PARG);
tagfile = NULL;
return;
}
taglen = strlen(tag);
/*
* Search the tags file for the desired tag.
*/
while (fgets(tline, sizeof(tline), f) != NULL)
{
if (strncmp(tag, tline, taglen) != 0 || !WHITESP(tline[taglen]))
continue;
/*
* Found it.
* The line contains the tag, the filename and the
* location in the file, separated by white space.
* The location is either a decimal line number,
* or a search pattern surrounded by a pair of delimiters.
* Parse the line and extract these parts.
*/
tagfile = tagpattern = NULL;
taglinenum = 0;
/*
* Skip over the whitespace after the tag name.
*/
p = skipsp(tline+taglen);
if (*p == '\0')
/* File name is missing! */
continue;
/*
* Save the file name.
* Skip over the whitespace after the file name.
*/
tagfile = p;
while (!WHITESP(*p) && *p != '\0')
p++;
*p++ = '\0';
p = skipsp(p);
if (*p == '\0')
/* Pattern is missing! */
continue;
tagfile = save(tagfile);
/*
* First see if it is a line number.
*/
taglinenum = getnum(&p, 0, &err);
if (err)
{
/*
* No, it must be a pattern.
* Delete the initial "^" (if present) and
* the final "$" from the pattern.
* Delete any backslash in the pattern.
*/
taglinenum = 0;
search_char = *p++;
if (*p == '^')
p++;
tagpattern = (char *) ecalloc(strlen(p)+1, sizeof(char));
q = tagpattern;
while (*p != search_char && *p != '\0')
{
if (*p == '\\')
p++;
*q++ = *p++;
}
tagendline = (q[-1] == '$');
if (tagendline)
q--;
*q = '\0';
}
fclose(f);
return;
}
fclose(f);
error("No such tag in tags file", NULL_PARG);
tagfile = NULL;
}
public int
edit_tagfile()
{
int r;
if (tagfile == NULL)
return (1);
r = edit(tagfile);
free(tagfile);
tagfile = NULL;
return (r);
}
/*
* Search for a tag.
* This is a stripped-down version of search().
* We don't use search() for several reasons:
* - We don't want to blow away any search string we may have saved.
* - The various regular-expression functions (from different systems:
* regcmp vs. re_comp) behave differently in the presence of
* parentheses (which are almost always found in a tag).
*/
public POSITION
tagsearch()
{
POSITION pos, linepos;
int linenum;
int len;
char *line;
/*
* If we have the line number of the tag instead of the pattern,
* just use find_pos.
*/
if (taglinenum)
return (find_pos(taglinenum));
pos = ch_zero();
linenum = find_linenum(pos);
for (;;)
{
/*
* Get lines until we find a matching one or
* until we hit end-of-file.
*/
if (ABORT_SIGS())
return (NULL_POSITION);
/*
* Read the next line, and save the
* starting position of that line in linepos.
*/
linepos = pos;
pos = forw_raw_line(pos, &line);
if (linenum != 0)
linenum++;
if (pos == NULL_POSITION)
{
/*
* We hit EOF without a match.
*/
error("Tag not found", NULL_PARG);
return (NULL_POSITION);
}
/*
* If we're using line numbers, we might as well
* remember the information we have now (the position
* and line number of the current line).
*/
if (linenums)
add_lnum(linenum, pos);
/*
* Test the line to see if we have a match.
* Use strncmp because the pattern may be
* truncated (in the tags file) if it is too long.
* If tagendline is set, make sure we match all
* the way to end of line (no extra chars after the match).
*/
len = strlen(tagpattern);
if (strncmp(tagpattern, line, len) == 0 &&
(!tagendline || line[len] == '\0' || line[len] == '\r'))
break;
}
free(tagpattern);
tagpattern = NULL;
return (linepos);
}
#endif

161
contrib/less/ttyin.c Normal file
View File

@ -0,0 +1,161 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Routines dealing with getting input from the keyboard (i.e. from the user).
*/
#include "less.h"
#if MSDOS_COMPILER==WIN32C
#include "windows.h"
extern char WIN32getch();
static DWORD console_mode;
#endif
static int tty;
extern int sigs;
/*
* Open keyboard for input.
*/
public void
open_getchr()
{
#if MSDOS_COMPILER==WIN32C
/* Need this to let child processes inherit our console handle */
SECURITY_ATTRIBUTES sa;
memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
tty = (int) CreateFile("CONIN$", GENERIC_READ,
FILE_SHARE_READ, &sa,
OPEN_EXISTING, 0L, NULL);
GetConsoleMode((HANDLE)tty, &console_mode);
/* Make sure we get Ctrl+C events. */
SetConsoleMode((HANDLE)tty, ENABLE_PROCESSED_INPUT);
#else
#if MSDOS_COMPILER || OS2
extern int fd0;
/*
* Open a new handle to CON: in binary mode
* for unbuffered keyboard read.
*/
fd0 = dup(0);
close(0);
tty = open("CON", OPEN_READ);
#if MSDOS_COMPILER==DJGPPC
/*
* Setting stdin to binary causes Ctrl-C to not
* raise SIGINT. We must undo that side-effect.
*/
(void) __djgpp_set_ctrl_c(1);
#endif
#else
/*
* Try /dev/tty.
* If that doesn't work, use file descriptor 2,
* which in Unix is usually attached to the screen,
* but also usually lets you read from the keyboard.
*/
tty = open("/dev/tty", OPEN_READ);
if (tty < 0)
tty = 2;
#endif
#endif
}
/*
* Close the keyboard.
*/
public void
close_getchr()
{
#if MSDOS_COMPILER==WIN32C
SetConsoleMode((HANDLE)tty, console_mode);
CloseHandle((HANDLE)tty);
#endif
}
/*
* Get a character from the keyboard.
*/
public int
getchr()
{
char c;
int result;
do
{
#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
/*
* In raw read, we don't see ^C so look here for it.
*/
flush();
#if MSDOS_COMPILER==WIN32C
if (ABORT_SIGS())
return (READ_INTR);
c = WIN32getch(tty);
#else
c = getch();
#endif
result = 1;
if (c == '\003')
return (READ_INTR);
#else
#if OS2
{
static int scan = -1;
flush();
if (scan >= 0)
{
c = scan;
scan = -1;
} else
{
if ((c = _read_kbd(0, 1, 0)) == -1)
return (READ_INTR);
if (c == '\0')
{
/*
* Zero is usually followed by another byte,
* since certain keys send two bytes.
*/
scan = _read_kbd(0, 0, 0);
}
}
result = 1;
}
#else
result = iread(tty, &c, sizeof(char));
if (result == READ_INTR)
return (READ_INTR);
if (result < 0)
{
/*
* Don't call error() here,
* because error calls getchr!
*/
quit(QUIT_ERROR);
}
#endif
#endif
/*
* Various parts of the program cannot handle
* an input character of '\0'.
* If a '\0' was actually typed, convert it to '\340' here.
*/
if (c == '\0')
c = '\340';
} while (result != 1);
return (c & 0377);
}

599
contrib/less/version.c Normal file
View File

@ -0,0 +1,599 @@
/*
* Copyright (C) 1984-2000 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
----------------------- CHANGE HISTORY --------------------------
1/29/84 Allowed use on standard input
2/1/84 Added E, N, P commands
4/17/84 Added '=' command, 'stop' signal handling
4/20/84 Added line folding
v2 4/27/84 Fixed '=' command to use BOTTOM_PLUS_ONE,
instead of TOP, added 'p' & 'v' commands
v3 5/3/84 Added -m and -t options, '-' command
v4 5/3/84 Added LESS environment variable
v5 5/3/84 New comments, fixed '-' command slightly
v6 5/15/84 Added -Q, visual bell
v7 5/24/84 Fixed jump_back(n) bug: n should count real
lines, not folded lines. Also allow number on G command.
v8 5/30/84 Re-do -q and -Q commands
v9 9/25/84 Added "+<cmd>" argument
v10 10/10/84 Fixed bug in -b<n> argument processing
v11 10/18/84 Made error() ring bell if \n not entered.
-----------------------------------------------------------------
v12 2/13/85 Reorganized signal handling and made portable to 4.2bsd.
v13 2/16/85 Reword error message for '-' command.
v14 2/22/85 Added -bf and -bp variants of -b.
v15 2/25/85 Miscellaneous changes.
v16 3/13/85 Added -u flag for backspace processing.
v17 4/13/85 Added j and k commands, changed -t default.
v18 4/20/85 Rewrote signal handling code.
v19 5/2/85 Got rid of "verbose" eq_message().
Made search() scroll in some cases.
v20 5/21/85 Fixed screen.c ioctls for System V.
v21 5/23/85 Fixed some first_cmd bugs.
v22 5/24/85 Added support for no RECOMP nor REGCMP.
v23 5/25/85 Miscellanous changes and prettying up.
Posted to USENET.
-----------------------------------------------------------------
v24 6/3/85 Added ti,te terminal init & de-init.
(Thanks to Mike Kersenbrock)
v25 6/8/85 Added -U flag, standout mode underlining.
v26 6/9/85 Added -M flag.
Use underline termcap (us) if it exists.
v27 6/15/85 Renamed some variables to make unique in
6 chars. Minor fix to -m.
v28 6/28/85 Fixed right margin bug.
v29 6/28/85 Incorporated M.Rose's changes to signal.c
v30 6/29/85 Fixed stupid bug in argument processing.
v31 7/15/85 Added -p flag, changed repaint algorithm.
Added kludge for magic cookie terminals.
v32 7/16/85 Added cat_file if output not a tty.
v33 7/23/85 Added -e flag and EDITOR.
v34 7/26/85 Added -s flag.
v35 7/27/85 Rewrote option handling; added option.c.
v36 7/29/85 Fixed -e flag to work if not last file.
v37 8/10/85 Added -x flag.
v38 8/19/85 Changed prompting; created prompt.c.
v39 8/24/85 (Not -p) does not initially clear screen.
v40 8/26/85 Added "skipping" indicator in forw().
Posted to USENET.
-----------------------------------------------------------------
v41 9/17/85 ONLY_RETURN, control char commands,
faster search, other minor fixes.
v42 9/25/85 Added ++ command line syntax;
ch_fsize for pipes.
v43 10/15/85 Added -h flag, changed prim.c algorithms.
v44 10/16/85 Made END print in all cases of eof;
ignore SIGTTOU after receiv ing SIGTSTP.
v45 10/16/85 Never print backspaces unless -u.
v46 10/24/85 Backwards scroll in jump_loc.
v47 10/30/85 Fixed bug in edit(): *first_cmd==0
v48 11/16/85 Use TIOCSETN instead of TIOCSETP.
Added marks (m and ' commands).
Posted to USENET.
-----------------------------------------------------------------
v49 1/9/86 Fixed bug: signal didn't clear mcc.
v50 1/15/86 Added ' (quote) to gomark.
v51 1/16/86 Added + cmd, fixed problem if first_cmd
fails, made g cmd sort of "work" on pipes
ev en if bof is no longer buffered.
v52 1/17/86 Made short files work better.
v53 1/20/86 Added -P option.
v54 1/20/86 Changed help to use HELPFILE.
v55 1/23/86 Messages work better if not tty output.
v56 1/24/86 Added -l option.
v57 1/31/86 Fixed -l to get confirmation before
ov erwriting an existing file.
v58 8/28/86 Added filename globbing.
v59 9/15/86 Fixed some bugs with very long filenames.
v60 9/26/86 Incorporated changes from Leith (Casey)
Leedom for boldface and -z option.
v61 9/26/86 Got rid of annoying repaints after ! cmd.
Posted to USENET.
-----------------------------------------------------------------
v62 12/23/86 Added is_directory(); change -z default to
-1 instead of 24; cat-and-exit if -e and
file is less than a screenful.
v63 1/8/87 Fixed bug in cat-and-exit if > 1 file.
v64 1/12/87 Changed puts/putstr, putc/putchr,
getc/getchr to av oid name conflict with
stdio functions.
v65 1/26/87 Allowed '-' command to change NUMBER
v alued options (thanks to Gary Puckering)
v66 2/13/87 Fixed bug: prepaint should use force=1.
v67 2/24/87 Added !! and % expansion to ! command.
v68 2/25/87 Added SIGWINCH and TIOCGWINSZ support;
changed is_directory to bad_file.
(thanks to J. Robert Ward)
v69 2/25/87 Added SIGWIND and WIOCGETD (for Unix PC).
v70 3/13/87 Changed help cmd from 'h' to 'H'; better
error msgs in bad_file, errno_message.
v71 5/11/87 Changed -p to -c, made triple -c/-C
for clear-eol like more's -c.
v72 6/26/87 Added -E, -L, use $SHELL in lsystem().
(thanks to Stev e Spearman)
v73 6/26/87 Allow Examine "#" for previous file.
Posted to USENET 8/25/87.
-----------------------------------------------------------------
v74 9/18/87 Fix conflict in EOF symbol with stdio.h,
Make os.c more portable to BSD.
v75 9/23/87 Fix problems in get_term (thanks to
Paul Eggert); new backwards scrolling in
jump_loc (thanks to Marion Hakanson).
v76 9/23/87 Added -i flag; allow single "!" to
inv oke a shell (thanks to Franco Barber).
v77 9/24/87 Added -n flag and line number support.
v78 9/25/87 Fixed problem with prompts longer than
the screen width.
v79 9/29/87 Added the _ command.
v80 10/6/87 Allow signal to break out of linenum scan.
v81 10/6/87 Allow -b to be changed from within less.
v82 10/7/87 Add cmd_decode to use a table for key
binding (thanks to Dav id Nason).
v83 10/9/87 Allow .less file for user-defined keys.
v84 10/11/87 Fix -e/-E problems (thanks to Felix Lee).
v85 10/15/87 Search now keeps track of line numbers.
v86 10/20/87 Added -B option and autobuf; fixed
"pipe error" bug.
v87 3/1/88 Fix bug re BSD signals while reading file.
v88 3/12/88 Use new format for -P option (thanks to
der Mouse), allow "+-c" without message,
fix bug re BSD hangup.
v89 3/18/88 Turn off line numbers if linenum scan
is interrupted.
v90 3/30/88 Allow -P from within less.
v91 3/30/88 Added tags file support (new -t option)
(thanks to Brian Campbell).
v92 4/4/88 Added -+option syntax.
v93 4/11/88 Add support for slow input (thanks to
Joe Orost & apologies for taking almost
3 years to get this in!)
v94 4/11/88 Redo reading/signal stuff.
v95 4/20/88 Repaint screen better after signal.
v96 4/21/88 Add /! and ?! commands.
v97 5/17/88 Allow -l/-L from within less.
Eliminate some static arrays (use calloc).
Posted to USENET.
-----------------------------------------------------------------
v98 10/14/88 Fix incorrect calloc call; uninitialized
var in exec_mca; core dump on unknown TERM.
Make v cmd work if past last line of file.
Fix some signal bugs.
v99 10/29/88 Allow space between -X and string,
when X is a string-valued option.
v100 1/5/89 Fix globbing bug when $SHELL not set;
allow spaces after -t command.
v101 1/6/89 Fix problem with long (truncated) lines
in tags file (thanks to Neil Dixon).
v102 1/6/89 Fix bug with E# when no prev file;
allow spaces after -l command.
v103 3/14/89 Add -N, -f and -? options. Add z and w
commands. Add %L for prompt strings.
v104 3/16/89 Added EDITPROTO.
v105 3/20/89 Fix bug in find_linenum which cached
incorrectly on long lines.
v106 3/31/89 Added -k option and multiple lesskey
files.
v107 4/27/89 Add 8-bit char support and -g option.
Split option code into 3 files.
v108 5/5/89 Allocate position table dynamically
(thanks to Paul Eggert); change % command
from "percent" to vi-style brace finder.
v109 5/10/89 Added ESC-% command, split prim.c.
v110 5/24/89 Fixed bug in + option; fixed repaint bug
under Sun windows (thanks to Paul Eggert).
v111 5/25/89 Generalized # and % expansion; use
calloc for some error messages.
v112 5/30/89 Get rid of ESC-%, add {}()[] commands.
v113 5/31/89 Optimize lseeks (thanks to Paul Eggert).
v114 7/25/89 Added ESC-/ and ESC-/! commands.
v115 7/26/89 Added ESC-n command.
v116 7/31/89 Added find_pos to optimize g command.
v117 8/1/89 Change -f option to -r.
v118 8/2/89 Save positions for all previous files,
not just the immediately previous one.
v119 8/7/89 Save marks across file boundaries.
Add file handle stuff.
v120 8/11/89 Add :ta command.
v121 8/16/89 Add -f option.
v122 8/30/89 Fix performance with many buffers.
v123 8/31/89 Verbose prompts for string options.
Posted beta to USENET.
-----------------------------------------------------------------
v124 9/18/89 Reorganize search commands,
N = rev, ESC-n = span, add ESC-N.
v125 9/18/89 Fix tab bug (thanks to Alex Liu).
Fix EOF bug when both -w and -c.
v126 10/25/89 Add -j option.
v127 10/27/89 Fix problems with blank lines before BOF.
v128 10/27/89 Add %bj, etc. to prompt strings.
v129 11/3/89 Add -+,-- commands; add set-option and
unset-option to lesskey.
v130 11/6/89 Generalize A_EXTRA to string, remove
set-option, unset-option from lesskey.
v131 11/7/89 Changed name of EDITPROTO to LESSEDIT.
v132 11/8/89 Allow editing of command prefix.
v133 11/16/89 Add -y option (thanks to Jeff Sullivan).
v134 12/1/89 Glob filenames in the -l command.
v135 12/5/89 Combined {}()[] commands into one, and
added ESC-^F and ESC-^B commands.
v136 1/20/90 Added -S, -R flags. Added | command.
Added warning for binary files. (thanks
to Richard Brittain and J. Sullivan).
v137 1/21/90 Rewrote horrible pappend code.
Added * notation for hi-bit chars.
v138 1/24/90 Fix magic cookie terminal handling.
Get rid of "cleanup" loop in ch_get.
v139 1/27/90 Added MSDOS support. (many thanks
to Richard Brittain).
v140 2/7/90 Editing a new file adds it to the
command line list.
v141 2/8/90 Add edit_list for editing >1 file.
v142 2/10/90 Add :x command.
v143 2/11/90 Add * and @ modifies to search cmds.
Change ESC-/ cmd from /@* to / *.
v144 3/1/90 Messed around with ch_zero;
no real change.
v145 3/2/90 Added -R and -v/-V for MSDOS;
renamed FILENAME to avoid conflict.
v146 3/5/90 Pull cmdbuf functions out of command.c
v147 3/7/90 Implement ?@; fix multi-file edit bugs.
v148 3/29/90 Fixed bug in :e<file> then :e#.
v149 4/3/90 Change error,ierror,query to use PARG.
v150 4/6/90 Add LESS_CHARSET, LESS_CHARDEF.
v151 4/13/90 Remove -g option; clean up ispipe.
v152 4/14/90 lsystem() closes input file, for
editors which require exclusive open.
v153 4/18/90 Fix bug if SHELL unset;
fix bug in overstrike control char.
v154 4/25/90 Output to fd 2 via buffer.
v155 4/30/90 Ignore -i if uppercase in pattern
(thanks to Michael Rendell.)
v156 5/3/90 Remove scroll limits in forw() & back();
causes problems with -c.
v157 5/4/90 Forward search starts at next real line
(not screen line) after jump target.
v158 6/14/90 Added F command.
v159 7/29/90 Fix bug in exiting: output not flushed.
v160 7/29/90 Clear screen before initial output w/ -c.
v161 7/29/90 Add -T flag.
v162 8/14/90 Fix bug with +F on command line.
v163 8/21/90 Added LESSBINFMT variable.
v164 9/5/90 Added -p, LINES, COLUMNS and
unset mark ' == BOF, for 1003.2 D5.
v165 9/6/90 At EOF with -c set, don't display empty
screen when try to page forward.
v166 9/6/90 Fix G when final line in file wraps.
v167 9/11/90 Translate CR/LF -> LF for 1003.2.
v168 9/13/90 Return to curr file if "tag not found".
v169 12/12/90 G goes to EOF even if file has grown.
v170 1/17/91 Add optimization for BSD _setjmp;
fix #include ioctl.h TERMIO problem.
(thanks to Paul Eggert)
Posted to USENET.
-----------------------------------------------------------------
v171 3/6/91 Fix -? bug in get_filename.
v172 3/15/91 Fix G bug in empty file.
Fix bug with ?\n and -i and uppercase
pattern at EOF!
(thanks to Paul Eggert)
v173 3/17/91 Change N cmd to not permanently change
direction. (thanks to Brian Matthews)
v174 3/18/91 Fix bug with namelogfile not getting
cleared when change files.
v175 3/18/91 Fix bug with ++cmd on command line.
(thanks to Jim Meyering)
v176 4/2/91 Change | to not force current screen,
include marked line, start/end from
top of screen. Improve search speed.
(thanks to Don Mears)
v177 4/2/91 Add LESSHELP variable.
Fix bug with F command with -e.
Try /dev/tty for input before using fd 2.
Patches posted to USENET 4/2/91.
-----------------------------------------------------------------
v178 4/8/91 Fixed bug in globbing logfile name.
(thanks to Jim Meyering)
v179 4/9/91 Allow negative -z for screen-relative.
v180 4/9/91 Clear to eos rather than eol if "db";
don't use "sr" if "da".
(thanks to Tor Lillqvist)
v181 4/18/91 Fixed bug with "negative" chars 80 - FF.
(thanks to Benny Sander Hofmann)
v182 5/16/91 Fixed bug with attribute at EOL.
(thanks to Brian Matthews)
v183 6/1/91 Rewrite linstall to do smart config.
v184 7/11/91 Process \b in searches based on -u
rather than -i.
v185 7/11/91 -Pxxx sets short prompt; assume SIGWINCH
after a SIGSTOP. (thanks to Ken Laprade)
-----------------------------------------------------------------
v186 4/20/92 Port to MS-DOS (Microsoft C).
v187 4/23/92 Added -D option & TAB_COMPLETE_FILENAME.
v188 4/28/92 Added command line editing features.
v189 12/8/92 Fix mem overrun in anscreen.c:init;
fix edit_list to recover from bin file.
v190 2/13/93 Make TAB enter one filename at a time;
create ^L with old TAB functionality.
v191 3/10/93 Defer creating "flash" page for MS-DOS.
v192 9/6/93 Add BACK-TAB.
v193 9/17/93 Simplify binary_file handling.
v194 1/4/94 Add rudiments of alt_filename handling.
v195 1/11/94 Port back to Unix; support keypad.
-----------------------------------------------------------------
v196 6/7/94 Fix bug with bad filename; fix IFILE
type problem. (thanks to David MacKenzie)
v197 6/7/94 Fix bug with .less tables inserted wrong.
v198 6/23/94 Use autoconf installation technology.
(thanks to David MacKenzie)
v199 6/29/94 Fix MS-DOS build (thanks to Tim Wiegman).
v200 7/25/94 Clean up copyright, minor fixes.
Posted to prep.ai.mit.edu
-----------------------------------------------------------------
v201 7/27/94 Check for no memcpy; add casts to calloc;
look for regcmp in libgen.a.
(thanks to Kaveh Ghazi).
v202 7/28/94 Fix bug in edit_next/edit_prev with
non-existant files.
v203 8/2/94 Fix a variety of configuration bugs on
various systems. (thanks to Sakai
Kiyotaka, Harald Koenig, Bjorn Brox,
Teemu Rantanen, and Thorsten Lockert)
v204 8/3/94 Use strerror if available.
(thanks to J.T. Conklin)
v205 8/5/94 Fix bug in finding "me" termcap entry.
(thanks to Andreas Stolcke)
8/10/94 v205+: Change BUFSIZ to LBUFSIZE to avoid name
conflict with stdio.h.
Posted to prep.ai.mit.edu
-----------------------------------------------------------------
v206 8/10/94 Use initial_scrpos for -t to avoid
displaying first page before init().
(thanks to Dominique Petitpierre)
v207 8/12/94 Fix bug if stdout is not tty.
v208 8/16/94 Fix bug in close_altfile if goto err1
in edit_ifile. (Thanks to M.J. Hewitt)
v209 8/16/94 Change scroll to wscroll to avoid
conflict with library function.
v210 8/16/94 Fix bug with bold on 8 bit chars.
(thanks to Vitor Duarte)
v211 8/16/94 Don't quit on EOI in jump_loc / forw.
v212 8/18/94 Use time_t if available.
v213 8/20/94 Allow ospeed to be defined in termcap.h.
v214 8/20/94 Added HILITE_SEARCH, -F, ESC-u cmd.
(thanks to Paul Lew and Bob Byrnes)
v215 8/23/94 Fix -i toggle behavior.
v216 8/23/94 Process BS in all searches, not only -u.
v217 8/24/94 Added -X flag.
v218 8/24/94 Reimplement undo_search.
v219 8/24/94 Find tags marked with line number
instead of pattern.
v220 8/24/94 Stay at same position after SIG_WINCH.
v221 8/24/94 Fix bug in file percentage in big file.
v222 8/25/94 Do better if can't reopen current file.
v223 8/27/94 Support setlocale.
(thanks to Robert Joop)
v224 8/29/94 Revert v216: process BS in search
only if -u.
v225 9/6/94 Rewrite undo_search again: toggle.
v226 9/15/94 Configuration fixes.
(thanks to David MacKenzie)
v227 9/19/94 Fixed strerror config problem.
Posted to prep.ai.mit.edu
-----------------------------------------------------------------
v228 9/21/94 Fix bug in signals: repeated calls to
get_editkeys overflowed st_edittable.
v229 9/21/94 Fix "Nothing to search" error if -a
and SRCH_PAST_EOF.
v230 9/21/94 Don't print extra error msg in search
after regerror().
v231 9/22/94 Fix hilite bug if search matches 0 chars.
(thanks to John Polstra)
v232 9/23/94 Deal with weird systems that have
termios.h but not tcgetattr().
Posted to prep.ai.mit.edu
-----------------------------------------------------------------
v233 9/26/94 Use get_term() instead of pos_init() in
psignals to re-get lower_left termcap.
(Thanks to John Malecki)
v234 9/26/94 Make MIDDLE closer to middle of screen.
v235 9/27/94 Use local strchr if system doesn't have.
v236 9/28/94 Don't use libucb; use libterm if
libtermcap & libcurses doesn't work.
(Fix for Solaris; thanks to Frank Kaefer)
v237 9/30/94 Use system isupper() etc if provided.
Posted to prep.ai.mit.edu
-----------------------------------------------------------------
v238 10/6/94 Make binary non-blinking if LESSBINFMT
is set to a string without a *.
v239 10/7/94 Don't let delimit_word run back past
beginning of cmdbuf.
v240 10/10/94 Don't write into termcap buffer.
(Thanks to Benoit Speckel)
v241 10/13/94 New lesskey file format.
Don't expand filenames in search command.
v242 10/14/94 Allow lesskey specification of "literal".
v243 10/14/94 Add #stop command to lesskey.
v244 10/16/94 Add -f flag to lesskey.
v245 10/25/94 Allow TAB_COMPLETE_FILENAME to be undefd.
v246 10/27/94 Move help file to /usr/local/share.
v247 10/27/94 Add -V option.
v248 11/5/94 Add -V option to lesskey.
v249 11/5/94 Remove -f flag from lesskey; default
input file is ~/.lesskey.in, not stdin.
v250 11/7/94 Lesskey input file "-" means stdin.
v251 11/9/94 Convert cfgetospeed result to ospeed.
(Thanks to Andrew Chernov)
v252 11/16/94 Change default lesskey input file from
.lesskey.in to .lesskey.
Posted to prep.ai.mit.edu
-----------------------------------------------------------------
v253 11/21/94 Fix bug when tags file has a backslash.
v254 12/6/94 Fix -k option.
v255 12/8/94 Add #define EXAMINE to disable :e etc.
v256 12/10/94 Change highlighting: only highlite search
results (but now it is reliable).
v257 12/10/94 Add goto_line and repaint_highlight
to optimize highlight repaints.
v258 12/12/94 Fixup in hilite_line if BS_SPECIAL.
v259 12/12/94 Convert to autoconf 2.0.
v260 12/13/94 Add SECURE define.
v261 12/14/94 Use system WERASE char as EC_W_BACKSPACE.
v262 12/16/94 Add -g/-G flag and screen_hilite.
v263 12/20/94 Reimplement/optimize -G flag behavior.
v264 12/23/94 Allow EXTRA string after line-edit cmd
in lesskey file.
v265 12/24/94 Add LESSOPEN=|cmd syntax.
v266 12/26/94 Add -I flag.
v267 12/28/94 Formalize the four-byte header emitted
by a LESSOPEN pipe.
v268 12/28/94 Get rid of four-byte header.
v269 1/2/95 Close alt file before open new one.
Avoids multiple popen().
v270 1/3/95 Use VISUAL; use S_ISDIR/S_ISREG; fix
config problem with Solaris POSIX regcomp.
v271 1/4/95 Don't quit on read error.
v272 1/5/95 Get rid of -L.
v273 1/6/95 Fix ch_ungetchar bug; don't call
LESSOPEN on a pipe.
v274 1/6/95 Ported to OS/2 (thanks to Kai Uwe Rommel)
v275 1/18/95 Fix bug if toggle -G at EOF.
v276 1/30/95 Fix OS/2 version.
v277 1/31/95 Add "next" charset; don't display ^X
for X > 128.
v278 2/14/95 Change default for -G.
Posted to prep.ai.mit.edu
-----------------------------------------------------------------
v279 2/22/95 Add GNU options --help, --version.
Minor config fixes.
v280 2/24/95 Clean up calls to glob(); don't set #
if we can't open the new file.
v281 2/24/95 Repeat search should turn on hilites.
v282 3/2/95 Minor fixes.
v283 3/2/95 Fix homefile; make OS2 look in $HOME.
v284 3/2/95 Error if "v" on LESSOPENed file;
"%" figures out file size on pipe.
v285 3/7/95 Don't set # in lsystem;
lesskey try $HOME first.
v286 3/7/95 Reformat change history (too much free time?).
v287 3/8/95 Fix hilite bug if overstrike multiple chars.
v288 3/8/95 Allow lesskey to override get_editkey keys.
v289 3/9/95 Fix adj_hilite bug when line gets processed by
hilite_line more than once.
v290 3/9/95 Make configure automatically. Fix Sequent problem
with incompatible sigsetmask().
Posted to prep.ai.mit.edu
-----------------------------------------------------------------
v291 3/21/95 Add #env to lesskey. Fix MS-DOS build.
Posted to simtel.
-----------------------------------------------------------------
v292 4/24/95 Add MS-DOS support for Borland C.
Fix arrow keys in MS-DOS versions.
v293 4/28/95 Add auto-versioning stuff to make dist.
v294 5/12/95 Fix Borland build.
v295 1/20/96 Fix search on squished file; add /@@.
v296 1/23/96 Allow cmdbuf larger than screen width.
v297 1/24/96 Don't call termcap if tgetent fails;
add #defines for buffers.
v298 1/24/96 Change @@ to ^K.
Add alternate search modifiers ^N, ^F, ^E.
v299 1/25/96 Fix percent overflow in jump_percent (thanks to Brent Wiese);
don't send "ti" after shell command till RETURN pressed.
v300 1/25/96 Change -U to print tabs as ^I.
v301 1/30/96 Make hilites work in cmd F output.
v302 1/31/96 Fix cmd F to notice window-change signals.
v303 1/31/96 Add ESC-SPACE command.
v304 2/1/96 Add ^R search modifier; add LESSSECURE.
v305 2/2/96 Workaround Linux /proc kernel bug; add LESSKEY.
v306 3/16/96 Minor fixes.
v307 3/25/96 Allow cmd line arg "--"; fix DOS & OS/2 defines.h.
v308 4/4/96 Port to OS-9 (thanks to Boisy Pitre); fix -d.
v309 4/9/96 Fix OS-9 version; fix tags bug with "$".
v310 4/10/96 Get rid of HELPFILE.
v311 4/22/96 Add Windows32 support; merge doscreen.c into screen.c.
v312 4/24/96 Don't quit after "cannot reopen" error.
v313 4/25/96 Added horizontal scrolling.
v314 4/26/96 Modified -e to quit on reaching end of a squished file.
v315 4/26/96 Fix "!;TAB" bug.
v316 5/2/96 Make "|a" when (a < curr screen) go to end of curr screen.
v317 5/14/96 Various fixes for the MS-DOS and OS/2 builds.
Added ## and %% handling for filenames
v318 5/29/96 Port to OS-9 Microware compiler; minor fixes
(thanks to Martin Gregorie).
v319 7/8/96 Fix Windows port (thanks to Jeff Paquette).
v320 7/11/96 Final fixes for Windows port.
v321 7/18/96 Minor fixes.
Posted to Web page.
-----------------------------------------------------------------
v322 8/13/96 Fix bug in shell escape from help file; add support for
Microsoft Visual C under Windows; numerous small fixes.
v323 8/19/96 Fixes for Windows version (thanks to Simon Munton);
fix for Linux library weirdness (thanks to Jim Diamond);
port to DJGPP (thanks to Eli Zaretskii).
v324 8/21/96 Add support for spaces in filenames (thanks to Simon Munton).
v325 8/21/96 Add lessecho, for spaces in filenames under Unix.
v326 8/27/96 Fix DJGPP version.
v327 9/1/96 Reorganize lglob, make spaces in filenames work better in Unix.
v328 10/7/96 Append / to directory name in filename completion.
Fix MS-DOS and OS-9 versions.
v329 10/11/96 Fix more MS-DOS bugs; add LESSSEPARATOR; add -" option.
Add LESSMETACHARS, LESSMETAESCAPE.
v330 10/21/96 Minor fixes.
Posted to Web page.
-----------------------------------------------------------------
v331 4/22/97 Various Windows fixes (thanks to Gurusamy Sarathy).
v332 4/22/97 Enter filenames from cmd line into edit history.
Posted to Web page.
-----------------------------------------------------------------
v333 3/4/99 Changed -w to highlite new line after forward movement.
v334 3/9/99 Avoid overflowing prompt buffer; add %d and %D.
v335 3/20/99 Add EBCDIC support (thanks to Thomas Dorner).
Use HOMEDRIVE/HOMEPATH on Windows (thanks to Preston Bannister).
Posted to Web page.
-----------------------------------------------------------------
v336 4/8/99 Fix installation bugs.
v337 4/9/99 Fix another installation bug.
Posted to Web page.
-----------------------------------------------------------------
v338 4/13/99 Add support for long option names.
v339 4/18/99 Add \k, long option names to lesskey. Add -^P. Add :d.
v340 4/21/99 Add regexec2. Fix Windows build.
Posted to Web page.
-----------------------------------------------------------------
v341 5/6/99 Add -F option; %c & ?c prompt escapes.
(Thanks to Michele Maltoni)
v342 7/22/99 Add system-wide lesskey file; allow GPL or Less License.
v343 9/23/99 Support UTF-8 (Thanks to Robert Brady).
Add %P and ?P in prompts.
v344 10/27/99 -w highlights target line of g and p commands.
v345 10/29/99 Make -R pass thru ESC but not other control chars.
Posted to Web page.
-----------------------------------------------------------------
v346 11/4/99 Fix bugs in long option processing; R cmd should clear hilites.
Posted to Web page.
-----------------------------------------------------------------
v347 12/13/99 Fixes for DJGPP version (thanks to Eli Zaretskii).
v348 12/28/99 Fix deleting file with marks (thanks to Dimitar Jekov).
Fix color problem in DJGPP version (thanks to Eli Zaretskii).
v349 1/24/00 Fix minor DJGPP bugs; check environment vars for UTF-8;
add --with-editor (thanks to Eli, Markus Kuhn, Thomas Schoepf).
v350 3/1/00 Fix clear-while-standout bug.
v351 3/5/00 Change -M and = prompts to show top & bottom line number.
Posted to Web page.
-----------------------------------------------------------------
v352 3/8/00 Fix scan_option NULL dereference.
-----------------------------------------------------------------
v353 3/20/00 Fix SECURE compile bug, allow space after numeric option.
v354 3/23/00 Add support for PCRE; add --with-regex configure option.
*/
char version[] = "354";