diff --exclude=*,v -r -U2 --entire less-205/Makefile.in less-227/Makefile.in --- less-205/Makefile.in Tue Jul 26 19:28:01 1994 +++ less-227/Makefile.in Fri Sep 16 12:57:05 1994 @@ -12,5 +12,7 @@ CFLAGS = -O +CFLAGS_COMPILE_ONLY = -c LDFLAGS = +O=o LIBS = @LIBS@ @@ -37,19 +39,20 @@ # in addition to whatever the user asks for. .c.o: - $(CC) -c -I. $(CPPFLAGS) $(CFLAGS) $< + $(CC) -I. $(CFLAGS_COMPILE_ONLY) $(CPPFLAGS) $(CFLAGS) $< -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 -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 -DISTFILES = ${SRC} INSTALL Makefile.in Makefile.dos README NEWS \ +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 +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@ +DISTFILES = ${SRC} regexp.c regexp.h \ + INSTALL Makefile.in Makefile.dos README NEWS \ configure configure.in doscreen.c acconfig.h lesskey.c \ cmd.h defines.dos funcs.h less.h option.h position.h \ @@ -62,10 +65,10 @@ $(CC) $(LDFLAGS) -o $@ $(OBJ) $(LIBS) -lesskey: lesskey.o - $(CC) $(LDFLAGS) -o $@ lesskey.o +lesskey: lesskey.$(O) + $(CC) $(LDFLAGS) -o $@ lesskey.$(O) $(OBJ): less.h defines.h funcs.h -filename.o: filename.c +filename.$(O): filename.c ${CC} -c -DHELPFILE=\"${datadir}/less.hlp\" -I. ${CPPFLAGS} ${CFLAGS} ${srcdir}/filename.c @@ -105,6 +108,8 @@ ./config.status --recheck +lint: + lint -I. $(CPPFLAGS) $(SRC) clean: - rm -f *.o core less lesskey + rm -f *.$(O) core less lesskey mostlyclean: clean diff --exclude=*,v -r -U2 --entire less-205/NEWS less-227/NEWS --- less-205/NEWS Tue Aug 9 16:26:02 1994 +++ less-227/NEWS Mon Sep 19 19:14:51 1994 @@ -1,14 +1,55 @@ - Major changes between "less" versions 170 and 205 + Major changes between "less" versions 170 and 227 -* Ported to MS-DOS. +* 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 and - filename completion. +* New line-editing keys, including command history (arrow keys) and + filename completion (TAB). -* Input filter allows modification of input files (e.g. uncompress) +* 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. diff --exclude=*,v -r -U2 --entire less-205/README less-227/README --- less-205/README Tue Aug 9 18:15:45 1994 +++ less-227/README Mon Sep 19 19:14:55 1994 @@ -1,4 +1,4 @@ ======================================================================= -=== NOTE: THIS IS A BETA DISTRIBUTION OF less (version 205) === +=== NOTE: THIS IS A BETA DISTRIBUTION OF less (version 227) === === PLEASE REPORT ANY PROBLEMS TO THE AUTHOR. === ======================================================================= @@ -17,11 +17,10 @@ 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. 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. For example, if you have both libtermcap and libcurses, - configure will choose libtermcap. But if your libtermcap has bugs, - you may wish to edit the Makefile to choose libcurses instead. + Makefile now. If you wish, you may edit defines.h to remove some optional features. diff --exclude=*,v -r -U2 --entire less-205/acconfig.h less-227/acconfig.h --- less-205/acconfig.h Wed Aug 3 20:37:54 1994 +++ less-227/acconfig.h Sun Aug 28 14:58:38 1994 @@ -44,4 +44,7 @@ #undef HAVE_VOID +/* 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 @@ -52,2 +55,11 @@ /* 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 */ +#undef HAVE_OSPEED +/* Define MUST_DEFINE_OSPEED if you have ospeed but it is not defined + * in termcap.h. */ +#undef MUST_DEFINE_OSPEED + +/* Define if you have locale.h and setlocale. */ +#undef HAVE_LOCALE diff --exclude=*,v -r -U2 --entire less-205/ch.c less-227/ch.c --- less-205/ch.c Wed Aug 10 16:18:37 1994 +++ less-227/ch.c Fri Aug 26 00:54:28 1994 @@ -221,5 +221,5 @@ slept = 1; } - if (sigs) + if (ABORT_SIGS()) return (EOI); } @@ -268,5 +268,5 @@ ierror("Finishing logfile", NULL_PARG); while (ch_forw_get() != EOI) - if (sigs) + if (ABORT_SIGS()) break; } @@ -360,5 +360,5 @@ */ while (ch_forw_get() != EOI) - if (sigs) + if (ABORT_SIGS()) return (1); return (0); diff --exclude=*,v -r -U2 --entire less-205/charset.c less-227/charset.c --- less-205/charset.c Thu Jul 28 17:13:02 1994 +++ less-227/charset.c Sun Aug 28 17:26:23 1994 @@ -32,4 +32,8 @@ #include "less.h" +#if HAVE_LOCALE +#include +#include +#endif /* @@ -44,4 +48,5 @@ { "latin1", "8bcccbcc18b95.33b." }, { "dos", "8bcccbcc12bc5b95.98b.b" }, + { "koi8-r", "8bcccbcc18b95.b128." }, { NULL } }; @@ -149,4 +154,26 @@ } +#if HAVE_LOCALE +/* + * Define a charset, given a locale name. + */ + static void +ilocale() +{ + register int c; + + setlocale(LC_CTYPE, ""); + for (c = 0; c < 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. @@ -157,5 +184,5 @@ { if (s == NULL || *s == '\0') - s = "*k<%X>"; + s = "*s<%X>"; /* * Select the attributes if it starts with "*". @@ -167,4 +194,5 @@ 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; @@ -172,8 +200,5 @@ s += 2; } - if (*s == '\0') - binfmt = "<%X>"; - else - binfmt = s; + binfmt = s; } @@ -204,9 +229,15 @@ return; } +#if HAVE_LOCALE + /* + * Use setlocale. + */ + ilocale(); +#else /* - * LESSCHARDEF is not defined either: default to "ascii". + * Default to "ascii". */ (void) icharset("ascii"); - +#endif } @@ -244,8 +275,8 @@ c &= 0377; - if (c == ESC) - sprintf(buf, "ESC"); - else if (!control_char(c)) + if (!control_char(c)) sprintf(buf, "%c", c); + else if (c == ESC) + sprintf(buf, "ESC"); else if (!control_char(c ^ 0100)) sprintf(buf, "^%c", c ^ 0100); diff --exclude=*,v -r -U2 --entire less-205/cmd.h less-227/cmd.h --- less-205/cmd.h Mon Jul 25 20:40:09 1994 +++ less-227/cmd.h Thu Aug 25 00:28:58 1994 @@ -66,5 +66,5 @@ #define A_PIPE 37 #define A_INDEX_FILE 38 - +#define A_UNDO_SEARCH 39 diff --exclude=*,v -r -U2 --entire less-205/cmdbuf.c less-227/cmdbuf.c --- less-205/cmdbuf.c Thu Jul 28 17:13:34 1994 +++ less-227/cmdbuf.c Fri Sep 2 16:18:46 1994 @@ -790,5 +790,5 @@ in_completion = 1; init_textlist(&tk_tlist, tk_text); - tk_trial = next_compl(action, NULL); + tk_trial = next_compl(action, (char*)NULL); } } else diff --exclude=*,v -r -U2 --entire less-205/command.c less-227/command.c --- less-205/command.c Thu Jul 28 17:14:06 1994 +++ less-227/command.c Fri Sep 2 16:19:24 1994 @@ -45,6 +45,7 @@ extern int jump_sline; extern int quitting; -extern int scroll; +extern int wscroll; extern int nohelp; +extern int top_scroll; extern int ignore_eoi; extern char *every_first_cmd; @@ -443,5 +444,11 @@ jump_loc(initial_scrpos.pos, initial_scrpos.ln); } else if (screen_trashed) + { + int save_top_scroll; + save_top_scroll = top_scroll; + top_scroll = 1; repaint(); + top_scroll = save_top_scroll; + } /* @@ -626,8 +633,11 @@ if (changed_file) + { /* * Restore the file we were originally viewing. */ - (void) edit_ifile(save_ifile); + if (edit_ifile(save_ifile)) + quit(-1); + } } @@ -648,5 +658,5 @@ search_type = SRCH_FORW; - scroll = (sc_height + 1) / 2; + wscroll = (sc_height + 1) / 2; for (;;) @@ -844,5 +854,5 @@ ignore_eoi = 1; hit_eof = 0; - while (sigs == 0) + while (!ABORT_SIGS()) forward(1, 0, 0); ignore_eoi = 0; @@ -855,7 +865,7 @@ */ if (number > 0) - scroll = number; + wscroll = number; cmd_exec(); - forward(scroll, 0, 0); + forward(wscroll, 0, 0); break; @@ -866,7 +876,7 @@ */ if (number > 0) - scroll = number; + wscroll = number; cmd_exec(); - backward(scroll, 0, 0); + backward(wscroll, 0, 0); break; @@ -1025,4 +1035,8 @@ break; + case A_UNDO_SEARCH: + undo_search(); + break; + case A_HELP: /* @@ -1063,5 +1077,5 @@ */ cmd_exec(); - lsystem(pr_expand(editproto, 0), NULL); + lsystem(pr_expand(editproto, 0)); /* * Re-edit the file, since data may have changed. @@ -1069,5 +1083,6 @@ * buffers is not sufficient. */ - (void) edit_ifile(curr_ifile); + if (edit_ifile(curr_ifile)) + quit(-1); break; #else diff --exclude=*,v -r -U2 --entire less-205/configure less-227/configure --- less-205/configure Thu Aug 4 00:45:01 1994 +++ less-227/configure Mon Sep 19 18:40:12 1994 @@ -488,5 +488,27 @@ -# Prefer BSD termcap library to SysV curses library. +ac_save_LIBS="${LIBS}" +LIBS="${LIBS} -lcurses" +ac_have_lib="" +test -n "$silent" || echo "checking for -lcurses" +cat > conftest.${ac_ext} < conftest.${ac_ext} < conftest.${ac_ext} < +int main() { return 0; } +int t() { time_t t = 0;; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining HAVE_TIME_T" +echo "#define" HAVE_TIME_T "1" >> confdefs.h +DEFS="$DEFS -DHAVE_TIME_T=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE_TIME_T\${ac_dB}HAVE_TIME_T\${ac_dC}1\${ac_dD} +\${ac_uA}HAVE_TIME_T\${ac_uB}HAVE_TIME_T\${ac_uC}1\${ac_uD} +\${ac_eA}HAVE_TIME_T\${ac_eB}HAVE_TIME_T\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -f conftest* + test -n "$silent" || echo "checking for return type of signal handlers" @@ -770,8 +838,16 @@ cat > conftest.${ac_ext} < - #include +#endif +#if HAVE_STRING_H +#include +#endif +#if HAVE_ERRNO_H +#include +#endif int main() { return 0; } -int t() { static int x,y; x=strerror(y);; return 0; } +int t() { static char *x; x = strerror(0);; return 0; } EOF if eval $ac_compile; then @@ -841,4 +917,102 @@ rm -f conftest* +test -n "$silent" || echo "checking for locale" +cat > conftest.${ac_ext} < +#include +int main() { return 0; } +int t() { setlocale(LC_CTYPE,""); isprint(0); iscntrl(0);; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining HAVE_LOCALE" +echo "#define" HAVE_LOCALE "1" >> confdefs.h +DEFS="$DEFS -DHAVE_LOCALE=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE_LOCALE\${ac_dB}HAVE_LOCALE\${ac_dC}1\${ac_dD} +\${ac_uA}HAVE_LOCALE\${ac_uB}HAVE_LOCALE\${ac_uC}1\${ac_uD} +\${ac_eA}HAVE_LOCALE\${ac_eB}HAVE_LOCALE\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -f conftest* + + +have_ospeed=no +test -n "$silent" || echo "checking termcap for ospeed" +cat > conftest.${ac_ext} < +#if HAVE_TERMIOS_H +#include +#endif +#if HAVE_TERMCAP_H +#include +#endif +int main() { return 0; } +int t() { ospeed = 0;; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining HAVE_OSPEED" +echo "#define" HAVE_OSPEED "1" >> confdefs.h +DEFS="$DEFS -DHAVE_OSPEED=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE_OSPEED\${ac_dB}HAVE_OSPEED\${ac_dC}1\${ac_dD} +\${ac_uA}HAVE_OSPEED\${ac_uB}HAVE_OSPEED\${ac_uC}1\${ac_uD} +\${ac_eA}HAVE_OSPEED\${ac_eB}HAVE_OSPEED\${ac_eC}1\${ac_eD} +" +} + have_ospeed=yes + +fi +rm -f conftest* + +if test $have_ospeed = no; then +cat > conftest.${ac_ext} <> confdefs.h +DEFS="$DEFS -DHAVE_OSPEED=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE_OSPEED\${ac_dB}HAVE_OSPEED\${ac_dC}1\${ac_dD} +\${ac_uA}HAVE_OSPEED\${ac_uB}HAVE_OSPEED\${ac_uC}1\${ac_uD} +\${ac_eA}HAVE_OSPEED\${ac_eB}HAVE_OSPEED\${ac_eC}1\${ac_eD} +" +} + +{ +test -n "$verbose" && \ +echo " defining MUST_DEFINE_OSPEED" +echo "#define" MUST_DEFINE_OSPEED "1" >> confdefs.h +DEFS="$DEFS -DMUST_DEFINE_OSPEED=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}MUST_DEFINE_OSPEED\${ac_dB}MUST_DEFINE_OSPEED\${ac_dC}1\${ac_dD} +\${ac_uA}MUST_DEFINE_OSPEED\${ac_uB}MUST_DEFINE_OSPEED\${ac_uC}1\${ac_uD} +\${ac_eA}MUST_DEFINE_OSPEED\${ac_eB}MUST_DEFINE_OSPEED\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -f conftest* + +fi + have_regex=no @@ -870,5 +1044,5 @@ if test $have_regex = no; then -test -n "$silent" || echo "checking for re_comp" +test -n "$silent" || echo "checking for regcmp" cat > conftest.${ac_ext} <> confdefs.h -DEFS="$DEFS -DHAVE_RE_COMP=1" -ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE_RE_COMP\${ac_dB}HAVE_RE_COMP\${ac_dC}1\${ac_dD} -\${ac_uA}HAVE_RE_COMP\${ac_uB}HAVE_RE_COMP\${ac_uC}1\${ac_uD} -\${ac_eA}HAVE_RE_COMP\${ac_eB}HAVE_RE_COMP\${ac_eC}1\${ac_eD} +echo " defining HAVE_REGCMP" +echo "#define" HAVE_REGCMP "1" >> confdefs.h +DEFS="$DEFS -DHAVE_REGCMP=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE_REGCMP\${ac_dB}HAVE_REGCMP\${ac_dC}1\${ac_dD} +\${ac_uA}HAVE_REGCMP\${ac_uB}HAVE_REGCMP\${ac_uC}1\${ac_uD} +\${ac_eA}HAVE_REGCMP\${ac_eB}HAVE_REGCMP\${ac_eC}1\${ac_eD} " } @@ -906,31 +1080,21 @@ fi if test $have_regex = no; then -test -n "$silent" || echo "checking for regcmp" cat > conftest.${ac_ext} < +#include "regexp.h" int main() { return 0; } -int t() { -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_regcmp) || defined (__stub___regcmp) -choke me -#else -/* Override any gcc2 internal prototype to avoid an error. */ -extern char regcmp(); regcmp(); -#endif -; return 0; } +int t() { regcomp("");; return 0; } EOF if eval $ac_compile; then rm -rf conftest* - { + +{ test -n "$verbose" && \ -echo " defining HAVE_REGCMP" -echo "#define" HAVE_REGCMP "1" >> confdefs.h -DEFS="$DEFS -DHAVE_REGCMP=1" -ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE_REGCMP\${ac_dB}HAVE_REGCMP\${ac_dC}1\${ac_dD} -\${ac_uA}HAVE_REGCMP\${ac_uB}HAVE_REGCMP\${ac_uC}1\${ac_uD} -\${ac_eA}HAVE_REGCMP\${ac_eB}HAVE_REGCMP\${ac_eC}1\${ac_eD} +echo " defining HAVE_V8_REGCOMP" +echo "#define" HAVE_V8_REGCOMP "1" >> confdefs.h +DEFS="$DEFS -DHAVE_V8_REGCOMP=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE_V8_REGCOMP\${ac_dB}HAVE_V8_REGCOMP\${ac_dC}1\${ac_dD} +\${ac_uA}HAVE_V8_REGCOMP\${ac_uB}HAVE_V8_REGCOMP\${ac_uC}1\${ac_uD} +\${ac_eA}HAVE_V8_REGCOMP\${ac_eB}HAVE_V8_REGCOMP\${ac_eC}1\${ac_eD} " } @@ -941,12 +1105,20 @@ fi -if test $have_regex = no; then -test -n "$silent" || echo "checking for Spencer V8 regexp.h" -echo '#include "confdefs.h" -#include ' > conftest.${ac_ext} -eval "$ac_cpp conftest.${ac_ext} > conftest.out 2>&1" -if egrep "reganch" conftest.out >/dev/null 2>&1; then - rm -rf conftest* - +if test $have_regex = no && test -f ${srcdir}/regex.c; then + +{ +test -n "$verbose" && \ +echo " defining HAVE_POSIX_REGCOMP" +echo "#define" HAVE_POSIX_REGCOMP "1" >> confdefs.h +DEFS="$DEFS -DHAVE_POSIX_REGCOMP=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE_POSIX_REGCOMP\${ac_dB}HAVE_POSIX_REGCOMP\${ac_dC}1\${ac_dD} +\${ac_uA}HAVE_POSIX_REGCOMP\${ac_uB}HAVE_POSIX_REGCOMP\${ac_uC}1\${ac_uD} +\${ac_eA}HAVE_POSIX_REGCOMP\${ac_eB}HAVE_POSIX_REGCOMP\${ac_eC}1\${ac_eD} +" +} + REGEX_O='regex.$(O)' have_regex=yes +fi +if test $have_regex = no && test -f ${srcdir}/regexp.c; then + { test -n "$verbose" && \ @@ -959,4 +1131,36 @@ " } + REGEX_O='regexp.$(O)' have_regex=yes +fi +if test $have_regex = no; then +test -n "$silent" || echo "checking for re_comp" +cat > conftest.${ac_ext} < +int main() { return 0; } +int t() { +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_re_comp) || defined (__stub___re_comp) +choke me +#else +/* Override any gcc2 internal prototype to avoid an error. */ +extern char re_comp(); re_comp(); +#endif +; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + { +test -n "$verbose" && \ +echo " defining HAVE_RE_COMP" +echo "#define" HAVE_RE_COMP "1" >> confdefs.h +DEFS="$DEFS -DHAVE_RE_COMP=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE_RE_COMP\${ac_dB}HAVE_RE_COMP\${ac_dC}1\${ac_dD} +\${ac_uA}HAVE_RE_COMP\${ac_uB}HAVE_RE_COMP\${ac_uC}1\${ac_uD} +\${ac_eA}HAVE_RE_COMP\${ac_eB}HAVE_RE_COMP\${ac_eC}1\${ac_eD} +" +} have_regex=yes @@ -1044,4 +1248,5 @@ INSTALL_PROGRAM='$INSTALL_PROGRAM' INSTALL_DATA='$INSTALL_DATA' +REGEX_O='$REGEX_O' LIBS='$LIBS' srcdir='$srcdir' @@ -1097,4 +1302,5 @@ s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@REGEX_O@%$REGEX_O%g s%@LIBS@%$LIBS%g s%@srcdir@%$srcdir%g diff --exclude=*,v -r -U2 --entire less-205/configure.in less-227/configure.in --- less-205/configure.in Thu Aug 4 00:42:08 1994 +++ less-227/configure.in Mon Sep 19 18:40:01 1994 @@ -9,25 +9,37 @@ dnl Checks for libraries. -# Prefer BSD termcap library to SysV curses library. -AC_HAVE_LIBRARY(termcap, -[LIBS="$LIBS -ltermcap"; AC_VERBOSE(using -ltermcap)], -[LIBS="$LIBS -lcurses"; AC_VERBOSE(using -lcurses)]) -# Regular expressions (regcmp) are in -lgen on Solaris 2. -AC_HAVE_LIBRARY(gen, [LIBS="$LIBS -lgen"; AC_VERBOSE(using -lgen)]) - +dnl Prefer BSD termcap library to SysV curses library. +AC_HAVE_LIBRARY(curses, [LIBS="$LIBS -lcurses"]) +AC_HAVE_LIBRARY(termcap, [LIBS="$LIBS -ltermcap"]) +dnl ??? AC_HAVE_LIBRARY(termlib, [LIBS="$LIBS -ltermlib"]) +dnl Regular expressions (regcmp) are in -lgen or -lucb on Solaris 2. +AC_HAVE_LIBRARY(gen, [LIBS="$LIBS -lgen"]) +AC_HAVE_LIBRARY(ucb, [LIBS="$LIBS -lucb"]) +dnl ??? AC_HAVE_LIBRARY(gnuregex, [LIBS="$LIBS -lgnuregex"]) dnl Checks for header files. AC_STDC_HEADERS -AC_HAVE_HEADERS(fcntl.h stdio.h termcap.h termio.h termios.h time.h unistd.h sys/stream.h sys/ptem.h) +AC_HAVE_HEADERS(errno.h fcntl.h stdio.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_OFF_T -AC_COMPILE_CHECK(void, , [void *foo = 0;], [AC_DEFINE(HAVE_VOID)]) +AC_COMPILE_CHECK(void, , [void *foo = 0;], + [AC_DEFINE(HAVE_VOID)]) +AC_COMPILE_CHECK(time_t, [#include ], [time_t t = 0;], + [AC_DEFINE(HAVE_TIME_T)]) dnl Checks for functions and external variables. AC_RETSIGTYPE AC_HAVE_FUNCS(_setjmp system sigsetmask memcpy) -AC_COMPILE_CHECK(strerror, [#include - #include ], [static int x,y; x=strerror(y);], +AC_COMPILE_CHECK(strerror, [ +#if HAVE_STDIO_H +#include +#endif +#if HAVE_STRING_H +#include +#endif +#if HAVE_ERRNO_H +#include +#endif], [static char *x; x = strerror(0);], [AC_DEFINE(HAVE_STRERROR)]) AC_COMPILE_CHECK(, , [extern int sys_errlist; static int x; x = sys_errlist;], @@ -35,4 +47,23 @@ AC_COMPILE_CHECK(, , [extern int errno; static int x; x = errno;], [AC_DEFINE(HAVE_ERRNO)]) +AC_COMPILE_CHECK(locale, [#include +#include ], [setlocale(LC_CTYPE,""); isprint(0); iscntrl(0);], + [AC_DEFINE(HAVE_LOCALE)]) + +have_ospeed=no +AC_CHECKING(termcap for ospeed) +AC_COMPILE_CHECK(, [ +#include +#if HAVE_TERMIOS_H +#include +#endif +#if HAVE_TERMCAP_H +#include +#endif], [ospeed = 0;], [AC_DEFINE(HAVE_OSPEED) have_ospeed=yes]) +if test $have_ospeed = no; then +AC_COMPILE_CHECK(, , [extern short ospeed; ospeed = 0;], + [AC_DEFINE(HAVE_OSPEED) AC_DEFINE(MUST_DEFINE_OSPEED)]) +fi + dnl Checks for regular expression functions. @@ -44,12 +75,18 @@ AC_DEFINE(HAVE_POSIX_REGCOMP) have_regex=yes) if test $have_regex = no; then -AC_FUNC_CHECK(re_comp, AC_DEFINE(HAVE_RE_COMP) have_regex=yes) +AC_FUNC_CHECK(regcmp, AC_DEFINE(HAVE_REGCMP) have_regex=yes) fi if test $have_regex = no; then -AC_FUNC_CHECK(regcmp, AC_DEFINE(HAVE_REGCMP) have_regex=yes) +AC_COMPILE_CHECK(, [#include "regexp.h"], [regcomp("");], +AC_DEFINE(HAVE_V8_REGCOMP) have_regex=yes) +fi +if test $have_regex = no && test -f ${srcdir}/regex.c; then +AC_DEFINE(HAVE_POSIX_REGCOMP) REGEX_O='regex.$(O)' AC_SUBST(REGEX_O) have_regex=yes +fi +if test $have_regex = no && test -f ${srcdir}/regexp.c; then +AC_DEFINE(HAVE_V8_REGCOMP) REGEX_O='regexp.$(O)' AC_SUBST(REGEX_O) have_regex=yes fi if test $have_regex = no; then -AC_CHECKING([for Spencer V8 [regexp.h]]) -AC_HEADER_EGREP(reganch, [regexp.h], AC_DEFINE(HAVE_V8_REGCOMP) have_regex=yes) +AC_FUNC_CHECK(re_comp, AC_DEFINE(HAVE_RE_COMP) have_regex=yes) fi if test $have_regex = no; then diff --exclude=*,v -r -U2 --entire less-205/decode.c less-227/decode.c --- less-205/decode.c Thu Jul 28 17:14:47 1994 +++ less-227/decode.c Thu Aug 25 00:28:26 1994 @@ -90,4 +90,5 @@ CONTROL('R'),0, A_REPAINT, CONTROL('L'),0, A_REPAINT, + ESC,'u',0, A_UNDO_SEARCH, 'g',0, A_GOLINE, '<',0, A_GOLINE, diff --exclude=*,v -r -U2 --entire less-205/defines.dos less-227/defines.dos --- less-205/defines.dos Tue Aug 9 16:28:15 1994 +++ less-227/defines.dos Mon Aug 29 14:34:29 1994 @@ -54,4 +54,10 @@ /* + * 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.) @@ -169,4 +175,7 @@ #define HAVE_VOID 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 0 @@ -178,4 +187,13 @@ #define HAVE_SYS_ERRLIST 0 +/* 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 if you have locale.h and setlocale. */ +#define HAVE_LOCALE 0 + /* Define if you have _setjmp. */ #define HAVE__SETJMP 0 @@ -190,7 +208,16 @@ #define HAVE_SYSTEM 1 +/* Define if you have the header file. */ +#define HAVE_ERRNO_H 0 + /* Define if you have the header file. */ #define HAVE_FCNTL_H 1 +/* Define if you have the header file. */ +#define HAVE_STDIO_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_IOCTL_H 0 + /* Define if you have the header file. */ #define HAVE_SYS_PTEM_H 0 @@ -213,2 +240,5 @@ /* Define if you have the header file. */ #define HAVE_UNISTD_H 1 + +/* Define if you have the header file. */ +#define HAVE_VALUES_H 0 diff --exclude=*,v -r -U2 --entire less-205/defines.h.in less-227/defines.h.in --- less-205/defines.h.in Fri Aug 5 17:13:32 1994 +++ less-227/defines.h.in Sun Aug 28 14:58:49 1994 @@ -33,4 +33,10 @@ /* + * 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.) @@ -144,4 +150,7 @@ #undef HAVE_VOID +/* 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 @@ -153,4 +162,13 @@ #undef HAVE_SYS_ERRLIST +/* Define HAVE_OSPEED if your termcap library has the ospeed variable */ +#undef HAVE_OSPEED +/* Define MUST_DEFINE_OSPEED if you have ospeed but it is not defined + * in termcap.h. */ +#undef MUST_DEFINE_OSPEED + +/* Define if you have locale.h and setlocale. */ +#undef HAVE_LOCALE + /* Define if you have _setjmp. */ #undef HAVE__SETJMP @@ -165,4 +183,7 @@ #undef HAVE_SYSTEM +/* Define if you have the header file. */ +#undef HAVE_ERRNO_H + /* Define if you have the header file. */ #undef HAVE_FCNTL_H @@ -171,4 +192,7 @@ #undef HAVE_STDIO_H +/* Define if you have the header file. */ +#undef HAVE_SYS_IOCTL_H + /* Define if you have the header file. */ #undef HAVE_SYS_PTEM_H @@ -191,2 +215,5 @@ /* Define if you have the header file. */ #undef HAVE_UNISTD_H + +/* Define if you have the header file. */ +#undef HAVE_VALUES_H diff --exclude=*,v -r -U2 --entire less-205/defines.h.top less-227/defines.h.top --- less-205/defines.h.top Mon Aug 1 20:22:41 1994 +++ less-227/defines.h.top Sun Aug 21 20:14:38 1994 @@ -32,4 +32,10 @@ /* + * 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.) diff --exclude=*,v -r -U2 --entire less-205/doscreen.c less-227/doscreen.c --- less-205/doscreen.c Wed Jul 27 16:05:02 1994 +++ less-227/doscreen.c Wed Aug 24 02:57:23 1994 @@ -182,4 +182,5 @@ init() { + /* {{ What could we take no_init (-X) to mean? }} */ sy_bg_color = _getbkcolor(); sy_fg_color = _gettextcolor(); diff --exclude=*,v -r -U2 --entire less-205/edit.c less-227/edit.c --- less-205/edit.c Tue Aug 2 20:43:30 1994 +++ less-227/edit.c Fri Sep 9 02:23:44 1994 @@ -231,9 +231,7 @@ if (alt_filename != NULL) { - close_altfile(filename, alt_filename); + close_altfile(alt_filename, filename); free(alt_filename); } - if (ifile == curr_ifile) - curr_ifile = getoff_ifile(curr_ifile); del_ifile(ifile); return (1); @@ -357,4 +355,10 @@ 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; @@ -388,5 +392,6 @@ */ return (0); - edit_ifile(save_curr_ifile); + if (edit_ifile(save_curr_ifile)) + quit(-1); return (edit(good_filename)); } diff --exclude=*,v -r -U2 --entire less-205/filename.c less-227/filename.c --- less-205/filename.c Tue Aug 2 20:41:38 1994 +++ less-227/filename.c Fri Sep 2 16:20:34 1994 @@ -348,5 +348,5 @@ * an "echo" command to the shell and reading its output. */ - fd = shellcmd("echo %s", filename, NULL); + fd = shellcmd("echo %s", filename, (char*)NULL); if (fd == NULL) { @@ -378,5 +378,5 @@ if (filename == NULL) return (NULL); - fd = shellcmd(lessopen, filename, NULL); + fd = shellcmd(lessopen, filename, (char*)NULL); if (fd == NULL) { diff --exclude=*,v -r -U2 --entire less-205/forwback.c less-227/forwback.c --- less-205/forwback.c Mon Jul 25 20:40:10 1994 +++ less-227/forwback.c Fri Sep 2 16:21:15 1994 @@ -49,5 +49,5 @@ extern int ignore_eoi; #if TAGS -extern int tagoption; +extern char *tagoption; #endif @@ -74,5 +74,5 @@ if (ignore_eoi) return; - if (sigs) + if (ABORT_SIGS()) return; /* @@ -230,5 +230,5 @@ if (first_time && pos == NULL_POSITION && !top_scroll && #if TAGS - !tagoption && + tagoption == NULL && #endif !plusoption) @@ -244,5 +244,5 @@ if (ignore_eoi) hit_eof = 0; - else if (eof && !sigs) + else if (eof && !ABORT_SIGS()) hit_eof++; else diff --exclude=*,v -r -U2 --entire less-205/funcs.h less-227/funcs.h --- less-205/funcs.h Thu Jul 28 17:54:08 1994 +++ less-227/funcs.h Fri Sep 2 16:25:29 1994 @@ -156,4 +156,5 @@ public void opt__P (); public void opt_b (); + public void opt_i (); public void opt_D (); public void opt_query (); @@ -172,5 +173,5 @@ public long get_time (); public char * errno_message (); - public char * errno_message (); + public int percentage (); public void put_line (); public void flush (); @@ -217,5 +218,8 @@ public void backspace (); public void putbs (); + public void undo_search (); + public void chg_caseless (); public int search (); + public void hlsearch (); public void fake_interrupt (); public RETSIGTYPE winch (); @@ -224,5 +228,5 @@ public void psignals (); public void findtag (); - public int tagsearch (); + public POSITION tagsearch (); public void open_getchr (); public int getchr (); diff --exclude=*,v -r -U2 --entire less-205/ifile.c less-227/ifile.c --- less-205/ifile.c Thu Jul 28 17:20:57 1994 +++ less-227/ifile.c Fri Sep 9 02:26:07 1994 @@ -39,4 +39,6 @@ #include "less.h" +extern IFILE curr_ifile; + struct ifile { struct ifile *h_next; /* Links for command line list */ @@ -138,4 +140,10 @@ if (h == NULL_IFILE) return; + /* + * If the ifile we're deleting is the currently open ifile, + * move off it. + */ + if (h == curr_ifile) + curr_ifile = getoff_ifile(curr_ifile); p = int_ifile(h); unlink_ifile(p); diff --exclude=*,v -r -U2 --entire less-205/input.c less-227/input.c --- less-205/input.c Mon Jul 25 20:40:11 1994 +++ less-227/input.c Fri Aug 26 00:55:34 1994 @@ -78,5 +78,5 @@ for (;;) { - if (sigs) + if (ABORT_SIGS()) { null_line(); @@ -130,5 +130,5 @@ */ while ((c = ch_forw_get()) == '\n' || c == '\r') - if (sigs) + if (ABORT_SIGS()) { null_line(); @@ -183,5 +183,5 @@ */ while ((c = ch_back_get()) == '\n' || c == '\r') - if (sigs) + if (ABORT_SIGS()) { null_line(); @@ -202,5 +202,5 @@ for (;;) { - if (sigs) + if (ABORT_SIGS()) { null_line(); @@ -253,5 +253,5 @@ { c = ch_forw_get(); - if (c == EOI || sigs) + if (c == EOI || ABORT_SIGS()) { null_line(); diff --exclude=*,v -r -U2 --entire less-205/jump.c less-227/jump.c --- less-205/jump.c Mon Jul 25 20:40:11 1994 +++ less-227/jump.c Wed Aug 17 01:11:09 1994 @@ -264,8 +264,10 @@ if (pos == NULL_POSITION) { - /* Cannot happen! */ - error("Program error: EOI in jump_loc (forw)", - NULL_PARG); - quit(1); + /* + * Ran into end of file. + * This shouldn't normally happen, + * but may if there is some kind of read error. + */ + break; } if (pos >= tpos) diff --exclude=*,v -r -U2 --entire less-205/less.h less-227/less.h --- less-205/less.h Tue Aug 9 19:22:02 1994 +++ less-227/less.h Fri Aug 26 00:59:10 1994 @@ -173,4 +173,5 @@ #define AT_BLINK (3) #define AT_INVIS (4) +#define AT_STANDOUT (5) #define CONTROL(c) ((c)&037) @@ -201,4 +202,9 @@ #define SIGNAL(sig,func) signal(sig,func) + +#define S_INTERRUPT 01 +#define S_STOP 02 +#define S_WINCH 04 +#define ABORT_SIGS() (sigs & (S_INTERRUPT|S_STOP)) #define ch_zero() ((POSITION)0) diff --exclude=*,v -r -U2 --entire less-205/less.hlp less-227/less.hlp --- less-205/less.hlp Thu Jun 23 19:52:19 1994 +++ less-227/less.hlp Tue Sep 6 12:41:15 1994 @@ -29,4 +29,5 @@ 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: @@ -80,4 +81,5 @@ -e -E Quit at end of file. -f Force open non-regular files. + -F Don't highlight matches for previous search pattern. -h [_N] Backward scroll limit. -i Ignore case in searches. @@ -99,4 +101,5 @@ -w Display ~ for lines after end-of-file. -x [_N] Set tab stops. + -X Don't use termcap init/deinit strings. -y [_N] Forward scroll limit. -z [_N] Set size of window. diff --exclude=*,v -r -U2 --entire less-205/less.man less-227/less.man --- less-205/less.man Tue Aug 9 18:47:29 1994 +++ less-227/less.man Tue Sep 13 00:54:39 1994 @@ -289,4 +289,13 @@ and crossing file boundaries. + ESC-u + Undo search highlighting. Turn off highlighting of + strings matching the current search pattern. If + highlighting is already off because of a previous ESC-u + command, turn highlighting back on. Any search command + will also turn highlighting back on. (Highlighting can + also be disabled by toggling the -F flag; in that case + search commands do not turn highlighting back on.) + :e [filename] Examine a new file. If the filename is missing, the @@ -314,13 +323,4 @@ examined. - :x Examine the first file in the command line list. If a - number N is specified, the N-th file in the list is - examined. - - = or ^G or :f - Prints some information about the file being viewed, - including its name and the line number and byte offset - of the bottom line being displayed. If possible, it - @@ -336,4 +336,12 @@ + :x Examine the first file in the command line list. If a + number N is specified, the N-th file in the list is + examined. + + = or ^G or :f + Prints some information about the file being viewed, + including its name and the line number and byte offset + of the bottom line being displayed. If possible, it also prints the length of the file, the number of lines in the file and the percent of the file above the last @@ -381,12 +389,4 @@ depending on your particular installation. - v Invokes an editor to edit the current file being - viewed. The editor is taken from the environment vari- - able EDITOR, or defaults to "vi". See also the discus- - sion of LESSEDIT under the section on PROMPTS below. - - ! shell-command - Invokes a shell to run the shell-command given. A - @@ -402,11 +402,17 @@ - percent sign (%) in the command is replaced by the name - of the current file. A pound sign (#) is replaced by - the name of the previously examined file. "!!" repeats - the last shell command. "!" with no shell command sim- - ply invokes a shell. In all cases, the shell is taken - from the environment variable SHELL, or defaults to - "sh". + v Invokes an editor to edit the current file being + viewed. The editor is taken from the environment vari- + able EDITOR, or defaults to "vi". See also the discus- + sion of LESSEDIT under the section on PROMPTS below. + + ! shell-command + Invokes a shell to run the shell-command given. A per- + cent sign (%) in the command is replaced by the name of + the current file. A pound sign (#) is replaced by the + name of the previously examined file. "!!" repeats the + last shell command. "!" with no shell command simply + invokes a shell. In all cases, the shell is taken from + the environment variable SHELL, or defaults to "sh". | shell-command @@ -448,10 +454,4 @@ after the help screen is viewed. (Depending on how your shell interprets the question mark, it may be - necessary to quote the question mark, thus: "-\?".) - - -a Causes searches to start after the last line displayed - on the screen, thus skipping all lines displayed on the - screen. By default, searches start at the second line - on the screen (or after the last found line; see the -j @@ -468,4 +468,10 @@ + necessary to quote the question mark, thus: "-\?".) + + -a Causes searches to start after the last line displayed + on the screen, thus skipping all lines displayed on the + screen. By default, searches start at the second line + on the screen (or after the last found line; see the -j option). @@ -514,10 +520,4 @@ -f Forces non-regular files to be opened. (A non-regular - file is a directory or a device special file.) Also - suppresses the warning message when a binary file is - opened. By default, _l_e_s_s will refuse to open non- - regular files. - - -h_n Specifies a maximum number of lines to scroll backward. @@ -534,4 +534,14 @@ + file is a directory or a device special file.) Also + suppresses the warning message when a binary file is + opened. By default, _l_e_s_s will refuse to open non- + regular files. + + -F Normally, _l_e_s_s will highlight all strings which match + the current search pattern, by displaying them in stan- + dout mode. The -F flag suppresses this highlighting. + + -h_n Specifies a maximum number of lines to scroll backward. If it is necessary to scroll backward more than _n lines, the screen is repainted in a forward direction @@ -576,14 +586,4 @@ Suppressing line numbers with the -n flag will avoid this problem. Using line numbers means: the line - number will be displayed in the verbose prompt and in - the = command, and the v command will pass the current - line number to the editor (see also the discussion of - LESSEDIT in PROMPTS below). - - -N Causes a line number to be displayed at the beginning - of each line in the display. - - -o_f_i_l_e_n_a_m_e - Causes _l_e_s_s to copy its input to the named file as it @@ -600,4 +600,14 @@ + number will be displayed in the verbose prompt and in + the = command, and the v command will pass the current + line number to the editor (see also the discussion of + LESSEDIT in PROMPTS below). + + -N Causes a line number to be displayed at the beginning + of each line in the display. + + -o_f_i_l_e_n_a_m_e + Causes _l_e_s_s to copy its input to the named file as it is being viewed. This applies only when the input file is a pipe, not an ordinary file. If the file already @@ -643,14 +653,4 @@ default is to ring the terminal bell in all such cases. - -Q Causes totally "quiet" operation: the terminal bell is - never rung. - - -r Causes "raw" control characters to be displayed. The - default is to display control characters using the - caret notation; for example, a control-A (octal 001) is - displayed as "^A". Warning: when the -r flag is used, - _l_e_s_s cannot keep track of the actual appearance of the - screen (since this depends on how the screen responds - @@ -666,4 +666,13 @@ + -Q Causes totally "quiet" operation: the terminal bell is + never rung. + + -r Causes "raw" control characters to be displayed. The + default is to display control characters using the + caret notation; for example, a control-A (octal 001) is + displayed as "^A". Warning: when the -r flag is used, + _l_e_s_s cannot keep track of the actual appearance of the + screen (since this depends on how the screen responds to each type of control character). Thus, various display problems may result, such as long lines being @@ -708,14 +717,5 @@ is printed using the terminal's hardware boldface capa- bility. Other backspaces are deleted, along with the - preceding character. Carriage returns immediately fol- - lowed by a newline are deleted. Other carriage returns - are handled as specified by the -r option. Text which - is overstruck or underlined can be searched for. - - -w Causes blank lines to be used to represent lines past - the end of the file. By default, a tilde character is - used. - - -x_n Sets tab stops every _n positions. The default for _n is + preceding character. Carriage returns immediately @@ -732,6 +732,21 @@ + followed by a newline are deleted. Other carriage + returns are handled as specified by the -r option. + Text which is overstruck or underlined can be searched + for. + + -w Causes blank lines to be used to represent lines past + the end of the file. By default, a tilde character is + used. + + -x_n Sets tab stops every _n positions. The default for _n is 8. + -X Disables sending the termcap initialization and deini- + tialization strings to the terminal. This is sometimes + desirable if the deinitialization string does something + unnecessary, like clearing the screen. + -y_n Specifies a maximum number of lines to scroll forward. If it is necessary to scroll forward more than _n lines, @@ -745,5 +760,10 @@ The default is one screenful. The z and w commands can also be used to change the window size. The "z" may be - omitted, as in "-_n" for compatibility with _m_o_r_e. + omitted for compatibility with _m_o_r_e. If the number _n is + negative, it indicates _n lines less than the current + screen size. For example, if the screen is 24 lines, + -_z-_4 sets the scrolling window to 20 lines. If the + screen is resized to 40 lines, the scrolling window + automatically changes to 36 lines. + If a command line option begins with +, the remainder @@ -764,4 +784,18 @@ LINE EDITING When entering command line at the bottom of the screen (for + + + + 12 + + + + + + +LESS(1) USER COMMANDS LESS(1) + + + example, a filename for the :e command, or the pattern for a search command), certain keys can be used to manipulate the @@ -769,5 +803,8 @@ brackets ] which can be used if a key does not exist on a particular keyboard. (The bracketed forms do not work in the - MS-DOS version.) + MS-DOS version.) Any of these special keys may be entered + literally by preceding it with a backslash. A backslash + itself may also be entered literally by entering two + backslashes. LEFTARROW [ ESC-h ] @@ -785,17 +822,4 @@ the cursor one word to the right. - - - 12 - - - - - - -LESS(1) USER COMMANDS LESS(1) - - - HOME [ ESC-0 ] Move the cursor to the beginning of the line. @@ -825,8 +849,22 @@ Retrieve the next command line. - TAB Complete the partial filename to the left of the cur- - sor. If it matches more than one filename, the first - match is entered into the command line. Repeated TABs - will cycle thru the other matching filesnames. + TAB Complete the partial filename to the left of the + + + + 13 + + + + + + +LESS(1) USER COMMANDS LESS(1) + + + + cursor. If it matches more than one filename, the + first match is entered into the command line. Repeated + TABs will cycle thru the other matching filesnames. BACKTAB [ ESC-TAB ] @@ -850,18 +888,4 @@ directory. This file specifies a set of command keys and an action associated with each key. See the _l_e_s_s_k_e_y manual - - - - 13 - - - - - - -LESS(1) USER COMMANDS LESS(1) - - - page for more details. @@ -892,4 +916,18 @@ preprocessor command is invoked. + + + + 14 + + + + + + +LESS(1) USER COMMANDS LESS(1) + + + When _l_e_s_s closes a file opened in such a way, it will call another program, called the input postprocessor, which may @@ -917,17 +955,4 @@ fi - - - 14 - - - - - - -LESS(1) USER COMMANDS LESS(1) - - - lessclose.sh: #! /bin/sh @@ -954,16 +979,38 @@ binary characters - cannot be displayed directly and are not expected to be - found in text files. + should not be displayed directly and are not expected + to be found in text files. + + + + + 15 + + + - By default, _l_e_s_s uses the ASCII character set. In the ASCII - character set, characters with values between 128 and 255 - are treated as binary. The LESSCHARSET environment variable - may be used to select another character set. If it is set - to the value "latin1", the ISO 8859/1 character set is - assumed. Latin-1 is the same as ASCII, except characters - between 161 and 255 are treated as normal characters. The - only valid values for LESSCHARSET currently are "ascii" and - "latin1". + + +LESS(1) USER COMMANDS LESS(1) + + + + A "character set" is simply a description of which charac- + ters are to be considered normal, control, and binary. The + LESSCHARSET environment variable may be used to select a + character set. Possible values for LESSCHARSET are: + + ascii + The default character set. BS, TAB, NL, CR, and + formfeed are control characters, all chars with values + between 127 and 255 are binary, and all others are nor- + mal. + + latin1 + Selects the ISO 8859/1 character set. latin-1 is the + same as ASCII, except characters between 161 and 255 + are treated as normal characters. + + dos Selects a character set appropriate for MS-DOS. In special cases, it may be desired to tailor _l_e_s_s to use a @@ -982,8 +1029,27 @@ character set.) + Setting LESSCHARDEF to "8bcccbcc18b95.b" is the same as set- + ting LESSCHARSET to "ascii". Setting LESSCHARDEF to + "8bcccbcc18b95.33b." is the same as setting LESSCHARSET to + "latin1". + + If neither LESSCHARSET nor LESSCHARDEF is set, but your sys- + tem supports the _s_e_t_l_o_c_a_l_e interface, _l_e_s_s will use setlo- + cale to determine the character set. setlocale is con- + trolled by setting the LANG or LC_CTYPE environment vari- + ables. + + Control and binary characters are displayed in standout + (reverse video). Each such character is displayed in caret + notation if possible (e.g. ^A for control-A). Caret nota- + tion is used only if inverting the 0100 bit results in a + normal printable character. Otherwise, the character is + displayed as a hex number in angle brackets. This format + can be changed by setting the LESSBINFMT environment vari- + able. LESSBINFMT may begin with a "*" and one character to - 15 + 16 @@ -996,24 +1062,13 @@ - Setting LESSCHARDEF to "8bcccbcc18b95.b" is the same as set- - ting LESSCHARSET to "ascii". Setting LESSCHARDEF to - "8bcccbcc18b95.33b." is the same as setting LESSCHARSET to - "latin1". - - Control and binary characters are displayed in blinking - mode. Each such character is displayed in caret notation if - possible (e.g. ^A for control-A). Caret notation is used - only if inverting the 0100 bit results in a normal printable - character. Otherwise, the character is displayed as an - octal number preceded by a backslash. This octal format can - be changed by setting the LESSBINFMT environment variable to - a printf-style format string; the default is '\%o'. The - blinking mode display of control and binary characters can - be changed or disabled by preceding the LESSBINFMT format - string with a "*" and one character to select the mode: "*k" - is blinking, "*d" is bold, "*u" is underlined, and "*n" is - normal (no special display attribute). For example, if - LESSBINFMT is "*u[%x]", binary characters are displayed in - underlined hexadecimal surrounded by brackets. + select the display attribute: "*k" is blinking, "*d" is + bold, "*u" is underlined, "*s" is standout. If LESSBINFMT + does not begin with a "*", normal attribute is assumed. The + remainder of LESSBINFMT is a string which may include one + printf-style escape sequence (a % followed by x, X, o, d, + etc.). For example, if LESSBINFMT is "*u[%x]", binary char- + acters are displayed in underlined hexadecimal surrounded by + brackets. The default if no LESSBINFMT is specified is + "*d<%X>". @@ -1048,29 +1103,28 @@ %f Replaced by the name of the current input file. + %i Replaced by the index of the current file in the list + of input files. + %l_X Replaced by the line number of a line in the input + file. The line to be used is determined by the _X, as + with the %b option. + %L Replaced by the line number of the last line in the + input file. - 16 - + %m Replaced by the total number of input files. + 17 -LESS(1) USER COMMANDS LESS(1) - %i Replaced by the index of the current file in the list - of input files. - %l_X Replaced by the line number of a line in the input - file. The line to be used is determined by the _X, as - with the %b option. +LESS(1) USER COMMANDS LESS(1) - %L Replaced by the line number of the last line in the - input file. - %m Replaced by the total number of input files. %p_X Replaced by the percent into the current input file. @@ -1114,29 +1168,29 @@ is not a pipe). + ?l_X True if the line number of the specified line is known. + ?L True if the line number of the last line in the file is + known. + ?m True if there is more than one input file. - 17 + ?n True if this is the first prompt in a new input file. + ?p_X True if the percent into the current input file of the + specified line is known. + 18 -LESS(1) USER COMMANDS LESS(1) - ?l_X True if the line number of the specified line is known. - ?L True if the line number of the last line in the file is - known. - ?m True if there is more than one input file. +LESS(1) USER COMMANDS LESS(1) - ?n True if this is the first prompt in a new input file. - ?p_X True if the percent into the current input file of the - specified line is known. ?s Same as "?B". @@ -1180,30 +1234,30 @@ ?n?f%f .?m(file %i of %m) ..?e(END) ?x- Next\: %x.: + ?pB%pB\%:byte %bB?s/%s...%t + ?f%f .?n?m(file %i of %m) ..?ltline %lt?L/%L. :byte %bB?s/%s. . + ?e(END) ?x- Next\: %x.:?pB%pB\%..%t + And here is the default message produced by the = command: - 18 + ?f%f .?m(file %i of %m) .?ltline %lt?L/%L. . + byte %bB?s/%s. ?e(END) :?pB%pB\%..%t + The prompt expansion features are also used for another pur- + pose: if an environment variable LESSEDIT is defined, it is + 19 -LESS(1) USER COMMANDS LESS(1) - ?pB%pB\%:byte %bB?s/%s...%t - ?f%f .?n?m(file %i of %m) ..?ltline %lt?L/%L. :byte %bB?s/%s. . - ?e(END) ?x- Next\: %x.:?pB%pB\%..%t +LESS(1) USER COMMANDS LESS(1) - And here is the default message produced by the = command: - ?f%f .?m(file %i of %m) .?ltline %lt?L/%L. . - byte %bB?s/%s. ?e(END) :?pB%pB\%..%t - The prompt expansion features are also used for another pur- - pose: if an environment variable LESSEDIT is defined, it is used as the command to be executed when the v command is invoked. The LESSEDIT string is expanded in the same way as @@ -1234,4 +1288,9 @@ file). + LANG Language for determining the character set. + + LC_CTYPE + Language for determining the character set. + LESS Flags which are passed to _l_e_s_s automatically. @@ -1246,25 +1305,24 @@ Selects a predefined character set. + LESSCLOSE + Command line to invoke the (optional) input- + postprocessor. + LESSEDIT + Editor prototype string (used for the v command). See + discussion under PROMPTS. - 19 - + 20 -LESS(1) USER COMMANDS LESS(1) +LESS(1) USER COMMANDS LESS(1) - LESSCLOSE - Command line to invoke the (optional) input- - postprocessor. - LESSEDIT - Editor prototype string (used for the v command). See - discussion under PROMPTS. LESSHELP @@ -1300,11 +1358,16 @@ files may be entered into the list in an unexpected order. - The handling of national character sets is nonstandard as - well as insufficient for multibyte characters. It will - probably change in a later release. - There is no way (yet) to modify key bindings for the line editing commands. + If a line longer than the screen width is split (folded), + and a search matches text which straddles the split, the + matching text will not be highlighted (although it will + still be found by the search). + + If a search is done using the ! operator for text NOT match- + ing a pattern, the strings which do match the pattern are + highlighted. + COPYRIGHT @@ -1315,5 +1378,8 @@ - 20 + + + + 21 diff --exclude=*,v -r -U2 --entire less-205/less.nro less-227/less.nro --- less-205/less.nro Tue Aug 9 18:45:53 1994 +++ less-227/less.nro Tue Sep 13 00:48:42 1994 @@ -248,4 +248,13 @@ and crossing file boundaries. .PP +.IP "ESC-u" +Undo search highlighting. +Turn off highlighting of strings matching the current search pattern. +If highlighting is already off because of a previous ESC-u command, +turn highlighting back on. +Any search command will also turn highlighting back on. +(Highlighting can also be disabled by toggling the -F flag; +in that case search commands do not turn highlighting back on.) +.PP .IP ":e [filename]" Examine a new file. @@ -461,4 +470,10 @@ .I less will refuse to open non-regular files. +.IP -F +Normally, +.I less +will highlight all strings which match the current +search pattern, by displaying them in standout mode. +The -F flag suppresses this highlighting. .IP -h\fIn\fP Specifies a maximum number of lines to scroll backward. @@ -643,4 +658,9 @@ Sets tab stops every \fIn\fP positions. The default for \fIn\fP is 8. +.IP -X +Disables sending the termcap initialization and deinitialization strings +to the terminal. +This is sometimes desirable if the deinitialization string does +something unnecessary, like clearing the screen. .IP -y\fIn\fP Specifies a maximum number of lines to scroll forward. @@ -654,6 +674,14 @@ The default is one screenful. The z and w commands can also be used to change the window size. -The "z" may be omitted, as in "-\fIn\fP" for compatibility with +The "z" may be omitted for compatibility with .I more. +If the number +.I n +is negative, it indicates +.I n +lines less than the current screen size. +For example, if the screen is 24 lines, \fI-z-4\fP sets the +scrolling window to 20 lines. If the screen is resized to 40 lines, +the scrolling window automatically changes to 36 lines. .IP + If a command line option begins with \fB+\fP, @@ -680,4 +708,7 @@ a key does not exist on a particular keyboard. (The bracketed forms do not work in the MS-DOS version.) +Any of these special keys may be entered literally by preceding +it with a backslash. +A backslash itself may also be entered literally by entering two backslashes. .IP "LEFTARROW [ ESC-h ]" Move the cursor one space to the left. @@ -824,19 +855,22 @@ in ordinary text files (such as backspace and tab). .IP "binary characters" -cannot be displayed directly and are not expected to be found +should not be displayed directly and are not expected to be found in text files. .PP -By default, -.I less -uses the ASCII character set. -In the ASCII character set, characters -with values between 128 and 255 are treated as binary. -The LESSCHARSET environment variable may be used to select -another character set. -If it is set to the value "latin1", -the ISO 8859/1 character set is assumed. -Latin-1 is the same as ASCII, except characters between 161 and 255 are +A "character set" is simply a description of which characters are to +be considered normal, control, and binary. +The LESSCHARSET environment variable may be used to select a character set. +Possible values for LESSCHARSET are: +.IP ascii +The default character set. +BS, TAB, NL, CR, and formfeed are control characters, +all chars with values between 127 and 255 are binary, +and all others are normal. +.IP latin1 +Selects the ISO 8859/1 character set. +latin-1 is the same as ASCII, except characters between 161 and 255 are treated as normal characters. -The only valid values for LESSCHARSET currently are "ascii" and "latin1". +.IP dos +Selects a character set appropriate for MS-DOS. .PP In special cases, it may be desired to tailor @@ -862,20 +896,28 @@ LESSCHARSET to "latin1". .PP -Control and binary characters are displayed in blinking mode. +If neither LESSCHARSET nor LESSCHARDEF is set, +but your system supports the +.I setlocale +interface, +.I less +will use setlocale to determine the character set. +setlocale is controlled by setting the LANG or LC_CTYPE environment variables. +.PP +Control and binary characters are displayed in standout (reverse video). Each such character is displayed in caret notation if possible (e.g. ^A for control-A). Caret notation is used only if inverting the 0100 bit results in a normal printable character. -Otherwise, the character is displayed as an octal number preceded -by a backslash. -This octal format can be changed by -setting the LESSBINFMT environment variable -to a printf-style format string; the default is '\\%o'. -The blinking mode display of control and binary characters can -be changed or disabled by preceding the LESSBINFMT format -string with a "*" and one character to select the mode: -"*k" is blinking, "*d" is bold, "*u" is underlined, -and "*n" is normal (no special display attribute). +Otherwise, the character is displayed as a hex number in angle brackets. +This format can be changed by +setting the LESSBINFMT environment variable. +LESSBINFMT may begin with a "*" and one character to select +the display attribute: +"*k" is blinking, "*d" is bold, "*u" is underlined, "*s" is standout. +If LESSBINFMT does not begin with a "*", normal attribute is assumed. +The remainder of LESSBINFMT is a string which may include one +printf-style escape sequence (a % followed by x, X, o, d, etc.). For example, if LESSBINFMT is "*u[%x]", binary characters are displayed in underlined hexadecimal surrounded by brackets. +The default if no LESSBINFMT is specified is "*d<%X>". .SH "PROMPTS" @@ -1048,4 +1090,8 @@ .IP HOME Name of the user's home directory (used to find a .less file). +.IP LANG +Language for determining the character set. +.IP LC_CTYPE +Language for determining the character set. .IP LESS Flags which are passed to @@ -1089,9 +1135,13 @@ the new files may be entered into the list in an unexpected order. .PP -The handling of national character sets is nonstandard as well as -insufficient for multibyte characters. -It will probably change in a later release. -.PP There is no way (yet) to modify key bindings for the line editing commands. +.PP +If a line longer than the screen width is split (folded), +and a search matches text which straddles the split, +the matching text will not be highlighted (although it will still +be found by the search). +.PP +If a search is done using the ! operator for text NOT matching a pattern, +the strings which do match the pattern are highlighted. .SH COPYRIGHT diff --exclude=*,v -r -U2 --entire less-205/lesskey.c less-227/lesskey.c --- less-205/lesskey.c Tue Aug 2 20:41:41 1994 +++ less-227/lesskey.c Tue Sep 13 00:56:02 1994 @@ -47,9 +47,11 @@ * 2. A character preceded by ^ to specify a * control character (e.g. ^X means control-X). - * 3. Any character (other than an octal digit) preceded by - * a \ to specify the character itself (characters which - * must be preceded by \ include ^, \, and whitespace. - * 4. A backslash followed by one to three octal digits + * 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 @@ -129,4 +131,5 @@ "toggle-flag", A_OPT_TOGGLE, "toggle-option", A_OPT_TOGGLE, + "undo-hilite", A_UNDO_SEARCH, "version", A_VERSION, "visual", A_VISUAL, @@ -149,6 +152,9 @@ { case '\\': - if (*++p >= '0' && *p <= '7') + ++p; + switch (*p) { + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': /* * Parse an octal number. @@ -161,10 +167,27 @@ *pp = p; return (ch); + case 'b': + *pp = p+1; + return ('\r'); + case 'e': + *pp = p+1; + return (ESC); + case 'n': + *pp = p+1; + return ('\n'); + case 'r': + *pp = p+1; + return ('\r'); + case 't': + *pp = p+1; + return ('\t'); + default: + /* + * Backslash followed by any other char + * just means that char. + */ + *pp = p+1; + return (*p); } - /* - * Backslash followed by a char just means that char. - */ - *pp = p+1; - return (*p); case '^': /* @@ -178,4 +201,10 @@ } +usage() +{ + fprintf(stderr, "usage: lesskey [-o output] [input]\n"); + exit(1); +} + main(argc, argv) int argc; @@ -376,7 +405,2 @@ } -usage() -{ - fprintf(stderr, "usage: lesskey [-o output] [input]\n"); - exit(1); -} diff --exclude=*,v -r -U2 --entire less-205/lesskey.man less-227/lesskey.man --- less-205/lesskey.man Fri Jun 24 13:19:01 1994 +++ less-227/lesskey.man Tue Sep 13 00:57:24 1994 @@ -30,11 +30,13 @@ less action, from the list below. The characters in the "string" may appear literally, or be prefixed by a carat to - indicate a control key. A backslash may be used to cause - the following character to be taken literally. Characters + 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 b, e, n, r or t speci- + fies BACKSPACE, ESCAPE, NEWLINE, RETURN or TAB, respec- + tively. A backslash followed by any other character indi- + cates that character is to be taken literally. Characters which must be preceded by backslash include carat, space, - tab and the backslash itself. A backslash followed by one - to three octal digits may be used to specify a character by - its octal value. Blank lines and lines which start with a - pound sign (#) are ignored. + tab and the backslash itself. Blank lines and lines which + start with a pound sign (#) are ignored. An action may be followed by an extra string. This string @@ -56,10 +58,8 @@ \r forw-line - \n forw-line - e forw-line - Last change: 1 + 1 @@ -72,4 +72,6 @@ + \n forw-line + e forw-line j forw-line ^E forw-line @@ -94,5 +96,5 @@ b back-screen ^B back-screen - \33v back-screen + \ev back-screen z forw-window w back-window @@ -104,5 +106,5 @@ g goto-line < goto-line - \33< goto-line + \e< goto-line p percent % percent @@ -113,8 +115,8 @@ [ forw-bracket [] ] back-bracket [] - \33^F forw-bracket - \33^B back-bracket + \e^F forw-bracket + \e^B back-bracket G goto-end - \33> goto-end + \e> goto-end > goto-end P goto-end @@ -122,10 +124,8 @@ ^G status :f status - / forw-search - ? back-search - Last change: 2 + 2 @@ -138,10 +138,13 @@ - \33/ forw-search * - \33? back-search * + / forw-search + ? back-search + \e/ forw-search * + \e? back-search * n repeat-search - \33n repeat-search-all + \en repeat-search-all N reverse-search - \33N reverse-search-all + \eN reverse-search-all + \u undo-hilite m set-mark ' goto-mark @@ -168,5 +171,4 @@ :Q quit ZZ quit - \33\33 quit Commands specified by _l_e_s_s_k_e_y take precedence over the @@ -191,7 +193,5 @@ - - - Last change: 3 + 3 diff --exclude=*,v -r -U2 --entire less-205/lesskey.nro less-227/lesskey.nro --- less-205/lesskey.nro Fri Jun 24 12:38:35 1994 +++ less-227/lesskey.nro Tue Sep 13 00:56:49 1994 @@ -24,10 +24,12 @@ The characters in the "string" may appear literally, or be prefixed by a carat to indicate a control key. -A backslash may be used to cause the following character +A backslash followed by one to three octal digits may be used to +specify a character by its octal value. +A backslash followed by b, e, n, r or t specifies +BACKSPACE, ESCAPE, NEWLINE, RETURN or TAB, respectively. +A backslash followed by any other character indicates that character is to be taken literally. Characters which must be preceded by backslash include carat, space, tab and the backslash itself. -A backslash followed by one to three octal digits may be used to -specify a character by its octal value. Blank lines and lines which start with a pound sign (#) are ignored. .PP @@ -79,5 +81,5 @@ b back-screen ^B back-screen - \e33v back-screen + \eev back-screen z forw-window w back-window @@ -89,5 +91,5 @@ g goto-line < goto-line - \e33< goto-line + \ee< goto-line p percent % percent @@ -98,8 +100,8 @@ [ forw-bracket [] ] back-bracket [] - \e33^F forw-bracket - \e33^B back-bracket + \ee^F forw-bracket + \ee^B back-bracket G goto-end - \e33> goto-end + \ee> goto-end > goto-end P goto-end @@ -109,10 +111,11 @@ / forw-search ? back-search - \e33/ forw-search * - \e33? back-search * + \ee/ forw-search * + \ee? back-search * n repeat-search - \e33n repeat-search-all + \een repeat-search-all N reverse-search - \e33N reverse-search-all + \eeN reverse-search-all + \eu undo-hilite m set-mark ' goto-mark @@ -139,5 +142,4 @@ :Q quit ZZ quit - \e33\e33 quit .fi .sp diff --exclude=*,v -r -U2 --entire less-205/line.c less-227/line.c --- less-205/line.c Mon Jul 25 20:40:11 1994 +++ less-227/line.c Fri Sep 2 16:16:55 1994 @@ -57,4 +57,5 @@ 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; @@ -132,4 +133,5 @@ case AT_UNDERLINE: return (ul_s_width); case AT_BLINK: return (bl_s_width); + case AT_STANDOUT: return (so_s_width); } return (0); @@ -149,4 +151,5 @@ case AT_UNDERLINE: return (ul_e_width); case AT_BLINK: return (bl_e_width); + case AT_STANDOUT: return (so_e_width); } return (0); @@ -317,5 +320,5 @@ */ overstrike = 0; - if (c == linebuf[curr]) + if ((char)c == linebuf[curr]) STOREC(linebuf[curr], AT_BOLD); else if (c == '_') @@ -366,5 +369,5 @@ { /* - * Output in the (blinking) ^X format. + * Convert to printable representation. */ s = prchar(c); @@ -373,5 +376,5 @@ /* * Make sure we can get the entire representation - * the character on this line. + * of the character on this line. */ if (column + strlen(s) + @@ -405,4 +408,21 @@ (void) do_append(pendc); +#if HILITE_SEARCH + /* + * Modify the attribute for matched strings; do this before we + * add a newline so that '$' will match end of line properly. + * {{ If a matched string is broken at the end of the line, + * we won't mark it. This is difficlt to fix. }} + */ + { + extern int hilite_search; + if (hilite_search) + { + linebuf[curr] = '\0'; + hlsearch(linebuf, attr, AT_STANDOUT); + } + } +#endif + /* * Add a newline if necessary, diff --exclude=*,v -r -U2 --entire less-205/linenum.c less-227/linenum.c --- less-205/linenum.c Tue Aug 2 20:40:46 1994 +++ less-227/linenum.c Fri Aug 26 00:55:45 1994 @@ -334,5 +334,5 @@ */ cpos = forw_raw_line(cpos, (char **)NULL); - if (sigs || cpos == NULL_POSITION) + if (ABORT_SIGS() || cpos == NULL_POSITION) return (0); longish(); @@ -363,5 +363,5 @@ */ cpos = back_raw_line(cpos, (char **)NULL); - if (sigs || cpos == NULL_POSITION) + if (ABORT_SIGS() || cpos == NULL_POSITION) return (0); longish(); @@ -419,5 +419,5 @@ */ cpos = forw_raw_line(cpos, (char **)NULL); - if (sigs || cpos == NULL_POSITION) + if (ABORT_SIGS() || cpos == NULL_POSITION) return (NULL_POSITION); } @@ -435,5 +435,5 @@ */ cpos = back_raw_line(cpos, (char **)NULL); - if (sigs || cpos == NULL_POSITION) + if (ABORT_SIGS() || cpos == NULL_POSITION) return (NULL_POSITION); } diff --exclude=*,v -r -U2 --entire less-205/lsystem.c less-227/lsystem.c --- less-205/lsystem.c Tue Aug 2 20:44:02 1994 +++ less-227/lsystem.c Fri Sep 2 16:23:17 1994 @@ -166,5 +166,6 @@ * Reopen the current input file. */ - (void) edit_ifile(save_ifile); + if (edit_ifile(save_ifile)) + quit(-1); #if defined(SIGWINCH) || defined(SIGWIND) @@ -175,5 +176,5 @@ * so psignals() should be called soon after lsystem(). */ - winch(); + winch(0); #endif } @@ -303,5 +304,5 @@ #if defined(SIGWINCH) || defined(SIGWIND) /* {{ Probably don't need this here. }} */ - winch(); + winch(0); #endif return (0); diff --exclude=*,v -r -U2 --entire less-205/main.c less-227/main.c --- less-205/main.c Thu Jul 28 17:36:43 1994 +++ less-227/main.c Fri Sep 2 16:17:37 1994 @@ -41,5 +41,5 @@ public struct scrpos initial_scrpos; public int any_display = 0; -public int scroll; +public int wscroll; public char * progname; public int quitting; @@ -66,6 +66,6 @@ #if TAGS extern char * tagfile; -extern char * tagpattern; -extern int tagoption; +extern char * tagoption; +extern int jump_sline; #endif @@ -81,5 +81,4 @@ { IFILE ifile; - int nofiles; progname = *argv++; @@ -172,5 +171,5 @@ do { cat_file(); - } while (edit_next() == 0); + } while (edit_next(1) == 0); } quit(0); @@ -189,5 +188,5 @@ */ #if TAGS - if (tagoption) + if (tagoption != NULL) { /* @@ -202,24 +201,27 @@ quit(1); } + findtag(tagoption); if (tagfile == NULL) quit(1); + if (edit(tagfile)) /* Edit file which contains the tag */ + quit(1); /* - * tagfile has already been set to the name of the file to edit. - * Edit that file and search for the tag string in it. + * Search for the line which contains the tag. + * Set up initial_scrpos so we display that line. */ - if (edit(tagfile) || tagsearch()) + initial_scrpos.pos = tagsearch(); + if (initial_scrpos.pos == NULL_POSITION) quit(1); - nofiles = 0; + initial_scrpos.ln = jump_sline; } else #endif if (nifile() == 0) - nofiles = edit_stdin(); /* Edit standard input */ - else - nofiles = edit_first(); /* Edit first valid file in cmd line */ - - if (nofiles) { - quit(1); - /*NOTREACHED*/ + if (edit_stdin()) /* Edit standard input */ + quit(1); + } else + { + if (edit_first()) /* Edit first valid file in cmd line */ + quit(1); } @@ -308,5 +310,5 @@ save_status = status; quitting = 1; - edit((void*)NULL); + edit((char*)NULL); if (any_display) clear_bot(); diff --exclude=*,v -r -U2 --entire less-205/optfunc.c less-227/optfunc.c --- less-205/optfunc.c Mon Jul 25 20:40:12 1994 +++ less-227/optfunc.c Fri Sep 2 16:26:20 1994 @@ -64,8 +64,8 @@ #endif #if TAGS -public int tagoption = 0; +public char *tagoption = NULL; extern char *tagfile; -extern char *tagpattern; extern char *tags; +extern int jump_sline; #endif #if MSOFTC @@ -166,4 +166,5 @@ } + /*ARGSUSED*/ public void opt__L(type, s) @@ -210,20 +211,26 @@ { IFILE save_ifile; + POSITION pos; switch (type) { case INIT: - tagoption = 1; - findtag(s); + tagoption = s; + /* Do the rest in main() */ break; case TOGGLE: findtag(skipsp(s)); - if (tagfile != NULL) + if (tagfile == NULL) + break; + save_ifile = curr_ifile; + if (edit(tagfile)) + break; + if ((pos = tagsearch()) == NULL_POSITION) { - save_ifile = curr_ifile; - if (edit(tagfile) == 0) - if (tagsearch()) - (void) edit_ifile(save_ifile); + if (edit_ifile(save_ifile)) + quit(-1); + break; } + jump_loc(pos, jump_sline); break; case QUERY: @@ -346,4 +353,24 @@ } +/* + * 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; + } +} + #if MSOFTC /* @@ -446,4 +473,10 @@ break; case INIT: + /* + * This is "less -?". + * It rather ungracefully grabs control, + * does the initializations normally done in main, + * shows the help file and exits. + */ raw_mode(1); get_term(); diff --exclude=*,v -r -U2 --entire less-205/opttbl.c less-227/opttbl.c --- less-205/opttbl.c Mon Jul 25 20:40:12 1994 +++ less-227/opttbl.c Wed Aug 24 02:56:06 1994 @@ -61,4 +61,8 @@ 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 */ +#if HILITE_SEARCH +public int hilite_search; /* Highlight matched search patterns? */ +#endif /* @@ -107,4 +111,11 @@ NULL }, +#if HILITE_SEARCH + { 'F', BOOL|REPAINT, 1, &hilite_search, NULL, + "Don't highlight matches for previous search pattern", + "Highlight all matches for previous search pattern", + NULL + }, +#endif { 'h', NUMBER, -1, &back_scroll, NULL, "Backwards scroll limit: ", @@ -117,5 +128,5 @@ NULL }, - { 'i', BOOL, 0, &caseless, NULL, + { 'i', BOOL|REPAINT, 0, &caseless, opt_i, "Case is significant in searches", "Ignore case in searches", @@ -205,4 +216,9 @@ "Tab stops: ", "Tab stops every %d spaces", + NULL + }, + { 'X', BOOL|NO_TOGGLE, 0, &no_init, NULL, + "Send init/deinit strings to terminal", + "Don't use init/deinit strings", NULL }, diff --exclude=*,v -r -U2 --entire less-205/os.c less-227/os.c --- less-205/os.c Wed Aug 3 20:41:18 1994 +++ less-227/os.c Fri Aug 26 19:05:41 1994 @@ -38,4 +38,5 @@ */ +#include "less.h" #include #include @@ -43,5 +44,16 @@ #include #endif -#include "less.h" +#if HAVE_ERRNO_H +#include +#endif +#if HAVE_VALUES_H +#include +#endif + +#if HAVE_TIME_T +#define time_type time_t +#else +#define time_type long +#endif /* @@ -125,5 +137,5 @@ get_time() { - long t; + time_type t; time(&t); @@ -174,3 +186,50 @@ sprintf(m, "%s: %s", filename, p); return (m); +} + +/* + * Return the largest possible number that can fit in a long. + */ +#ifdef MAXLONG + static long +get_maxlong() +{ + return (MAXLONG); +} +#else + static long +get_maxlong() +{ + 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 + +/* + * Return the ratio of two longs, as a percentage. + */ + public int +percentage(num, den) + long num, den; +{ + static long maxlong100 = 0; + + if (maxlong100 == 0) + maxlong100 = get_maxlong() / 100; + if (num > maxlong100) + return (num / (den/100)); + else + return (100*num / den); } diff --exclude=*,v -r -U2 --entire less-205/output.c less-227/output.c --- less-205/output.c Thu Jul 28 17:20:30 1994 +++ less-227/output.c Fri Aug 26 00:56:05 1994 @@ -52,5 +52,5 @@ int curr_attr; - if (sigs) + if (ABORT_SIGS()) { /* @@ -77,4 +77,5 @@ case AT_BOLD: bo_exit(); break; case AT_BLINK: bl_exit(); break; + case AT_STANDOUT: so_exit(); break; } switch (a) @@ -83,4 +84,5 @@ case AT_BOLD: bo_enter(); break; case AT_BLINK: bl_enter(); break; + case AT_STANDOUT: so_enter(); break; } curr_attr = a; @@ -99,4 +101,5 @@ case AT_BOLD: bo_exit(); break; case AT_BLINK: bl_exit(); break; + case AT_STANDOUT: so_exit(); break; } } diff --exclude=*,v -r -U2 --entire less-205/position.c less-227/position.c --- less-205/position.c Mon Jul 25 20:40:13 1994 +++ less-227/position.c Thu Aug 25 15:20:55 1994 @@ -118,15 +118,28 @@ /* - * Allocate the position table. + * 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; } diff --exclude=*,v -r -U2 --entire less-205/prompt.c less-227/prompt.c --- less-205/prompt.c Mon Jul 25 20:40:13 1994 +++ less-227/prompt.c Thu Aug 25 01:20:51 1994 @@ -251,8 +251,5 @@ len = ch_length(); if (pos != NULL_POSITION && len > 0) - /* - * {{ This calculation may overflow! }} - */ - ap_int((int)(100*pos / len)); + ap_int(percentage(pos,len)); else ap_quest(); diff --exclude=*,v -r -U2 --entire less-205/regexp.c less-227/regexp.c --- less-205/regexp.c Wed Dec 31 19:00:00 1969 +++ less-227/regexp.c Thu Aug 25 00:35:09 1994 @@ -0,0 +1,1228 @@ +/* + * regcomp and regexec -- regsub and regerror are elsewhere + * + * Copyright (c) 1986 by University of Toronto. + * Written by Henry Spencer. Not derived from licensed software. + * + * Permission is granted to anyone to use this software for any + * purpose on any computer system, and to redistribute it freely, + * subject to the following restrictions: + * + * 1. The author is not responsible for the consequences of use of + * this software, no matter how awful, even if they arise + * from defects in it. + * + * 2. The origin of this software must not be misrepresented, either + * by explicit claim or by omission. + * + * 3. Altered versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + * + * Beware that some of this code is subtly aware of the way operator + * precedence is structured in regular expressions. Serious changes in + * regular-expression syntax might require a total rethink. + * + * *** NOTE: this code has been altered slightly for use in Tcl. *** + * Slightly modified by David MacKenzie to undo most of the changes for TCL. + */ + +#include +#include "regexp.h" +char *strchr(); + +/* + * The "internal use only" fields in regexp.h are present to pass info from + * compile to execute that permits the execute phase to run lots faster on + * simple cases. They are: + * + * regstart char that must begin a match; '\0' if none obvious + * reganch is the match anchored (at beginning-of-line only)? + * regmust string (pointer into program) that match must include, or NULL + * regmlen length of regmust string + * + * Regstart and reganch permit very fast decisions on suitable starting points + * for a match, cutting down the work a lot. Regmust permits fast rejection + * of lines that cannot possibly match. The regmust tests are costly enough + * that regcomp() supplies a regmust only if the r.e. contains something + * potentially expensive (at present, the only such thing detected is * or + + * at the start of the r.e., which can involve a lot of backup). Regmlen is + * supplied because the test in regexec() needs it and regcomp() is + * computing it anyway. + */ + +/* + * Structure for regexp "program". This is essentially a linear encoding + * of a nondeterministic finite-state machine (aka syntax charts or + * "railroad normal form" in parsing technology). Each node is an opcode + * plus a "next" pointer, possibly plus an operand. "Next" pointers of + * all nodes except BRANCH implement concatenation; a "next" pointer with + * a BRANCH on both ends of it is connecting two alternatives. (Here we + * have one of the subtle syntax dependencies: an individual BRANCH (as + * opposed to a collection of them) is never concatenated with anything + * because of operator precedence.) The operand of some types of node is + * a literal string; for others, it is a node leading into a sub-FSM. In + * particular, the operand of a BRANCH node is the first node of the branch. + * (NB this is *not* a tree structure: the tail of the branch connects + * to the thing following the set of BRANCHes.) The opcodes are: + */ + +/* definition number opnd? meaning */ +#define END 0 /* no End of program. */ +#define BOL 1 /* no Match "" at beginning of line. */ +#define EOL 2 /* no Match "" at end of line. */ +#define ANY 3 /* no Match any one character. */ +#define ANYOF 4 /* str Match any character in this string. */ +#define ANYBUT 5 /* str Match any character not in this string. */ +#define BRANCH 6 /* node Match this alternative, or the next... */ +#define BACK 7 /* no Match "", "next" ptr points backward. */ +#define EXACTLY 8 /* str Match this string. */ +#define NOTHING 9 /* no Match empty string. */ +#define STAR 10 /* node Match this (simple) thing 0 or more times. */ +#define PLUS 11 /* node Match this (simple) thing 1 or more times. */ +#define OPEN 20 /* no Mark this point in input as start of #n. */ + /* OPEN+1 is number 1, etc. */ +#define CLOSE 30 /* no Analogous to OPEN. */ + +/* + * Opcode notes: + * + * BRANCH The set of branches constituting a single choice are hooked + * together with their "next" pointers, since precedence prevents + * anything being concatenated to any individual branch. The + * "next" pointer of the last BRANCH in a choice points to the + * thing following the whole choice. This is also where the + * final "next" pointer of each individual branch points; each + * branch starts with the operand node of a BRANCH node. + * + * BACK Normal "next" pointers all implicitly point forward; BACK + * exists to make loop structures possible. + * + * STAR,PLUS '?', and complex '*' and '+', are implemented as circular + * BRANCH structures using BACK. Simple cases (one character + * per match) are implemented with STAR and PLUS for speed + * and to minimize recursive plunges. + * + * OPEN,CLOSE ...are numbered at compile time. + */ + +/* + * A node is one char of opcode followed by two chars of "next" pointer. + * "Next" pointers are stored as two 8-bit pieces, high order first. The + * value is a positive offset from the opcode of the node containing it. + * An operand, if any, simply follows the node. (Note that much of the + * code generation knows about this implicit relationship.) + * + * Using two bytes for the "next" pointer is vast overkill for most things, + * but allows patterns to get big without disasters. + */ +#define OP(p) (*(p)) +#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377)) +#define OPERAND(p) ((p) + 3) + +/* + * See regmagic.h for one further detail of program structure. + */ + + +/* + * Utility definitions. + */ +#ifndef CHARBITS +#define UCHARAT(p) ((int)*(unsigned char *)(p)) +#else +#define UCHARAT(p) ((int)*(p)&CHARBITS) +#endif + +#define FAIL(m) { regerror(m); return(NULL); } +#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?') +#define META "^$.[()|?+*\\" + +/* + * Flags to be passed up and down. + */ +#define HASWIDTH 01 /* Known never to match null string. */ +#define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */ +#define SPSTART 04 /* Starts with * or +. */ +#define WORST 0 /* Worst case. */ + +/* + * Global work variables for regcomp(). + */ +static char *regparse; /* Input-scan pointer. */ +static int regnpar; /* () count. */ +static char regdummy; +static char *regcode; /* Code-emit pointer; ®dummy = don't. */ +static long regsize; /* Code size. */ + +/* + * The first byte of the regexp internal "program" is actually this magic + * number; the start node begins in the second byte. + */ +#define MAGIC 0234 + + +/* + * Forward declarations for regcomp()'s friends. + */ +#ifndef STATIC +#define STATIC static +#endif +STATIC char *reg(); +STATIC char *regbranch(); +STATIC char *regpiece(); +STATIC char *regatom(); +STATIC char *regnode(); +STATIC char *regnext(); +STATIC void regc(); +STATIC void reginsert(); +STATIC void regtail(); +STATIC void regoptail(); +#ifdef STRCSPN +STATIC int strcspn(); +#endif + +/* + - regcomp - compile a regular expression into internal code + * + * We can't allocate space until we know how big the compiled form will be, + * but we can't compile it (and thus know how big it is) until we've got a + * place to put the code. So we cheat: we compile it twice, once with code + * generation turned off and size counting turned on, and once "for real". + * This also means that we don't allocate space until we are sure that the + * thing really will compile successfully, and we never have to move the + * code and thus invalidate pointers into it. (Note that it has to be in + * one piece because free() must be able to free it all.) + * + * Beware that the optimization-preparation code in here knows about some + * of the structure of the compiled regexp. + */ +regexp * +regcomp(exp) +char *exp; +{ + register regexp *r; + register char *scan; + register char *longest; + register int len; + int flags; + + if (exp == NULL) + FAIL("NULL argument"); + + /* First pass: determine size, legality. */ + regparse = exp; + regnpar = 1; + regsize = 0L; + regcode = ®dummy; + regc(MAGIC); + if (reg(0, &flags) == NULL) + return(NULL); + + /* Small enough for pointer-storage convention? */ + if (regsize >= 32767L) /* Probably could be 65535L. */ + FAIL("regexp too big"); + + /* Allocate space. */ + r = (regexp *)malloc(sizeof(regexp) + (unsigned)regsize); + if (r == NULL) + FAIL("out of space"); + + /* Second pass: emit code. */ + regparse = exp; + regnpar = 1; + regcode = r->program; + regc(MAGIC); + if (reg(0, &flags) == NULL) + return(NULL); + + /* Dig out information for optimizations. */ + r->regstart = '\0'; /* Worst-case defaults. */ + r->reganch = 0; + r->regmust = NULL; + r->regmlen = 0; + scan = r->program+1; /* First BRANCH. */ + if (OP(regnext(scan)) == END) { /* Only one top-level choice. */ + scan = OPERAND(scan); + + /* Starting-point info. */ + if (OP(scan) == EXACTLY) + r->regstart = *OPERAND(scan); + else if (OP(scan) == BOL) + r->reganch++; + + /* + * If there's something expensive in the r.e., find the + * longest literal string that must appear and make it the + * regmust. Resolve ties in favor of later strings, since + * the regstart check works with the beginning of the r.e. + * and avoiding duplication strengthens checking. Not a + * strong reason, but sufficient in the absence of others. + */ + if (flags&SPSTART) { + longest = NULL; + len = 0; + for (; scan != NULL; scan = regnext(scan)) + if (OP(scan) == EXACTLY && ((int) strlen(OPERAND(scan))) >= len) { + longest = OPERAND(scan); + len = strlen(OPERAND(scan)); + } + r->regmust = longest; + r->regmlen = len; + } + } + + return(r); +} + +/* + - reg - regular expression, i.e. main body or parenthesized thing + * + * Caller must absorb opening parenthesis. + * + * Combining parenthesis handling with the base level of regular expression + * is a trifle forced, but the need to tie the tails of the branches to what + * follows makes it hard to avoid. + */ +static char * +reg(paren, flagp) +int paren; /* Parenthesized? */ +int *flagp; +{ + register char *ret; + register char *br; + register char *ender; + register int parno = 0; + int flags; + + *flagp = HASWIDTH; /* Tentatively. */ + + /* Make an OPEN node, if parenthesized. */ + if (paren) { + if (regnpar >= NSUBEXP) + FAIL("too many ()"); + parno = regnpar; + regnpar++; + ret = regnode(OPEN+parno); + } else + ret = NULL; + + /* Pick up the branches, linking them together. */ + br = regbranch(&flags); + if (br == NULL) + return(NULL); + if (ret != NULL) + regtail(ret, br); /* OPEN -> first. */ + else + ret = br; + if (!(flags&HASWIDTH)) + *flagp &= ~HASWIDTH; + *flagp |= flags&SPSTART; + while (*regparse == '|') { + regparse++; + br = regbranch(&flags); + if (br == NULL) + return(NULL); + regtail(ret, br); /* BRANCH -> BRANCH. */ + if (!(flags&HASWIDTH)) + *flagp &= ~HASWIDTH; + *flagp |= flags&SPSTART; + } + + /* Make a closing node, and hook it on the end. */ + ender = regnode((paren) ? CLOSE+parno : END); + regtail(ret, ender); + + /* Hook the tails of the branches to the closing node. */ + for (br = ret; br != NULL; br = regnext(br)) + regoptail(br, ender); + + /* Check for proper termination. */ + if (paren && *regparse++ != ')') { + FAIL("unmatched ()"); + } else if (!paren && *regparse != '\0') { + if (*regparse == ')') { + FAIL("unmatched ()"); + } else + FAIL("junk on end"); /* "Can't happen". */ + /* NOTREACHED */ + } + + return(ret); +} + +/* + - regbranch - one alternative of an | operator + * + * Implements the concatenation operator. + */ +static char * +regbranch(flagp) +int *flagp; +{ + register char *ret; + register char *chain; + register char *latest; + int flags; + + *flagp = WORST; /* Tentatively. */ + + ret = regnode(BRANCH); + chain = NULL; + while (*regparse != '\0' && *regparse != '|' && *regparse != ')') { + latest = regpiece(&flags); + if (latest == NULL) + return(NULL); + *flagp |= flags&HASWIDTH; + if (chain == NULL) /* First piece. */ + *flagp |= flags&SPSTART; + else + regtail(chain, latest); + chain = latest; + } + if (chain == NULL) /* Loop ran zero times. */ + (void) regnode(NOTHING); + + return(ret); +} + +/* + - regpiece - something followed by possible [*+?] + * + * Note that the branching code sequences used for ? and the general cases + * of * and + are somewhat optimized: they use the same NOTHING node as + * both the endmarker for their branch list and the body of the last branch. + * It might seem that this node could be dispensed with entirely, but the + * endmarker role is not redundant. + */ +static char * +regpiece(flagp) +int *flagp; +{ + register char *ret; + register char op; + register char *next; + int flags; + + ret = regatom(&flags); + if (ret == NULL) + return(NULL); + + op = *regparse; + if (!ISMULT(op)) { + *flagp = flags; + return(ret); + } + + if (!(flags&HASWIDTH) && op != '?') + FAIL("*+ operand could be empty"); + *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH); + + if (op == '*' && (flags&SIMPLE)) + reginsert(STAR, ret); + else if (op == '*') { + /* Emit x* as (x&|), where & means "self". */ + reginsert(BRANCH, ret); /* Either x */ + regoptail(ret, regnode(BACK)); /* and loop */ + regoptail(ret, ret); /* back */ + regtail(ret, regnode(BRANCH)); /* or */ + regtail(ret, regnode(NOTHING)); /* null. */ + } else if (op == '+' && (flags&SIMPLE)) + reginsert(PLUS, ret); + else if (op == '+') { + /* Emit x+ as x(&|), where & means "self". */ + next = regnode(BRANCH); /* Either */ + regtail(ret, next); + regtail(regnode(BACK), ret); /* loop back */ + regtail(next, regnode(BRANCH)); /* or */ + regtail(ret, regnode(NOTHING)); /* null. */ + } else if (op == '?') { + /* Emit x? as (x|) */ + reginsert(BRANCH, ret); /* Either x */ + regtail(ret, regnode(BRANCH)); /* or */ + next = regnode(NOTHING); /* null. */ + regtail(ret, next); + regoptail(ret, next); + } + regparse++; + if (ISMULT(*regparse)) + FAIL("nested *?+"); + + return(ret); +} + +/* + - regatom - the lowest level + * + * Optimization: gobbles an entire sequence of ordinary characters so that + * it can turn them into a single node, which is smaller to store and + * faster to run. Backslashed characters are exceptions, each becoming a + * separate node; the code is simpler that way and it's not worth fixing. + */ +static char * +regatom(flagp) +int *flagp; +{ + register char *ret; + int flags; + + *flagp = WORST; /* Tentatively. */ + + switch (*regparse++) { + case '^': + ret = regnode(BOL); + break; + case '$': + ret = regnode(EOL); + break; + case '.': + ret = regnode(ANY); + *flagp |= HASWIDTH|SIMPLE; + break; + case '[': { + register int clss; + register int classend; + + if (*regparse == '^') { /* Complement of range. */ + ret = regnode(ANYBUT); + regparse++; + } else + ret = regnode(ANYOF); + if (*regparse == ']' || *regparse == '-') + regc(*regparse++); + while (*regparse != '\0' && *regparse != ']') { + if (*regparse == '-') { + regparse++; + if (*regparse == ']' || *regparse == '\0') + regc('-'); + else { + clss = UCHARAT(regparse-2)+1; + classend = UCHARAT(regparse); + if (clss > classend+1) + FAIL("invalid [] range"); + for (; clss <= classend; clss++) + regc(clss); + regparse++; + } + } else + regc(*regparse++); + } + regc('\0'); + if (*regparse != ']') + FAIL("unmatched []"); + regparse++; + *flagp |= HASWIDTH|SIMPLE; + } + break; + case '(': + ret = reg(1, &flags); + if (ret == NULL) + return(NULL); + *flagp |= flags&(HASWIDTH|SPSTART); + break; + case '\0': + case '|': + case ')': + FAIL("internal urp"); /* Supposed to be caught earlier. */ + /* NOTREACHED */ + break; + case '?': + case '+': + case '*': + FAIL("?+* follows nothing"); + /* NOTREACHED */ + break; + case '\\': + if (*regparse == '\0') + FAIL("trailing \\"); + ret = regnode(EXACTLY); + regc(*regparse++); + regc('\0'); + *flagp |= HASWIDTH|SIMPLE; + break; + default: { + register int len; + register char ender; + + regparse--; + len = strcspn(regparse, META); + if (len <= 0) + FAIL("internal disaster"); + ender = *(regparse+len); + if (len > 1 && ISMULT(ender)) + len--; /* Back off clear of ?+* operand. */ + *flagp |= HASWIDTH; + if (len == 1) + *flagp |= SIMPLE; + ret = regnode(EXACTLY); + while (len > 0) { + regc(*regparse++); + len--; + } + regc('\0'); + } + break; + } + + return(ret); +} + +/* + - regnode - emit a node + */ +static char * /* Location. */ +regnode(op) +char op; +{ + register char *ret; + register char *ptr; + + ret = regcode; + if (ret == ®dummy) { + regsize += 3; + return(ret); + } + + ptr = ret; + *ptr++ = op; + *ptr++ = '\0'; /* Null "next" pointer. */ + *ptr++ = '\0'; + regcode = ptr; + + return(ret); +} + +/* + - regc - emit (if appropriate) a byte of code + */ +static void +regc(b) +char b; +{ + if (regcode != ®dummy) + *regcode++ = b; + else + regsize++; +} + +/* + - reginsert - insert an operator in front of already-emitted operand + * + * Means relocating the operand. + */ +static void +reginsert(op, opnd) +char op; +char *opnd; +{ + register char *src; + register char *dst; + register char *place; + + if (regcode == ®dummy) { + regsize += 3; + return; + } + + src = regcode; + regcode += 3; + dst = regcode; + while (src > opnd) + *--dst = *--src; + + place = opnd; /* Op node, where operand used to be. */ + *place++ = op; + *place++ = '\0'; + *place++ = '\0'; +} + +/* + - regtail - set the next-pointer at the end of a node chain + */ +static void +regtail(p, val) +char *p; +char *val; +{ + register char *scan; + register char *temp; + register int offset; + + if (p == ®dummy) + return; + + /* Find last node. */ + scan = p; + for (;;) { + temp = regnext(scan); + if (temp == NULL) + break; + scan = temp; + } + + if (OP(scan) == BACK) + offset = scan - val; + else + offset = val - scan; + *(scan+1) = (offset>>8)&0377; + *(scan+2) = offset&0377; +} + +/* + - regoptail - regtail on operand of first argument; nop if operandless + */ +static void +regoptail(p, val) +char *p; +char *val; +{ + /* "Operandless" and "op != BRANCH" are synonymous in practice. */ + if (p == NULL || p == ®dummy || OP(p) != BRANCH) + return; + regtail(OPERAND(p), val); +} + +/* + * regexec and friends + */ + +/* + * Global work variables for regexec(). + */ +static char *reginput; /* String-input pointer. */ +static char *regbol; /* Beginning of input, for ^ check. */ +static char **regstartp; /* Pointer to startp array. */ +static char **regendp; /* Ditto for endp. */ + +/* + * Forwards. + */ +STATIC int regtry(); +STATIC int regmatch(); +STATIC int regrepeat(); + +#ifdef DEBUG +int regnarrate = 0; +void regdump(); +STATIC char *regprop(); +#endif + +/* + - regexec - match a regexp against a string + */ +int +regexec(prog, string) +register regexp *prog; +register char *string; +{ + register char *s; + + /* Be paranoid... */ + if (prog == NULL || string == NULL) { + regerror("NULL parameter"); + return(0); + } + + /* Check validity of program. */ + if (UCHARAT(prog->program) != MAGIC) { + regerror("corrupted program"); + return(0); + } + + /* If there is a "must appear" string, look for it. */ + if (prog->regmust != NULL) { + s = string; + while ((s = strchr(s, prog->regmust[0])) != NULL) { + if (strncmp(s, prog->regmust, prog->regmlen) == 0) + break; /* Found it. */ + s++; + } + if (s == NULL) /* Not present. */ + return(0); + } + + /* Mark beginning of line for ^ . */ + regbol = string; + + /* Simplest case: anchored match need be tried only once. */ + if (prog->reganch) + return(regtry(prog, string)); + + /* Messy cases: unanchored match. */ + s = string; + if (prog->regstart != '\0') + /* We know what char it must start with. */ + while ((s = strchr(s, prog->regstart)) != NULL) { + if (regtry(prog, s)) + return(1); + s++; + } + else + /* We don't -- general case. */ + do { + if (regtry(prog, s)) + return(1); + } while (*s++ != '\0'); + + /* Failure. */ + return(0); +} + +/* + - regtry - try match at specific point + */ +static int /* 0 failure, 1 success */ +regtry(prog, string) +regexp *prog; +char *string; +{ + register int i; + register char **sp; + register char **ep; + + reginput = string; + regstartp = prog->startp; + regendp = prog->endp; + + sp = prog->startp; + ep = prog->endp; + for (i = NSUBEXP; i > 0; i--) { + *sp++ = NULL; + *ep++ = NULL; + } + if (regmatch(prog->program + 1)) { + prog->startp[0] = string; + prog->endp[0] = reginput; + return(1); + } else + return(0); +} + +/* + - regmatch - main matching routine + * + * Conceptually the strategy is simple: check to see whether the current + * node matches, call self recursively to see whether the rest matches, + * and then act accordingly. In practice we make some effort to avoid + * recursion, in particular by going through "ordinary" nodes (that don't + * need to know whether the rest of the match failed) by a loop instead of + * by recursion. + */ +static int /* 0 failure, 1 success */ +regmatch(prog) +char *prog; +{ + register char *scan; /* Current node. */ + char *next; /* Next node. */ + + scan = prog; +#ifdef DEBUG + if (scan != NULL && regnarrate) + fprintf(stderr, "%s(\n", regprop(scan)); +#endif + while (scan != NULL) { +#ifdef DEBUG + if (regnarrate) + fprintf(stderr, "%s...\n", regprop(scan)); +#endif + next = regnext(scan); + + switch (OP(scan)) { + case BOL: + if (reginput != regbol) + return(0); + break; + case EOL: + if (*reginput != '\0') + return(0); + break; + case ANY: + if (*reginput == '\0') + return(0); + reginput++; + break; + case EXACTLY: { + register int len; + register char *opnd; + + opnd = OPERAND(scan); + /* Inline the first character, for speed. */ + if (*opnd != *reginput) + return(0); + len = strlen(opnd); + if (len > 1 && strncmp(opnd, reginput, len) != 0) + return(0); + reginput += len; + } + break; + case ANYOF: + if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL) + return(0); + reginput++; + break; + case ANYBUT: + if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL) + return(0); + reginput++; + break; + case NOTHING: + break; + case BACK: + break; + case OPEN+1: + case OPEN+2: + case OPEN+3: + case OPEN+4: + case OPEN+5: + case OPEN+6: + case OPEN+7: + case OPEN+8: + case OPEN+9: { + register int no; + register char *save; + + no = OP(scan) - OPEN; + save = reginput; + + if (regmatch(next)) { + /* + * Don't set startp if some later + * invocation of the same parentheses + * already has. + */ + if (regstartp[no] == NULL) + regstartp[no] = save; + return(1); + } else + return(0); + } + /* NOTREACHED */ + break; + case CLOSE+1: + case CLOSE+2: + case CLOSE+3: + case CLOSE+4: + case CLOSE+5: + case CLOSE+6: + case CLOSE+7: + case CLOSE+8: + case CLOSE+9: { + register int no; + register char *save; + + no = OP(scan) - CLOSE; + save = reginput; + + if (regmatch(next)) { + /* + * Don't set endp if some later + * invocation of the same parentheses + * already has. + */ + if (regendp[no] == NULL) + regendp[no] = save; + return(1); + } else + return(0); + } + /* NOTREACHED */ + break; + case BRANCH: { + register char *save; + + if (OP(next) != BRANCH) /* No choice. */ + next = OPERAND(scan); /* Avoid recursion. */ + else { + do { + save = reginput; + if (regmatch(OPERAND(scan))) + return(1); + reginput = save; + scan = regnext(scan); + } while (scan != NULL && OP(scan) == BRANCH); + return(0); + /* NOTREACHED */ + } + } + /* NOTREACHED */ + break; + case STAR: + case PLUS: { + register char nextch; + register int no; + register char *save; + register int min; + + /* + * Lookahead to avoid useless match attempts + * when we know what character comes next. + */ + nextch = '\0'; + if (OP(next) == EXACTLY) + nextch = *OPERAND(next); + min = (OP(scan) == STAR) ? 0 : 1; + save = reginput; + no = regrepeat(OPERAND(scan)); + while (no >= min) { + /* If it could work, try it. */ + if (nextch == '\0' || *reginput == nextch) + if (regmatch(next)) + return(1); + /* Couldn't or didn't -- back up. */ + no--; + reginput = save + no; + } + return(0); + } + /* NOTREACHED */ + break; + case END: + return(1); /* Success! */ + /* NOTREACHED */ + break; + default: + regerror("memory corruption"); + return(0); + /* NOTREACHED */ + break; + } + + scan = next; + } + + /* + * We get here only if there's trouble -- normally "case END" is + * the terminating point. + */ + regerror("corrupted pointers"); + return(0); +} + +/* + - regrepeat - repeatedly match something simple, report how many + */ +static int +regrepeat(p) +char *p; +{ + register int count = 0; + register char *scan; + register char *opnd; + + scan = reginput; + opnd = OPERAND(p); + switch (OP(p)) { + case ANY: + count = strlen(scan); + scan += count; + break; + case EXACTLY: + while (*opnd == *scan) { + count++; + scan++; + } + break; + case ANYOF: + while (*scan != '\0' && strchr(opnd, *scan) != NULL) { + count++; + scan++; + } + break; + case ANYBUT: + while (*scan != '\0' && strchr(opnd, *scan) == NULL) { + count++; + scan++; + } + break; + default: /* Oh dear. Called inappropriately. */ + regerror("internal foulup"); + count = 0; /* Best compromise. */ + break; + } + reginput = scan; + + return(count); +} + +/* + - regnext - dig the "next" pointer out of a node + */ +static char * +regnext(p) +register char *p; +{ + register int offset; + + if (p == ®dummy) + return(NULL); + + offset = NEXT(p); + if (offset == 0) + return(NULL); + + if (OP(p) == BACK) + return(p-offset); + else + return(p+offset); +} + +#ifdef DEBUG + +STATIC char *regprop(); + +/* + - regdump - dump a regexp onto stdout in vaguely comprehensible form + */ +void +regdump(r) +regexp *r; +{ + register char *s; + register char op = EXACTLY; /* Arbitrary non-END op. */ + register char *next; + + + s = r->program + 1; + while (op != END) { /* While that wasn't END last time... */ + op = OP(s); + printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */ + next = regnext(s); + if (next == NULL) /* Next ptr. */ + printf("(0)"); + else + printf("(%d)", (s-r->program)+(next-s)); + s += 3; + if (op == ANYOF || op == ANYBUT || op == EXACTLY) { + /* Literal string, where present. */ + while (*s != '\0') { + putchar(*s); + s++; + } + s++; + } + putchar('\n'); + } + + /* Header fields of interest. */ + if (r->regstart != '\0') + printf("start `%c' ", r->regstart); + if (r->reganch) + printf("anchored "); + if (r->regmust != NULL) + printf("must have \"%s\"", r->regmust); + printf("\n"); +} + +/* + - regprop - printable representation of opcode + */ +static char * +regprop(op) +char *op; +{ + register char *p; + static char buf[50]; + + (void) strcpy(buf, ":"); + + switch (OP(op)) { + case BOL: + p = "BOL"; + break; + case EOL: + p = "EOL"; + break; + case ANY: + p = "ANY"; + break; + case ANYOF: + p = "ANYOF"; + break; + case ANYBUT: + p = "ANYBUT"; + break; + case BRANCH: + p = "BRANCH"; + break; + case EXACTLY: + p = "EXACTLY"; + break; + case NOTHING: + p = "NOTHING"; + break; + case BACK: + p = "BACK"; + break; + case END: + p = "END"; + break; + case OPEN+1: + case OPEN+2: + case OPEN+3: + case OPEN+4: + case OPEN+5: + case OPEN+6: + case OPEN+7: + case OPEN+8: + case OPEN+9: + sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN); + p = NULL; + break; + case CLOSE+1: + case CLOSE+2: + case CLOSE+3: + case CLOSE+4: + case CLOSE+5: + case CLOSE+6: + case CLOSE+7: + case CLOSE+8: + case CLOSE+9: + sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE); + p = NULL; + break; + case STAR: + p = "STAR"; + break; + case PLUS: + p = "PLUS"; + break; + default: + regerror("corrupted opcode"); + break; + } + if (p != NULL) + (void) strcat(buf, p); + return(buf); +} +#endif + +/* + * The following is provided for those people who do not have strcspn() in + * their C libraries. They should get off their butts and do something + * about it; at least one public-domain implementation of those (highly + * useful) string routines has been published on Usenet. + */ +#ifdef STRCSPN +/* + * strcspn - find length of initial segment of s1 consisting entirely + * of characters not from s2 + */ + +static int +strcspn(s1, s2) +char *s1; +char *s2; +{ + register char *scan1; + register char *scan2; + register int count; + + count = 0; + for (scan1 = s1; *scan1 != '\0'; scan1++) { + for (scan2 = s2; *scan2 != '\0';) /* ++ moved down. */ + if (*scan1 == *scan2++) + return(count); + count++; + } + return(count); +} +#endif diff --exclude=*,v -r -U2 --entire less-205/regexp.h less-227/regexp.h --- less-205/regexp.h Wed Dec 31 19:00:00 1969 +++ less-227/regexp.h Thu Aug 25 00:35:09 1994 @@ -0,0 +1,33 @@ +/* + * 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 void regsub _ANSI_ARGS_((regexp *prog, char *source, char *dest)); +extern void regerror _ANSI_ARGS_((char *msg)); + +#endif /* REGEXP */ diff --exclude=*,v -r -U2 --entire less-205/screen.c less-227/screen.c --- less-205/screen.c Fri Aug 5 16:40:30 1994 +++ less-227/screen.c Fri Aug 26 00:38:14 1994 @@ -30,5 +30,5 @@ * Uses termcap to be as terminal-independent as possible. * - * {{ Someday this should be rewritten to use curses. }} + * {{ Maybe someday this should be rewritten to use curses or terminfo. }} */ @@ -38,4 +38,7 @@ #if HAVE_TERMIOS_H #include +#if HAVE_SYS_IOCTL_H && !defined(TIOCGWINSZ) +#include +#endif #else #if HAVE_TERMIO_H @@ -43,10 +46,9 @@ #else #include -#if defined(TIOCGWINSZ) || defined(TCGETA) || defined(TIOCGETP) || defined(WIOCGETD) +#if HAVE_SYS_IOCTL_H && (defined(TIOCGWINSZ) || defined(TCGETA) || defined(TIOCGETP) || defined(WIOCGETD)) #include #endif #endif #endif - #if HAVE_TERMCAP_H #include @@ -117,8 +119,9 @@ * These two variables are sometimes defined in, * and needed by, the termcap library. - * It may be necessary on some systems to declare them extern here. */ -/*extern*/ short ospeed; /* Terminal output baud rate */ -/*extern*/ char PC; /* Pad character */ +#if MUST_DEFINE_OSPEED +extern short ospeed; /* Terminal output baud rate */ +extern char PC; /* Pad character */ +#endif extern int quiet; /* If VERY_QUIET, use visual bell for bell */ @@ -126,4 +129,5 @@ extern int back_scroll; extern int swindow; +extern int no_init; extern char *tgetstr(); extern char *tgoto(); @@ -165,5 +169,7 @@ */ save_term = s; +#if HAVE_OSPEED ospeed = cfgetospeed(&s); +#endif erase_char = s.c_cc[VERASE]; kill_char = s.c_cc[VKILL]; @@ -172,15 +178,56 @@ * Set the modes to the way we want them. */ - s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL); -#ifdef OXTABS - s.c_oflag |= (OPOST|ONLCR|OXTABS); + s.c_lflag &= ~(0 +#ifdef ICANON + | ICANON +#endif +#ifdef ECHO + | ECHO +#endif +#ifdef ECHOE + | ECHOE +#endif +#ifdef ECHOK + | ECHOK +#endif +#if ECHONL + | ECHONL +#endif + ); + + s.c_oflag |= (0 +#ifdef XTABS + | XTABS #else - s.c_oflag |= (OPOST|ONLCR|TAB3); +#ifdef TAB3 + | TAB3 +#else +#ifdef OXTABS + | OXTABS +#endif +#endif +#endif +#ifdef OPOST + | OPOST #endif +#ifdef ONLCR + | ONLCR +#endif + ); + + s.c_oflag &= ~(0 #ifdef ONOEOT - s.c_oflag &= ~(ONOEOT); -#else - s.c_oflag &= ~(OCRNL|ONOCR|ONLRET); + | ONOEOT +#endif +#ifdef OCRNL + | OCRNL #endif +#ifdef ONOCR + | ONOCR +#endif +#ifdef ONLRET + | ONLRET +#endif + ); s.c_cc[VMIN] = 1; s.c_cc[VTIME] = 0; @@ -211,5 +258,7 @@ */ save_term = s; +#if HAVE_OSPEED ospeed = s.c_cflag & CBAUD; +#endif erase_char = s.c_cc[VERASE]; kill_char = s.c_cc[VKILL]; @@ -248,5 +297,7 @@ */ save_term = s; +#if HAVE_OSPEED ospeed = s.sg_ospeed; +#endif erase_char = s.sg_erase; kill_char = s.sg_kill; @@ -405,5 +456,6 @@ /* UP ARROW */ s = tbuf; - if ((s = tgetstr("ku", &sp)) != NULL) { + if ((s = tgetstr("ku", &sp)) != NULL) + { add_table(s, EC_UP, edittable, sz_edittable); add_table(s, A_B_LINE, kcmdtable, sz_kcmdtable); @@ -412,5 +464,6 @@ /* DOWN ARROW */ s = tbuf; - if ((s = tgetstr("kd", &sp)) != NULL) { + if ((s = tgetstr("kd", &sp)) != NULL) + { add_table(s, EC_DOWN, edittable, sz_edittable); add_table(s, A_F_LINE, kcmdtable, sz_kcmdtable); @@ -419,5 +472,6 @@ /* PAGE UP */ s = tbuf; - if ((s = tgetstr("kP", &sp)) != NULL) { + if ((s = tgetstr("kP", &sp)) != NULL) + { add_table(s, A_B_SCREEN, kcmdtable, sz_kcmdtable); } @@ -425,5 +479,6 @@ /* PAGE DOWN */ s = tbuf; - if ((s = tgetstr("kN", &sp)) != NULL) { + if ((s = tgetstr("kN", &sp)) != NULL) + { add_table(s, A_F_SCREEN, kcmdtable, sz_kcmdtable); } @@ -431,5 +486,6 @@ /* HOME */ sp = tbuf; - if ((s = tgetstr("kh", &sp)) != NULL) { + if ((s = tgetstr("kh", &sp)) != NULL) + { add_table(s, EC_HOME, edittable, sz_edittable); } @@ -437,5 +493,6 @@ /* END */ sp = tbuf; - if ((s = tgetstr("@7", &sp)) != NULL) { + if ((s = tgetstr("@7", &sp)) != NULL) + { add_table(s, EC_END, edittable, sz_edittable); } @@ -443,5 +500,7 @@ /* DELETE */ sp = tbuf+1; - if ((s = tgetstr("kD", &sp)) == NULL) { + if ((s = tgetstr("kD", &sp)) == NULL) + { + /* Use DEL (\177) if no "kD" termcap. */ tbuf[1] = '\177'; tbuf[2] = '\0'; @@ -519,7 +578,9 @@ sp = sbuf; +#if HAVE_OSPEED sc_pad = tgetstr("pc", &sp); if (sc_pad != NULL) PC = *sc_pad; +#endif sc_s_keypad = tgetstr("ks", &sp); @@ -749,4 +810,6 @@ init() { + if (no_init) + return; tputs(sc_init, sc_height, putchr); tputs(sc_s_keypad, sc_height, putchr); @@ -760,4 +823,6 @@ deinit() { + if (no_init) + return; if (!init_done) return; diff --exclude=*,v -r -U2 --entire less-205/search.c less-227/search.c --- less-205/search.c Thu Jul 28 17:38:17 1994 +++ less-227/search.c Mon Sep 19 12:39:59 1994 @@ -32,10 +32,23 @@ #include "less.h" #include "position.h" + #if HAVE_POSIX_REGCOMP #include #endif +#if HAVE_RE_COMP +char *re_comp(); +int re_exec(); +#endif +#if HAVE_REGCMP +char *regcmp(); +char *regex(); +extern char *__loc1; +#endif #if HAVE_V8_REGCOMP #include "regexp.h" #endif +#if NO_REGEX +static int match(); +#endif extern int sigs; @@ -45,103 +58,141 @@ extern int jump_sline; extern int bs_mode; +#if HILITE_SEARCH +extern int hilite_search; +extern int screen_trashed; +#endif +/* + * These are the static variables that represent the "remembered" + * search pattern. + */ +#if HAVE_POSIX_REGCOMP +static regex_t *regpattern = NULL; +#endif +#if HAVE_RE_COMP +int re_pattern = 0; +#endif +#if HAVE_REGCMP +static char *cpattern = NULL; +#endif +#if HAVE_V8_REGCOMP +static struct regexp *regpattern = NULL; +#endif +#if NO_REGEX +static char *last_pattern = NULL; +#endif + +static int is_caseless; +static int is_ucase_pattern; +#if HILITE_SEARCH +static int no_hilite_search; +#endif /* - * Search for the n-th occurrence of a specified pattern, - * either forward or backward. - * Return the number of matches not yet found in this file - * (that is, n minus the number of matches found). - * Return -1 if the search should be aborted. - * Caller may continue the search in another file - * if less than n matches are found in this file. + * Convert text. Perform one or more of these transformations: */ - public int -search(search_type, pattern, n) - int search_type; - char *pattern; - int n; +#define CVT_TO_LC 01 /* Convert upper-case to lower-case */ +#define CVT_BS 02 /* Do backspace processing */ + + static void +cvt_text(odst, osrc, ops) + char *odst; + char *osrc; + int ops; +{ + register char *dst; + register char *src; + + for (src = osrc, dst = odst; *src != '\0'; src++, dst++) + { + if ((ops & CVT_TO_LC) && *src >= 'A' && *src <= 'Z') + /* Convert uppercase to lowercase. */ + *dst = *src + 'a' - 'A'; + else if ((ops & CVT_BS) && *src == '\b' && dst > odst) + /* Delete BS and preceding char. */ + dst -= 2; + else + /* Just copy. */ + *dst = *src; + } + *dst = '\0'; +} + +/* + * Are there any uppercase letters in this string? + */ + static int +is_ucase(s) + char *s; { - POSITION pos, linepos, oldpos; register char *p; - register char *q; - register int goforw; - register int want_match; - char *line; - int linenum; - int line_match; - static int is_caseless; + + for (p = s; *p != '\0'; p++) + if (*p >= 'A' && *p <= 'Z') + return (1); + return (0); +} + +/* + * Is there a previous (remembered) search pattern? + */ + static int +prev_pattern() +{ #if HAVE_POSIX_REGCOMP - static regex_t *regpattern = NULL; + return (regpattern != NULL); #endif #if HAVE_RE_COMP - char *re_comp(); - PARG parg; + return (re_pattern != 0); #endif #if HAVE_REGCMP - char *regcmp(); - static char *cpattern = NULL; + return (cpattern != NULL); #endif #if HAVE_V8_REGCOMP - static struct regexp *regpattern = NULL; + return (regpattern != NULL); #endif #if NO_REGEX - static char lpbuf[100]; - static char *last_pattern = NULL; - static int match(); + return (last_pattern != NULL); #endif +} - /* - * Extract flags and type of search. - */ - goforw = (SRCH_DIR(search_type) == SRCH_FORW); - want_match = !(search_type & SRCH_NOMATCH); - - if (pattern != NULL && *pattern != '\0' && (is_caseless = caseless)) +/* + * Undo search string highlighting. + */ + public void +undo_search() +{ + if (!prev_pattern()) { - /* - * Search will ignore case, unless - * there are any uppercase letters in the pattern. - */ - for (p = pattern; *p != '\0'; p++) - if (*p >= 'A' && *p <= 'Z') - { - is_caseless = 0; - break; - } + error("No previous regular expression", NULL_PARG); + return; } +#if HILITE_SEARCH + no_hilite_search = !no_hilite_search; + screen_trashed = 1; +#endif +} + +/* + * Compile a pattern in preparation for a pattern match. + */ + static int +compile_pattern(pattern) + char *pattern; +{ #if HAVE_POSIX_REGCOMP - if (pattern == NULL || *pattern == '\0') + regex_t *s = (regex_t *) ecalloc(1, sizeof(regex_t)); + if (regcomp(s, pattern, 0)) { - /* - * A null pattern means use the previous pattern. - * The compiled previous pattern is in regpattern, - * so just use it. - */ - if (regpattern == NULL) - { - error("No previous regular expression", NULL_PARG); - return (-1); - } - } else - { - /* - * Otherwise compile the given pattern. - */ - if (regpattern == NULL) - regpattern = (regex_t *) ecalloc(1, sizeof(regex_t)); - else - regfree(regpattern); - if (regcomp(regpattern, pattern, 0)) - { - error("Invalid pattern", NULL_PARG); - return (-1); - } + free(s); + error("Invalid pattern", NULL_PARG); + return (-1); } -#endif /* HAVE_POSIX_REGCOMP */ + if (regpattern != NULL) + regfree(regpattern); + regpattern = s; +#endif #if HAVE_RE_COMP - /* - * (re_comp handles a null pattern internally, - * so there is no need to check for a null pattern here.) - */ + PARG parg; if ((parg.p_string = re_comp(pattern)) != NULL) { @@ -149,118 +200,194 @@ return (-1); } + re_pattern = 1; #endif #if HAVE_REGCMP - if (pattern == NULL || *pattern == '\0') + char *s; + if ((s = regcmp(pattern, 0)) == NULL) { - /* - * A null pattern means use the previous pattern. - * The compiled previous pattern is in cpattern, so just use it. - */ - if (cpattern == NULL) - { - error("No previous regular expression", NULL_PARG); - return (-1); - } - } else + error("Invalid pattern", NULL_PARG); + return (-1); + } + if (cpattern != NULL) + free(cpattern); + cpattern = s; +#endif +#if HAVE_V8_REGCOMP + struct regexp *s; + if ((s = regcomp(pattern)) == NULL) { - /* - * Otherwise compile the given pattern. - */ - char *s; - if ((s = regcmp(pattern, 0)) == NULL) - { - error("Invalid pattern", NULL_PARG); - return (-1); - } - if (cpattern != NULL) - free(cpattern); - cpattern = s; + error("Invalid pattern", NULL_PARG); + return (-1); } + if (regpattern != NULL) + free(regpattern); + regpattern = s; +#endif +#if NO_REGEX + static char lpbuf[100]; + strcpy(lpbuf, pattern); + last_pattern = lpbuf; +#endif + return (0); +} + +/* + * Perform a pattern match with the previously compiled pattern. + */ + static int +match_pattern(line) + char *line; +{ +#if HAVE_POSIX_REGCOMP + return (!regexec(regpattern, line, 0, NULL, 0)); +#endif +#if HAVE_RE_COMP + return (re_exec(line) == 1); +#endif +#if HAVE_REGCMP + return (regex(cpattern, line) != NULL); #endif #if HAVE_V8_REGCOMP - if (pattern == NULL || *pattern == '\0') + return (regexec(regpattern, line)); +#endif +#if NO_REGEX + return (match(last_pattern, line, (char*)NULL, (char*)NULL)); +#endif +} + +/* + * Change the caseless-ness of searches. + * Updates the internal search state to reflect a change in the -i flag. + */ + public void +chg_caseless() +{ + if (!is_ucase_pattern) + is_caseless = caseless; +} + +/* + * Figure out where to start a search. + */ + static POSITION +search_pos(goforw) + int goforw; +{ + POSITION pos; + int linenum; + + if (empty_screen()) { /* - * A null pattern means use the previous pattern. - * The compiled previous pattern is in regpattern, - * so just use it. + * Start at the beginning (or end) of the file. + * (The empty_screen() case is mainly for + * command line initiated searches; + * for example, "+/xyz" on the command line.) */ - if (regpattern == NULL) + if (goforw) { - error("No previous regular expression", NULL_PARG); - return (-1); + return (ch_zero()); + } else + { + pos = ch_length(); + if (pos == NULL_POSITION) + return (ch_zero()); + return (pos); } + } + if (how_search) + { + /* + * Search does not include current screen. + */ + if (goforw) + linenum = BOTTOM_PLUS_ONE; + else + linenum = TOP; + pos = position(linenum); } else { /* - * Otherwise compile the given pattern. + * Search includes current screen. + * It starts at the jump target (if searching backwards), + * or at the jump target plus one (if forwards). */ - struct regexp *s; - if ((s = regcomp(pattern)) == NULL) - { - error("Invalid pattern", NULL_PARG); - return (-1); - } - if (regpattern != NULL) - free(regpattern); - regpattern = s; + linenum = adjsline(jump_sline); + pos = position(linenum); + if (goforw) + pos = forw_raw_line(pos, (char **)NULL); } -#endif -#if NO_REGEX + return (pos); +} + +/* + * Search for the n-th occurrence of a specified pattern, + * either forward or backward. + * Return the number of matches not yet found in this file + * (that is, n minus the number of matches found). + * Return -1 if the search should be aborted. + * Caller may continue the search in another file + * if less than n matches are found in this file. + */ + public int +search(search_type, pattern, n) + int search_type; + char *pattern; + int n; +{ + POSITION pos, linepos, oldpos; + register int goforw; + register int want_match; + char *line; + int linenum; + int line_match; + + /* + * Extract flags and type of search. + */ + goforw = (SRCH_DIR(search_type) == SRCH_FORW); + want_match = !(search_type & SRCH_NOMATCH); + if (pattern == NULL || *pattern == '\0') { /* - * Null pattern means use the previous pattern. + * A null pattern means use the previously compiled pattern. */ - if (last_pattern == NULL) + if (!prev_pattern()) { error("No previous regular expression", NULL_PARG); return (-1); } - pattern = last_pattern; } else { - strcpy(lpbuf, pattern); - last_pattern = lpbuf; - } -#endif + /* + * Ignore case if -i is set AND + * the pattern is all lowercase. + */ + is_ucase_pattern = is_ucase(pattern); + if (is_ucase_pattern) + is_caseless = 0; + else + is_caseless = caseless; - /* - * Figure out where to start the search. - */ - if (empty_screen()) - { /* - * Start at the beginning (or end) of the file. - * (The empty_screen() case is mainly for - * command line initiated searches; - * for example, "+/xyz" on the command line.) + * Compile the pattern. */ - if (goforw) - pos = ch_zero(); - else - { - pos = ch_length(); - if (pos == NULL_POSITION) - pos = ch_zero(); - } - } else - { - if (how_search) - { - if (goforw) - linenum = BOTTOM_PLUS_ONE; - else - linenum = TOP; - pos = position(linenum); - } else - { - linenum = adjsline(jump_sline); - pos = position(linenum); - if (goforw) - pos = forw_raw_line(pos, (char **)NULL); - } + if (compile_pattern(pattern) < 0) + return (-1); +#if HILITE_SEARCH + /* + * If our current screen *might be* displaying highlighted + * search targets, we need to repaint. + */ + if (hilite_search) + screen_trashed = 1; +#endif } + /* + * Figure out where to start the search. + */ + pos = search_pos(goforw); if (pos == NULL_POSITION) { @@ -272,4 +399,10 @@ } +#if HILITE_SEARCH + if (no_hilite_search) + screen_trashed = 1; + no_hilite_search = 0; +#endif + linenum = find_linenum(pos); oldpos = pos; @@ -281,5 +414,5 @@ * if we're going backwards). */ - if (sigs) + if (ABORT_SIGS()) /* * A signal aborts the search. @@ -333,51 +466,19 @@ if (is_caseless || bs_mode == BS_SPECIAL) { - /* - * If this is a caseless search, convert - * uppercase in the input line to lowercase. - * While we're at it, remove any backspaces - * along with the preceding char. - * This allows us to match text which is - * underlined or overstruck. - */ - for (p = q = line; *p != '\0'; p++, q++) - { - if (is_caseless && *p >= 'A' && *p <= 'Z') - /* Convert uppercase to lowercase. */ - *q = *p + 'a' - 'A'; - else if (bs_mode == BS_SPECIAL && q > line && *p == '\b') - /* Delete BS and preceding char. */ - q -= 2; - else - /* Otherwise, just copy. */ - *q = *p; - } + int ops = 0; + if (is_caseless) + ops |= CVT_TO_LC; + if (bs_mode == BS_SPECIAL) + ops |= CVT_BS; + cvt_text(line, line, ops); } /* * Test the next line to see if we have a match. - * This is done in a variety of ways, depending - * on what pattern matching functions are available. - */ -#if HAVE_POSIX_REGCOMP - line_match = !regexec(regpattern, line, 0, NULL, 0); -#endif -#if HAVE_RE_COMP - line_match = (re_exec(line) == 1); -#endif -#if HAVE_REGCMP - line_match = (regex(cpattern, line) != NULL); -#endif -#if HAVE_V8_REGCOMP - line_match = regexec(regpattern, line); -#endif -#if NO_REGEX - line_match = match(pattern, line); -#endif - /* * We are successful if want_match and line_match are * both true (want a match and got it), * or both false (want a non-match and got it). */ + line_match = match_pattern(line); if (((want_match && line_match) || (!want_match && !line_match)) && --n <= 0) @@ -392,4 +493,97 @@ } +#if HILITE_SEARCH +/* + * Search for all occurrences of the previous pattern + * within a line. Mark all matches found. + * "Marking" a match is done by copying "marker" into the chars whose + * positions in the "found" string are equal to the positions of + * the matching string in the "line" string. + */ + public void +hlsearch(line, found, marker) + char *line; + char *found; + int marker; +{ + char *buf; + register char *p; + + if (!prev_pattern()) + return; + if (no_hilite_search) + return; + + /* + * If the last search was caseless, convert + * uppercase from the input line to lowercase + * in a temporary buffer. + */ + buf = line; + if (is_caseless) + { + /* + * {{ Yikes, a calloc for every line displayed (with -i)! + * Is this worth optimizing? }} + */ + buf = save(line); + cvt_text(buf, line, CVT_TO_LC); + } + + { + /* + * Now depending on what type of pattern matching function + * we have, define the macro NEXT_MATCH(p). + * This will look for the first match in "p"; + * if it finds one it sets sp and ep to the start and + * end of the matching string and returns 1. + * If there is no match, it returns 0. + */ + +#if HAVE_POSIX_REGCOMP +regmatch_t rm; +#define NEXT_MATCH(p) (!regexec(regpattern,p,1,&rm,0)) +#define sp (p+rm.rm_so) +#define ep (p+rm.rm_eo) +#endif + +#if HAVE_RE_COMP +@@@ Sorry, re_comp does not support HILITE_SEARCH. +@@@ Either undefine HILITE_SEARCH, or use the regexp.c that is +@@@ distributed with "less" (and set HAVE_V8_REGCOMP). +#endif + +#if HAVE_REGCMP +#define sp __loc1 +char *ep; +#define NEXT_MATCH(p) (ep = regex(cpattern, p)) +#endif + +#if HAVE_V8_REGCOMP +#define sp (regpattern->startp[0]) +#define ep (regpattern->endp[0]) +#define NEXT_MATCH(p) (regexec(regpattern, p)) +#endif + +#if NO_REGEX +char *sp, *ep; +#define NEXT_MATCH(p) (match(last_pattern,p,&sp,&ep)) +#endif + + for (p = buf; NEXT_MATCH(p); p = ep) + { + register char *fsp = &found[sp-buf]; + register char *fep = &found[ep-buf]; + + while (fsp < fep) + *fsp++ = marker; + } + } + + if (buf != line) + free(buf); +} +#endif /* HILITE_SEARCH */ + #if NO_REGEX /* @@ -399,6 +593,7 @@ */ static int -match(pattern, buf) +match(pattern, buf, pfound, pend) char *pattern, *buf; + char **pfound, **pend; { register char *pp, *lp; @@ -410,7 +605,26 @@ break; if (*pp == '\0') + { + if (pfound != NULL) + *pfound = buf; + if (pend != NULL) + *pend = lp; return (1); + } } return (0); +} +#endif + +#if HAVE_V8_REGCOMP +/* + * This function is called by the V8 regcomp to report + * errors in regular expressions. + */ + void +regerror(s) + char *s; +{ + error(s, NULL_PARG); } #endif diff --exclude=*,v -r -U2 --entire less-205/signal.c less-227/signal.c --- less-205/signal.c Mon Jul 25 20:40:13 1994 +++ less-227/signal.c Fri Aug 26 00:58:13 1994 @@ -44,17 +44,9 @@ public int sigs; -#define S_INTERRUPT 01 -#ifdef SIGTSTP -#define S_STOP 02 -#endif -#if defined(SIGWINCH) || defined(SIGWIND) -#define S_WINCH 04 -#endif - extern int sc_width, sc_height; extern int screen_trashed; extern int lnloop; extern int linenums; -extern int scroll; +extern int wscroll; extern int reading; @@ -224,5 +216,5 @@ if (sc_width != old_width || sc_height != old_height) { - scroll = (sc_height + 1) / 2; + wscroll = (sc_height + 1) / 2; screen_trashed = 1; } diff --exclude=*,v -r -U2 --entire less-205/tags.c less-227/tags.c --- less-205/tags.c Tue Aug 2 20:42:05 1994 +++ less-227/tags.c Fri Aug 26 00:56:36 1994 @@ -33,8 +33,9 @@ public char *tagfile; -public char *tagpattern; - public char *tags = "tags"; +static char *tagpattern; +static int taglinenum; + extern int linenums; extern int sigs; @@ -51,8 +52,9 @@ register char *tag; { - register char *p; + char *p; register FILE *f; register int taglen; int search_char; + int err; static char tline[200]; @@ -77,18 +79,16 @@ * Found it. * The line contains the tag, the filename and the - * pattern, separated by white space. - * The pattern is surrounded by a pair of identical - * search characters. + * 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. */ - for (p = tline; !WHITESP(*p) && *p != '\0'; p++) - continue; - while (WHITESP(*p)) - p++; + p = skipsp(tline+taglen); if (*p == '\0') /* File name is missing! */ @@ -103,6 +103,5 @@ p++; *p++ = '\0'; - while (WHITESP(*p)) - p++; + p = skipsp(p); if (*p == '\0') /* Pattern is missing! */ @@ -110,17 +109,25 @@ /* - * Save the pattern. - * Skip to the end of the pattern. - * Delete the initial "^" and the final "$" from the pattern. + * First see if it is a line number. */ - search_char = *p++; - if (*p == '^') - p++; - tagpattern = p; - while (*p != search_char && *p != '\0') - p++; - if (p[-1] == '$') - p--; - *p = '\0'; + taglinenum = getnum(&p, 0, &err); + if (err) + { + /* + * No, it must be a pattern. + * Delete the initial "^" (if present) and + * the final "$" from the pattern. + */ + taglinenum = 0; + search_char = *p++; + if (*p == '^') + p++; + tagpattern = p; + while (*p != search_char && *p != '\0') + p++; + if (p[-1] == '$') + p--; + *p = '\0'; + } fclose(f); @@ -141,5 +148,5 @@ * parentheses (which are almost always found in a tag). */ - public int + public POSITION tagsearch() { @@ -148,4 +155,11 @@ 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); @@ -157,6 +171,6 @@ * until we hit end-of-file. */ - if (sigs) - return (1); + if (ABORT_SIGS()) + return (NULL_POSITION); /* @@ -175,5 +189,5 @@ */ error("Tag not found", NULL_PARG); - return (1); + return (NULL_POSITION); } @@ -195,6 +209,5 @@ } - jump_loc(linepos, jump_sline); - return (0); + return (linepos); } diff --exclude=*,v -r -U2 --entire less-205/version.c less-227/version.c --- less-205/version.c Fri Aug 5 17:17:59 1994 +++ less-227/version.c Mon Sep 19 19:15:20 1994 @@ -371,5 +371,41 @@ * v205: Fix bug in finding "me" termcap entry. 8/5/94 * (thanks to Andreas Stolcke) + * v205+: Change BUFSIZ to LBUFSIZE to avoid name 8/10/94 + * conflict with stdio.h. + * Posted to prep.ai.mit.edu + * ----------------------------------------------------------------- + * v206: Use initial_scrpos for -t to avoid 8/10/94 + * displaying first page before init(). + * (thanks to Dominique Petitpierre) + * v207: Fix bug if stdout is not tty. 8/12/94 + * v208: Fix bug in close_altfile if goto err1 8/16/94 + * in edit_ifile. (Thanks to M.J. Hewitt) + * v209: Change scroll to wscroll to avoid 8/16/94 + * conflict with library function. + * v210: Fix bug with bold on 8 bit chars. 8/16/94 + * (thanks to Vitor Duarte) + * v211: Don't quit on EOI in jump_loc / forw. 8/16/94 + * v212: Use time_t if available. 8/18/94 + * v213: Allow ospeed to be defined in termcap.h. 8/20/94 + * v214: Added HILITE_SEARCH, -F, ESC-u cmd. 8/20/94 + * (thanks to Paul Lew and Bob Byrnes) + * v215: Fix -i toggle behavior. 8/23/94 + * v216: Process BS in all searches, not only -u. 8/23/94 + * v217: Added -X flag. 8/24/94 + * v218: Reimplement undo_search. 8/24/94 + * v219: Find tags marked with line number 8/24/94 + * instead of pattern. + * v220: Stay at same position after SIG_WINCH. 8/24/94 + * v221: Fix bug in file percentage in big file. 8/24/94 + * v222: Do better if can't reopen current file. 8/25/94 + * v223: Support setlocale. 8/27/94 + * (thanks to Robert Joop) + * v224: Revert v216: process BS in search 8/29/94 + * only if -u. + * v225: Rewrite undo_search again: toggle. 9/6/94 + * v226: Configuration fixes. 9/15/94 + * (thanks to David MacKenzie) + * v227: Fixed strerror config problem. 9/19/94 */ -char version[] = "@(#) less version 205"; +char version[] = "@(#) less version 227";