Imported Upstream version 530 upstream/530
authorJinWang An <jinwang.an@samsung.com>
Wed, 28 Dec 2022 07:13:18 +0000 (16:13 +0900)
committerJinWang An <jinwang.an@samsung.com>
Wed, 28 Dec 2022 07:13:18 +0000 (16:13 +0900)
75 files changed:
Makefile.aut
Makefile.dsg
Makefile.in
NEWS
README
brac.c
ch.c
charset.c
charset.h
cmd.h
cmdbuf.c
command.c
compose.uni
configure
configure.ac
cvt.c
decode.c
defines.ds
defines.h.in
defines.o2
defines.o9
defines.wn
edit.c
filename.c
fmt.uni [new file with mode: 0644]
forwback.c
funcs.h
help.c
ifile.c
input.c
install.sh [changed mode: 0755->0644]
jump.c
less.h
less.hlp
less.man
less.nro
lessecho.c
lessecho.man
lessecho.nro
lesskey.c
lesskey.h
lesskey.man
lesskey.nro
lglob.h
line.c
linenum.c
lsystem.c
main.c
mark.c
mkfuncs.awk [deleted file]
mkfuncs.pl [new file with mode: 0644]
mkhelp.c [deleted file]
mkhelp.pl [new file with mode: 0755]
mkutable
optfunc.c
option.c
option.h
opttbl.c
os.c
output.c
pattern.c
pattern.h
pckeys.h
position.c
position.h
prompt.c
screen.c
scrsize.c
search.c
signal.c
tags.c
ttyin.c
ubin.uni
version.c
wide.uni

index 9cc04ce..8816902 100644 (file)
@@ -3,7 +3,7 @@
 EMAIL = bug-less@gnu.org
 HOMEPAGE = http://www.greenwoodsoftware.com/less
 SHELL = /bin/sh
-RCS = rcs
+GIT = git
 NROFF = nroff -man
 
 srcdir = .
@@ -22,7 +22,7 @@ DISTFILES_W = \
        defines.wn  Makefile.wnm Makefile.wnb \
        configure 
 UNICODE_FILES = \
-       compose.uni ubin.uni wide.uni
+       compose.uni fmt.uni ubin.uni wide.uni
 DISTFILES = \
        ${SRC} regexp.c regexp.h \
        COPYING INSTALL LICENSE Makefile.in Makefile.aut NEWS README \
@@ -32,7 +32,7 @@ DISTFILES = \
        install.sh defines.h.in mkinstalldirs \
        less.nro less.man lesskey.nro lesskey.man lessecho.nro lessecho.man \
        less.hlp \
-       mkfuncs.awk mkhelp.c \
+       mkfuncs.pl mkhelp.pl \
        mkutable $(UNICODE_FILES) \
        ${DISTFILES_W}
 
@@ -46,22 +46,19 @@ release: .FORCE
 
 .FORCE:
 
-help.c: less.hlp mkhelp
+help.c: less.hlp 
        -mv -f ${srcdir}/help.c ${srcdir}/help.c.old
        rm -rf help.c
-       ./mkhelp < less.hlp > help.c
+       ${srcdir}/mkhelp.pl < less.hlp > help.c
        if cmp -s help.c help.c.old; then mv -f help.c.old help.c; fi
 
-mkhelp: mkhelp.c
-       ${CC} -o mkhelp mkhelp.c
-
 ${srcdir}/configure: ${srcdir}/configure.ac \
                ${srcdir}/Makefile.in
        cd ${srcdir}; autoheader; autoconf
 
 funcs.h: ${SRC:%=${srcdir}/%}
        -mv -f ${srcdir}/funcs.h ${srcdir}/funcs.h.old
-       awk -f ${srcdir}/mkfuncs.awk ${SRC:%=${srcdir}/%} >${srcdir}/funcs.h
+       perl ${srcdir}/mkfuncs.pl ${SRC:%=${srcdir}/%} >${srcdir}/funcs.h
        if cmp -s funcs.h funcs.h.old; then mv -f funcs.h.old funcs.h; fi
 
 lint:
@@ -108,8 +105,10 @@ ${srcdir}/lessecho.man: ${srcdir}/lessecho.nro
 
 compose.uni: unicode/UnicodeData.txt
        ./mkutable -f2 Mn Me -- unicode/UnicodeData.txt > $@
+fmt.uni: unicode/UnicodeData.txt
+       ./mkutable -f2 Cf -- unicode/UnicodeData.txt > $@
 ubin.uni: unicode/UnicodeData.txt
-       ./mkutable -f2 Cc Cf Cs Co Zl Zp -- unicode/UnicodeData.txt > $@
+       ./mkutable -f2 Cc Cs Co Zl Zp -- unicode/UnicodeData.txt > $@
 wide.uni: unicode/EastAsianWidth.txt
        ./mkutable -f1 W F -- unicode/EastAsianWidth.txt > $@
 
@@ -130,6 +129,7 @@ dist: ${DISTFILES}
        tar -cf - $$REL | gzip -c >release/$$REL/$$REL.tar.gz; \
        echo "Signing release/$$REL/$$REL.tar.gz"; \
        gpg --detach-sign release/$$REL/$$REL.tar.gz; \
+       mv release/$$REL/$$REL.tar.gz.sig release/$$REL/$$REL.sig; \
        echo "Creating release/$$REL/$$REL.zip"; \
        zip -rq release/$$REL/$$REL.zip $$REL; \
        rm -rf $$REL
@@ -137,7 +137,4 @@ dist: ${DISTFILES}
 tagall:
        @REL=`sed -e '/char version/!d' -e 's/[^0-9.]*\([0-9.]*\).*/v\1/' -e q ${srcdir}/version.c`; \
        echo "tagging $$REL"; \
-       for f in ${srcdir}/RCS/*,v; do \
-         REV=`co -p $$f 2>&1 | sed -e '1d' -e '3,$$d' -e 's/revision //'`; \
-         ${RCS} -N$$REL:$$REV $$f; \
-       done
+       $(GIT) tag -f "$$REL"
index b921b5d..4c11be0 100644 (file)
@@ -73,10 +73,6 @@ installcheck:
 TAGS:
        etags *.c *.h
 
-newfuncs:
-       command.com /c if exist funcs.h del funcs.h
-       ${AWK} -f mkfuncs.awk ${OBJ:.${O}=.c} > funcs.h
-
 clean:
        command.com /c for %f in (*.${O} less lesskey lessecho *.exe) do if exist %f del %f
 
index 8c8aed8..c9cbf8e 100644 (file)
@@ -62,6 +62,8 @@ lesskey$(EXEEXT): lesskey.${O} version.${O}
 lessecho$(EXEEXT): lessecho.${O} version.${O}
        ${CC} ${LDFLAGS} -o $@ lessecho.${O} version.${O}
 
+charset.${O}: compose.uni ubin.uni wide.uni
+
 ${OBJ}: ${srcdir}/less.h ${srcdir}/funcs.h defines.h 
 
 install: all ${srcdir}/less.nro ${srcdir}/lesskey.nro ${srcdir}/lessecho.nro installdirs
diff --git a/NEWS b/NEWS
index ebdce64..14997c2 100644 (file)
--- a/NEWS
+++ b/NEWS
 
 ======================================================================
 
+       Major changes between "less" versions 487 and 530
+
+* Don't output terminal init sequence if using -F and file fits on one screen.
+
+* When using -S, mark truncated lines with a special character.
+  The character can be changed or disabled via the new --rscroll option.
+
+* New command M marks the last line displayed on the screen.
+
+* New command ESC-m removes a line mark.
+
+* Status column (enabled via -J) now shows mark letters.
+
+* Status column shows search matches even if highlighting is disabled via -G.
+
+* A second ESC-u command will clear search match markers in the status column.
+
+* Do same ANSI escape code filtering for tag matching that we do for 
+  searching, to help when viewing syntax-highlighted code.
+  
+* Catch SIGTERM and clean up before exiting.
+
+* Fix bug initializing default charset on Windows.
+
+* Handle keypad ENTER key correctly if it sends something other than newline.
+
+* Fix buffering bug when using stdin with a LESSOPEN pipe.
+
+* On Windows, allow 'u' in -D option to enable underlining.
+
+* On Windows, use underline in sgr mode.
+
+* On Windows, convert UTF-8 to multibyte if console is not UTF-8.
+
+* Update Unicode tables to 2017-03-08.
+
+* Pass-thru Unicode formating chars (Cf type) instead of treating them
+  as binary chars. But treat them as binary if -U is set.
+
+* Fix erroneous binary file warning when UTF-8 file contains ANSI SGR sequences.
+
+* Fix bugs when using LESSOPEN and switching between stdin and other files.
+
+* Fix some bugs handling filenames containing shell metacharacters.
+
+* Fix some memory leaks.
+
+* Allow some debugging environment variables to be set in lesskey file.
+
+* Code improvements:
+  . Use ANSI prototypes in funcs.h declarations.
+  . Fix some const mismatches.
+  . Remove archaic "register" in variable declarations.
+
+======================================================================
+
        Major changes between "less" versions 481 and 487
 
 * New commands ESC-{ and ESC-} to shift to start/end of displayed lines.
diff --git a/README b/README
index ee8903d..9103598 100644 (file)
--- a/README
+++ b/README
@@ -1,7 +1,7 @@
 
-                            Less, version 487
+                            Less, version 530
 
-    This is the distribution of less, version 487, released 25 Oct 2016.
+    This is the distribution of less, version 530, released 05 Dec 2017.
     This program is part of the GNU project (http://www.gnu.org).
 
     This program is free software.  You may redistribute it and/or
@@ -15,6 +15,7 @@
 
     Please report any problems to bug-less@gnu.org.
     See http://www.greenwoodsoftware.com/less for the latest info.
+    Source repository is at https://github.com/gwsw/less.git.
 
 =========================================================================
 
diff --git a/brac.c b/brac.c
index 5119f4e..44f2403 100644 (file)
--- a/brac.c
+++ b/brac.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
  */
        public void
 match_brac(obrac, cbrac, forwdir, n)
-       register int obrac;
-       register int cbrac;
+       int obrac;
+       int cbrac;
        int forwdir;
        int n;
 {
-       register int c;
-       register int nest;
+       int c;
+       int nest;
        POSITION pos;
        int (*chget)();
 
diff --git a/ch.c b/ch.c
index ddebb73..47c1a32 100644 (file)
--- a/ch.c
+++ b/ch.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -146,11 +146,11 @@ static int ch_addbuf();
        int
 ch_get()
 {
-       register struct buf *bp;
-       register struct bufnode *bn;
-       register int n;
-       register int slept;
-       register int h;
+       struct buf *bp;
+       struct bufnode *bn;
+       int n;
+       int slept;
+       int h;
        POSITION pos;
        POSITION len;
 
@@ -419,8 +419,8 @@ end_logfile()
        public void
 sync_logfile()
 {
-       register struct buf *bp;
-       register struct bufnode *bn;
+       struct buf *bp;
+       struct bufnode *bn;
        int warned = FALSE;
        BLOCKNUM block;
        BLOCKNUM nblocks;
@@ -457,9 +457,9 @@ sync_logfile()
 buffered(block)
        BLOCKNUM block;
 {
-       register struct buf *bp;
-       register struct bufnode *bn;
-       register int h;
+       struct buf *bp;
+       struct bufnode *bn;
+       int h;
 
        h = BUFHASH(block);
        FOR_BUFS_IN_CHAIN(h, bn)
@@ -477,7 +477,7 @@ buffered(block)
  */
        public int
 ch_seek(pos)
-       register POSITION pos;
+       POSITION pos;
 {
        BLOCKNUM new_block;
        POSITION len;
@@ -544,8 +544,8 @@ ch_end_seek()
        public int
 ch_end_buffer_seek()
 {
-       register struct buf *bp;
-       register struct bufnode *bn;
+       struct buf *bp;
+       struct bufnode *bn;
        POSITION buf_pos;
        POSITION end_pos;
 
@@ -572,8 +572,8 @@ ch_end_buffer_seek()
        public int
 ch_beg_seek()
 {
-       register struct bufnode *bn;
-       register struct bufnode *firstbn;
+       struct bufnode *bn;
+       struct bufnode *firstbn;
 
        /*
         * Try a plain ch_seek first.
@@ -632,7 +632,7 @@ ch_tell()
        public int
 ch_forw_get()
 {
-       register int c;
+       int c;
 
        if (thisfile == NULL)
                return (EOI);
@@ -695,7 +695,7 @@ ch_setbufspace(bufspace)
        public void
 ch_flush()
 {
-       register struct bufnode *bn;
+       struct bufnode *bn;
 
        if (thisfile == NULL)
                return;
@@ -762,8 +762,8 @@ ch_flush()
        static int
 ch_addbuf()
 {
-       register struct buf *bp;
-       register struct bufnode *bn;
+       struct buf *bp;
+       struct bufnode *bn;
 
        /*
         * Allocate and initialize a new buffer and link it 
@@ -787,7 +787,7 @@ ch_addbuf()
        static void
 init_hashtbl()
 {
-       register int h;
+       int h;
 
        for (h = 0;  h < BUFHASH_SIZE;  h++)
        {
@@ -802,7 +802,7 @@ init_hashtbl()
        static void
 ch_delbufs()
 {
-       register struct bufnode *bn;
+       struct bufnode *bn;
 
        while (ch_bufhead != END_OF_CHAIN)
        {
@@ -867,13 +867,12 @@ ch_init(f, flags)
                                calloc(1, sizeof(struct filestate));
                thisfile->buflist.next = thisfile->buflist.prev = END_OF_CHAIN;
                thisfile->nbufs = 0;
-               thisfile->flags = 0;
+               thisfile->flags = flags;
                thisfile->fpos = 0;
                thisfile->block = 0;
                thisfile->offset = 0;
                thisfile->file = -1;
                thisfile->fsize = NULL_POSITION;
-               ch_flags = flags;
                init_hashtbl();
                /*
                 * Try to seek; set CH_CANSEEK if it works.
@@ -898,7 +897,7 @@ ch_close()
        if (thisfile == NULL)
                return;
 
-       if (ch_flags & (CH_CANSEEK|CH_POPENED|CH_HELPFILE))
+       if ((ch_flags & (CH_CANSEEK|CH_POPENED|CH_HELPFILE)) && !(ch_flags & CH_KEEPOPEN))
        {
                /*
                 * We can seek or re-open, so we don't need to keep buffers.
index 16613cc..8897891 100644 (file)
--- a/charset.c
+++ b/charset.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
 
 #include "charset.h"
 
+#if MSDOS_COMPILER==WIN32C
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
+extern int bs_mode;
+
 public int utf_mode = 0;
 
 /*
@@ -135,9 +142,9 @@ public int binattr = AT_STANDOUT;
 ichardef(s)
        char *s;
 {
-       register char *cp;
-       register int n;
-       register char v;
+       char *cp;
+       int n;
+       char v;
 
        n = 0;
        v = 0;
@@ -190,11 +197,11 @@ ichardef(s)
  */
        static int
 icharset(name, no_error)
-       register char *name;
+       char *name;
        int no_error;
 {
-       register struct charset *p;
-       register struct cs_alias *a;
+       struct charset *p;
+       struct cs_alias *a;
 
        if (name == NULL || *name == '\0')
                return (0);
@@ -215,7 +222,13 @@ icharset(name, no_error)
                {
                        ichardef(p->desc);
                        if (p->p_flag != NULL)
+                       {
+#if MSDOS_COMPILER==WIN32C
+                               *(p->p_flag) = 1 + (GetConsoleOutputCP() != CP_UTF8);
+#else
                                *(p->p_flag) = 1;
+#endif
+                       }
                        return (1);
                }
        }
@@ -234,7 +247,7 @@ icharset(name, no_error)
        static void
 ilocale()
 {
-       register int c;
+       int c;
 
        for (c = 0;  c < (int) sizeof(chardef);  c++)
        {
@@ -251,16 +264,17 @@ ilocale()
 /*
  * Define the printing format for control (or binary utf) chars.
  */
-       static void
-setbinfmt(s, fmtvarptr, default_fmt)
+       public void
+setfmt(s, fmtvarptr, attrptr, default_fmt)
        char *s;
        char **fmtvarptr;
+       int *attrptr;
        char *default_fmt;
 {
        if (s && utf_mode)
        {
                /* It would be too hard to account for width otherwise.  */
-               char *t = s;
+               char constant *t = s;
                while (*t)
                {
                        if (*t < ' ' || *t > '~')
@@ -282,15 +296,15 @@ setbinfmt(s, fmtvarptr, default_fmt)
         * Select the attributes if it starts with "*".
         */
  attr:
-       if (*s == '*')
+       if (*s == '*' && s[1] != '\0')
        {
                switch (s[1])
                {
-               case 'd':  binattr = AT_BOLD;      break;
-               case 'k':  binattr = AT_BLINK;     break;
-               case 's':  binattr = AT_STANDOUT;  break;
-               case 'u':  binattr = AT_UNDERLINE; break;
-               default:   binattr = AT_NORMAL;    break;
+               case 'd':  *attrptr = AT_BOLD;      break;
+               case 'k':  *attrptr = AT_BLINK;     break;
+               case 's':  *attrptr = AT_STANDOUT;  break;
+               case 'u':  *attrptr = AT_UNDERLINE; break;
+               default:   *attrptr = AT_NORMAL;    break;
                }
                s += 2;
        }
@@ -305,6 +319,14 @@ set_charset()
 {
        char *s;
 
+#if MSDOS_COMPILER==WIN32C
+       /*
+        * If the Windows console is using UTF-8, we'll use it too.
+        */
+       if (GetConsoleOutputCP() == CP_UTF8)
+               if (icharset("utf-8", 1))
+                       return;
+#endif
        /*
         * See if environment variable LESSCHARSET is defined.
         */
@@ -354,6 +376,7 @@ set_charset()
         * rather than from predefined charset entry.
         */
        ilocale();
+#else
 #if MSDOS_COMPILER
        /*
         * Default to "dos".
@@ -383,10 +406,10 @@ init_charset()
        set_charset();
 
        s = lgetenv("LESSBINFMT");
-       setbinfmt(s, &binfmt, "*s<%02X>");
+       setfmt(s, &binfmt, &binattr, "*s<%02X>");
        
        s = lgetenv("LESSUTFBINFMT");
-       setbinfmt(s, &utfbinfmt, "<U+%04lX>");
+       setfmt(s, &utfbinfmt, &binattr, "<U+%04lX>");
 }
 
 /*
@@ -486,7 +509,7 @@ prutfchar(ch)
  */
        public int
 utf_len(ch)
-       char ch;
+       unsigned char ch;
 {
        if ((ch & 0x80) == 0)
                return 1;
@@ -508,17 +531,18 @@ utf_len(ch)
  * Does the parameter point to the lead byte of a well-formed UTF-8 character?
  */
        public int
-is_utf8_well_formed(s, slen)
-       unsigned char *s;
+is_utf8_well_formed(ss, slen)
+       char *ss;
        int slen;
 {
        int i;
        int len;
+       unsigned char *s = (unsigned char *) ss;
 
        if (IS_UTF8_INVALID(s[0]))
                return (0);
 
-       len = utf_len((char) s[0]);
+       len = utf_len(s[0]);
        if (len > slen)
                return (0);
        if (len == 1)
@@ -542,40 +566,25 @@ is_utf8_well_formed(s, slen)
 }
 
 /*
- * Return number of invalid UTF-8 sequences found in a buffer.
+ * Skip bytes until a UTF-8 lead byte (11xxxxxx) or ASCII byte (0xxxxxxx) is found.
  */
-       public int
-utf_bin_count(data, len)
-       unsigned char *data;
-       int len;
+       public void
+utf_skip_to_lead(pp, limit)
+       char **pp;
+       char *limit;
 {
-       int bin_count = 0;
-       while (len > 0)
-       {
-               if (is_utf8_well_formed(data, len))
-               {
-                       int clen = utf_len(*data);
-                       data += clen;
-                       len -= clen;
-               } else
-               {
-                       /* Skip to next lead byte. */
-                       bin_count++;
-                       do {
-                               ++data;
-                               --len;
-                       } while (len > 0 && !IS_UTF8_LEAD(*data));
-               }
-       }
-       return (bin_count);
+       do {
+               ++(*pp);
+       } while (*pp < limit && !IS_UTF8_LEAD((*pp)[0] & 0377) && !IS_ASCII_OCTET((*pp)[0]));
 }
 
+
 /*
  * Get the value of a UTF-8 character.
  */
        public LWCHAR
 get_wchar(p)
-       char *p;
+       constant char *p;
 {
        switch (utf_len(p[0]))
        {
@@ -679,7 +688,7 @@ put_wchar(pp, ch)
 step_char(pp, dir, limit)
        char **pp;
        signed int dir;
-       char *limit;
+       constant char *limit;
 {
        LWCHAR ch;
        int len;
@@ -689,16 +698,16 @@ step_char(pp, dir, limit)
        {
                /* It's easy if chars are one byte. */
                if (dir > 0)
-                       ch = (LWCHAR) ((p < limit) ? *p++ : 0);
+                       ch = (LWCHAR) (unsigned char) ((p < limit) ? *p++ : 0);
                else
-                       ch = (LWCHAR) ((p > limit) ? *--p : 0);
+                       ch = (LWCHAR) (unsigned char) ((p > limit) ? *--p : 0);
        } else if (dir > 0)
        {
                len = utf_len(*p);
                if (p + len > limit)
                {
                        ch = 0;
-                       p = limit;
+                       p = (char *) limit;
                } else
                {
                        ch = get_wchar(p);
@@ -739,6 +748,10 @@ DECLARE_RANGE_TABLE_START(wide)
 #include "wide.uni"
 DECLARE_RANGE_TABLE_END(wide)
 
+DECLARE_RANGE_TABLE_START(fmt)
+#include "fmt.uni"
+DECLARE_RANGE_TABLE_END(fmt)
+
 /* comb_table is special pairs, not ranges. */
 static struct wchar_range comb_table[] = {
        {0x0644,0x0622}, {0x0644,0x0623}, {0x0644,0x0625}, {0x0644,0x0627},
@@ -779,7 +792,8 @@ is_in_table(ch, table)
 is_composing_char(ch)
        LWCHAR ch;
 {
-       return is_in_table(ch, &compose_table);
+       return is_in_table(ch, &compose_table) ||
+              (bs_mode != BS_CONTROL && is_in_table(ch, &fmt_table));
 }
 
 /*
@@ -789,7 +803,21 @@ is_composing_char(ch)
 is_ubin_char(ch)
        LWCHAR ch;
 {
-       return is_in_table(ch, &ubin_table);
+       int ubin = is_in_table(ch, &ubin_table) ||
+                  (bs_mode == BS_CONTROL && is_in_table(ch, &fmt_table));
+#if MSDOS_COMPILER==WIN32C
+       if (!ubin && utf_mode == 2 && ch < 0x10000)
+       {
+               /*
+                * Consider it binary if it can't be converted.
+                */
+               BOOL used_default = TRUE;
+               WideCharToMultiByte(GetConsoleOutputCP(), WC_NO_BEST_FIT_CHARS, (LPCWSTR) &ch, 1, NULL, 0, NULL, &used_default);
+               if (used_default)
+                       ubin = 1;
+       }
+#endif
+       return ubin;
 }
 
 /*
index a4e3bf1..1e3f069 100644 (file)
--- a/charset.h
+++ b/charset.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
diff --git a/cmd.h b/cmd.h
index dd07ff8..632b65e 100644 (file)
--- a/cmd.h
+++ b/cmd.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
  */
 
 
-#define        MAX_USERCMD             1000
-#define        MAX_CMDLEN              16
+#define MAX_USERCMD            1000
+#define MAX_CMDLEN             16
 
-#define        A_B_LINE                2
-#define        A_B_SCREEN              3
-#define        A_B_SCROLL              4
-#define        A_B_SEARCH              5
-#define        A_DIGIT                 6
-#define        A_DISP_OPTION           7
-#define        A_DEBUG                 8
-#define        A_EXAMINE               9
-#define        A_FIRSTCMD              10
-#define        A_FREPAINT              11
-#define        A_F_LINE                12
-#define        A_F_SCREEN              13
-#define        A_F_SCROLL              14
-#define        A_F_SEARCH              15
-#define        A_GOEND                 16
-#define        A_GOLINE                17
-#define        A_GOMARK                18
-#define        A_HELP                  19
-#define        A_NEXT_FILE             20
-#define        A_PERCENT               21
-#define        A_PREFIX                22
-#define        A_PREV_FILE             23
-#define        A_QUIT                  24
-#define        A_REPAINT               25
-#define        A_SETMARK               26
-#define        A_SHELL                 27
-#define        A_STAT                  28
-#define        A_FF_LINE               29
-#define        A_BF_LINE               30
-#define        A_VERSION               31
-#define        A_VISUAL                32
-#define        A_F_WINDOW              33
-#define        A_B_WINDOW              34
-#define        A_F_BRACKET             35
-#define        A_B_BRACKET             36
-#define        A_PIPE                  37
-#define        A_INDEX_FILE            38
-#define        A_UNDO_SEARCH           39
-#define        A_FF_SCREEN             40
-#define        A_LSHIFT                41
-#define        A_RSHIFT                42
-#define        A_AGAIN_SEARCH          43
-#define        A_T_AGAIN_SEARCH        44
-#define        A_REVERSE_SEARCH        45
-#define        A_T_REVERSE_SEARCH      46
-#define        A_OPT_TOGGLE            47
-#define        A_OPT_SET               48
-#define        A_OPT_UNSET             49
-#define        A_F_FOREVER             50
-#define        A_GOPOS                 51
-#define        A_REMOVE_FILE           52
-#define        A_NEXT_TAG              53
-#define        A_PREV_TAG              54
-#define        A_FILTER                55
-#define        A_F_UNTIL_HILITE        56
-#define        A_GOEND_BUF             57
-#define        A_LLSHIFT               58
-#define        A_RRSHIFT               59
+#define A_B_LINE               2
+#define A_B_SCREEN             3
+#define A_B_SCROLL             4
+#define A_B_SEARCH             5
+#define A_DIGIT                6
+#define A_DISP_OPTION          7
+#define A_DEBUG                8
+#define A_EXAMINE              9
+#define A_FIRSTCMD             10
+#define A_FREPAINT             11
+#define A_F_LINE               12
+#define A_F_SCREEN             13
+#define A_F_SCROLL             14
+#define A_F_SEARCH             15
+#define A_GOEND                16
+#define A_GOLINE               17
+#define A_GOMARK               18
+#define A_HELP                 19
+#define A_NEXT_FILE            20
+#define A_PERCENT              21
+#define A_PREFIX               22
+#define A_PREV_FILE            23
+#define A_QUIT                 24
+#define A_REPAINT              25
+#define A_SETMARK              26
+#define A_SHELL                27
+#define A_STAT                 28
+#define A_FF_LINE              29
+#define A_BF_LINE              30
+#define A_VERSION              31
+#define A_VISUAL               32
+#define A_F_WINDOW             33
+#define A_B_WINDOW             34
+#define A_F_BRACKET            35
+#define A_B_BRACKET            36
+#define A_PIPE                 37
+#define A_INDEX_FILE           38
+#define A_UNDO_SEARCH          39
+#define A_FF_SCREEN            40
+#define A_LSHIFT               41
+#define A_RSHIFT               42
+#define A_AGAIN_SEARCH         43
+#define A_T_AGAIN_SEARCH       44
+#define A_REVERSE_SEARCH       45
+#define A_T_REVERSE_SEARCH     46
+#define A_OPT_TOGGLE           47
+#define A_OPT_SET              48
+#define A_OPT_UNSET            49
+#define A_F_FOREVER            50
+#define A_GOPOS                51
+#define A_REMOVE_FILE          52
+#define A_NEXT_TAG             53
+#define A_PREV_TAG             54
+#define A_FILTER               55
+#define A_F_UNTIL_HILITE       56
+#define A_GOEND_BUF            57
+#define A_LLSHIFT              58
+#define A_RRSHIFT              59
+#define A_CLRMARK              62
+#define A_SETMARKBOT           63
 
-#define        A_INVALID               100
-#define        A_NOACTION              101
-#define        A_UINVALID              102
-#define        A_END_LIST              103
-#define        A_SPECIAL_KEY           104
+#define A_INVALID              100
+#define A_NOACTION             101
+#define A_UINVALID             102
+#define A_END_LIST             103
+#define A_SPECIAL_KEY          104
 
-#define A_SKIP                 127
+#define A_SKIP                 127
 
-#define        A_EXTRA                 0200
+#define A_EXTRA                0200
 
 
 /* Line editing characters */
 
-#define        EC_BACKSPACE    1
-#define        EC_LINEKILL     2
-#define        EC_RIGHT        3
-#define        EC_LEFT         4
-#define        EC_W_LEFT       5
-#define        EC_W_RIGHT      6
-#define        EC_INSERT       7
-#define        EC_DELETE       8
-#define        EC_HOME         9
-#define        EC_END          10
-#define        EC_W_BACKSPACE  11
-#define        EC_W_DELETE     12
-#define        EC_UP           13
-#define        EC_DOWN         14
-#define        EC_EXPAND       15
-#define        EC_F_COMPLETE   17
-#define        EC_B_COMPLETE   18
-#define        EC_LITERAL      19
-#define        EC_ABORT        20
+#define EC_BACKSPACE           1
+#define EC_LINEKILL            2
+#define EC_RIGHT               3
+#define EC_LEFT                4
+#define EC_W_LEFT              5
+#define EC_W_RIGHT             6
+#define EC_INSERT              7
+#define EC_DELETE              8
+#define EC_HOME                9
+#define EC_END                 10
+#define EC_W_BACKSPACE         11
+#define EC_W_DELETE            12
+#define EC_UP                  13
+#define EC_DOWN                14
+#define EC_EXPAND              15
+#define EC_F_COMPLETE          17
+#define EC_B_COMPLETE          18
+#define EC_LITERAL             19
+#define EC_ABORT               20
 
-#define        EC_NOACTION     101
-#define        EC_UINVALID     102
+#define EC_NOACTION            101
+#define EC_UINVALID            102
 
 /* Flags for editchar() */
-#define        EC_PEEK         01
-#define        EC_NOHISTORY    02
-#define        EC_NOCOMPLETE   04
-#define        EC_NORIGHTLEFT  010
+#define EC_PEEK                01
+#define EC_NOHISTORY           02
+#define EC_NOCOMPLETE          04
+#define EC_NORIGHTLEFT         010
 
 /* Environment variable stuff */
-#define        EV_OK           01
+#define EV_OK                  01
 
 /* Special keys (keys which output different strings on different terminals) */
-#define SK_SPECIAL_KEY         CONTROL('K')
-#define SK_RIGHT_ARROW         1
-#define SK_LEFT_ARROW          2
-#define SK_UP_ARROW            3
-#define SK_DOWN_ARROW          4
-#define SK_PAGE_UP             5
-#define SK_PAGE_DOWN           6
-#define SK_HOME                        7
-#define SK_END                 8
-#define SK_DELETE              9
-#define SK_INSERT              10
-#define SK_CTL_LEFT_ARROW      11
-#define SK_CTL_RIGHT_ARROW     12
-#define SK_CTL_DELETE          13
-#define SK_F1                  14
-#define SK_BACKTAB             15
-#define SK_CTL_BACKSPACE       16
-#define SK_CONTROL_K           40
+#define SK_SPECIAL_KEY         CONTROL('K')
+#define SK_RIGHT_ARROW         1
+#define SK_LEFT_ARROW          2
+#define SK_UP_ARROW            3
+#define SK_DOWN_ARROW          4
+#define SK_PAGE_UP             5
+#define SK_PAGE_DOWN           6
+#define SK_HOME                7
+#define SK_END                 8
+#define SK_DELETE              9
+#define SK_INSERT              10
+#define SK_CTL_LEFT_ARROW      11
+#define SK_CTL_RIGHT_ARROW     12
+#define SK_CTL_DELETE          13
+#define SK_F1                  14
+#define SK_BACKTAB             15
+#define SK_CTL_BACKSPACE       16
+#define SK_CONTROL_K           40
index 540b84d..db5b259 100644 (file)
--- a/cmdbuf.c
+++ b/cmdbuf.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -40,7 +40,7 @@ static int in_completion = 0;
 static char *tk_text;
 static char *tk_original;
 static char *tk_ipoint;
-static char *tk_trial;
+static char *tk_trial = NULL;
 static struct textlist tk_tlist;
 #endif
 
@@ -76,25 +76,25 @@ struct mlist
  */
 struct mlist mlist_search =  
        { &mlist_search,  &mlist_search,  &mlist_search,  NULL, 0 };
-public void * constant ml_search = (void *) &mlist_search;
+public void *ml_search = (void *) &mlist_search;
 
 struct mlist mlist_examine = 
        { &mlist_examine, &mlist_examine, &mlist_examine, NULL, 0 };
-public void * constant ml_examine = (void *) &mlist_examine;
+public void *ml_examine = (void *) &mlist_examine;
 
 #if SHELL_ESCAPE || PIPEC
 struct mlist mlist_shell =   
        { &mlist_shell,   &mlist_shell,   &mlist_shell,   NULL, 0 };
-public void * constant ml_shell = (void *) &mlist_shell;
+public void *ml_shell = (void *) &mlist_shell;
 #endif
 
 #else /* CMD_HISTORY */
 
 /* If CMD_HISTORY is off, these are just flags. */
-public void * constant ml_search = (void *)1;
-public void * constant ml_examine = (void *)2;
+public void *ml_search = (void *)1;
+public void *ml_examine = (void *)2;
 #if SHELL_ESCAPE || PIPEC
-public void * constant ml_shell = (void *)3;
+public void *ml_shell = (void *)3;
 #endif
 
 #endif /* CMD_HISTORY */
@@ -141,14 +141,14 @@ clear_cmd()
  */
        public void
 cmd_putstr(s)
-       char *s;
+       constant char *s;
 {
        LWCHAR prev_ch = 0;
        LWCHAR ch;
-       char *endline = s + strlen(s);
+       constant char *endline = s + strlen(s);
        while (*s != '\0')
        {
-               char *ns = s;
+               char *ns = (char *) s;
                int width;
                ch = step_char(&ns, +1, endline);
                while (s < ns)
@@ -262,7 +262,7 @@ cmd_step_left(pp, pwidth, bswidth)
  */
        static void
 cmd_repaint(old_cp)
-       char *old_cp;
+       constant char *old_cp;
 {
        /*
         * Repaint the line from the current position.
@@ -427,8 +427,9 @@ cmd_right()
 cmd_left()
 {
        char *ncp;
-       int width, bswidth;
-       
+       int width = 0;
+       int bswidth = 0;
+
        if (cp <= cmdbuf)
        {
                /* Already at the beginning of the line */
@@ -493,7 +494,7 @@ cmd_ichar(cs, clen)
        static int
 cmd_erase()
 {
-       register char *s;
+       char *s;
        int clen;
 
        if (cp == cmdbuf)
@@ -661,7 +662,7 @@ set_mlist(mlist, cmdflags)
 cmd_updown(action)
        int action;
 {
-       char *s;
+       constant char *s;
        struct mlist *ml;
        
        if (curr_mlist == NULL)
@@ -723,7 +724,7 @@ cmd_updown(action)
        public void
 cmd_addhist(mlist, cmd, modified)
        struct mlist *mlist;
-       char *cmd;
+       constant char *cmd;
        int modified;
 {
 #if CMD_HISTORY
@@ -940,7 +941,7 @@ delimit_word()
        char *p;
        int delim_quoted = 0;
        int meta_quoted = 0;
-       char *esc = get_meta_escape();
+       constant char *esc = get_meta_escape();
        int esclen = (int) strlen(esc);
 #endif
        
@@ -1223,6 +1224,13 @@ cmd_char(c)
                        *cmd_mbc_buf = c;
                        if (IS_ASCII_OCTET(c))
                                cmd_mbc_buf_len = 1;
+#if MSDOS_COMPILER || OS2
+                       else if (c == (unsigned char) '\340' && IS_ASCII_OCTET(peekcc()))
+                       {
+                               /* Assume a special key. */
+                               cmd_mbc_buf_len = 1;
+                       }
+#endif
                        else if (IS_UTF8_LEAD(c))
                        {
                                cmd_mbc_buf_len = utf_len(c);
index 955a18f..4338b3d 100644 (file)
--- a/command.c
+++ b/command.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -26,6 +26,7 @@ extern int quit_if_one_screen;
 extern int squished;
 extern int sc_width;
 extern int sc_height;
+extern char *kent;
 extern int swindow;
 extern int jump_sline;
 extern int quitting;
@@ -36,16 +37,18 @@ extern int secure;
 extern int hshift;
 extern int bs_mode;
 extern int show_attn;
+extern int status_col;
 extern POSITION highest_hilite;
+extern POSITION start_attnpos;
+extern POSITION end_attnpos;
 extern char *every_first_cmd;
-extern char *curr_altfilename;
 extern char version[];
 extern struct scrpos initial_scrpos;
 extern IFILE curr_ifile;
-extern void constant *ml_search;
-extern void constant *ml_examine;
+extern void *ml_search;
+extern void *ml_examine;
 #if SHELL_ESCAPE || PIPEC
-extern void constant *ml_shell;
+extern void *ml_shell;
 #endif
 #if EDITOR
 extern char *editor;
@@ -55,7 +58,6 @@ extern int screen_trashed;    /* The screen has been overwritten */
 extern int shift_count;
 extern int oldbot;
 extern int forw_prompt;
-extern int same_pos_bell;
 
 #if SHELL_ESCAPE
 static char *shellcmd = NULL;  /* For holding last shell command for "!!" */
@@ -75,10 +77,10 @@ static int save_bs_mode;
 static char pipec;
 #endif
 
+/* Stack of ungotten chars (via ungetcc) */
 struct ungot {
        struct ungot *ug_next;
-       char ug_char;
-       char ug_end_command;
+       LWCHAR ug_char;
 };
 static struct ungot* ungot = NULL;
 
@@ -92,9 +94,7 @@ static void multi_search();
        static void
 cmd_exec()
 {
-#if HILITE_SEARCH
-       clear_attn();
-#endif
+    clear_attn();
        clear_bot();
        flush();
 }
@@ -106,7 +106,7 @@ cmd_exec()
 start_mca(action, prompt, mlist, cmdflags)
        int action;
        constant char *prompt;
-       constant void *mlist;
+       void *mlist;
        int cmdflags;
 {
        mca = action;
@@ -206,7 +206,7 @@ mca_opt_toggle()
        static void
 exec_mca()
 {
-       register char *cbuf;
+       char *cbuf;
 
        cmd_exec();
        cbuf = get_cmdbuf();
@@ -301,11 +301,21 @@ is_erase_char(c)
 }
 
 /*
+ * Is a character a carriage return or newline?
+ */
+       static int
+is_newline_char(c)
+       int c;
+{
+       return (c == '\n' || c == '\r');
+}
+
+/*
  * Handle the first char of an option (after the initial dash).
  */
        static int
 mca_opt_first_char(c)
-    int c;
+       int c;
 {
        int flag = (optflag & ~OPT_NO_PROMPT);
        if (flag == OPT_NO_TOGGLE)
@@ -425,7 +435,7 @@ mca_opt_char(c)
        if (optgetname)
        {
                /* We're getting a long option name.  */
-               if (c != '\n' && c != '\r')
+               if (!is_newline_char(c))
                        return (mca_opt_nonfirst_char(c));
                if (curropt == NULL)
                {
@@ -589,7 +599,7 @@ mca_char(c)
        /*
         * The multichar command is terminated by a newline.
         */
-       if (c == '\n' || c == '\r')
+       if (is_newline_char(c))
        {
                /*
                 * Execute the command.
@@ -685,9 +695,9 @@ make_display()
        static void
 prompt()
 {
-       register constant char *p;
+       constant char *p;
 
-       if (ungot != NULL && !ungot->ug_end_command)
+       if (ungot != NULL && ungot->ug_char != CHAR_END_COMMAND)
        {
                /*
                 * No prompt necessary if commands are from 
@@ -769,74 +779,122 @@ dispversion()
 }
 
 /*
+ * Return a character to complete a partial command, if possible.
+ */
+       static LWCHAR
+getcc_end_command()
+{
+       switch (mca)
+       {
+       case A_DIGIT:
+               /* We have a number but no command.  Treat as #g. */
+               return ('g');
+       case A_F_SEARCH:
+       case A_B_SEARCH:
+               /* We have "/string" but no newline.  Add the \n. */
+               return ('\n'); 
+       default:
+               /* Some other incomplete command.  Let user complete it. */
+               return (getchr());
+       }
+}
+
+/*
  * Get command character.
  * The character normally comes from the keyboard,
  * but may come from ungotten characters
  * (characters previously given to ungetcc or ungetsc).
  */
-       public int
-getcc()
+       static LWCHAR
+getccu(VOID_PARAM)
 {
+       LWCHAR c;
        if (ungot == NULL)
        {
-               /*
-                * Normal case: no ungotten chars, so get one from the user.
-                */
-               return (getchr());
-       }
-
-       /*
-        * Return the next ungotten char.
-        */
+               /* Normal case: no ungotten chars.
+                * Get char from the user. */
+               c = getchr();
+       } else
        {
+               /* Ungotten chars available:
+                * Take the top of stack (most recent). */
                struct ungot *ug = ungot;
-               char c = ug->ug_char;
-               int end_command = ug->ug_end_command;
+               c = ug->ug_char;
                ungot = ug->ug_next;
                free(ug);
-               if (end_command)
-               {
-                       /*
-                        * Command is incomplete, so try to complete it.
-                        */
-                       switch (mca)
-                       {
-                       case A_DIGIT:
-                               /*
-                                * We have a number but no command.  Treat as #g.
-                                */
-                               return ('g');
 
-                       case A_F_SEARCH:
-                       case A_B_SEARCH:
-                               /*
-                                * We have "/string" but no newline.  Add the \n.
-                                */
-                               return ('\n'); 
+               if (c == CHAR_END_COMMAND)
+                       c = getcc_end_command();
+       }
+       return (c);
+}
 
-                       default:
-                               /*
-                                * Some other incomplete command.  Let user complete it.
-                                */
-                               return (getchr());
-                       }
+/*
+ * Get a command character, but if we receive the orig sequence,
+ * convert it to the repl sequence.
+ */
+       static LWCHAR
+getcc_repl(orig, repl, gr_getc, gr_ungetc)
+       char const* orig;
+       char const* repl;
+       LWCHAR (*gr_getc)(VOID_PARAM);
+       void (*gr_ungetc)(LWCHAR);
+{
+       LWCHAR c;
+       LWCHAR keys[16];
+       int ki = 0;
+
+       c = (*gr_getc)();
+       if (orig == NULL || orig[0] == '\0')
+               return c;
+       for (;;)
+       {
+               keys[ki] = c;
+               if (c != orig[ki] || ki >= sizeof(keys)-1)
+               {
+                       /* This is not orig we have been receiving.
+                        * If we have stashed chars in keys[],
+                        * unget them and return the first one. */
+                       while (ki > 0)
+                               (*gr_ungetc)(keys[ki--]);
+                       return keys[0];
                }
-               return (c);
+               if (orig[++ki] == '\0')
+               {
+                       /* We've received the full orig sequence.
+                        * Return the repl sequence. */
+                       ki = strlen(repl)-1;
+                       while (ki > 0)
+                               (*gr_ungetc)(repl[ki--]);
+                       return repl[0];
+               }
+               /* We've received a partial orig sequence (ki chars of it).
+                * Get next char and see if it continues to match orig. */
+               c = (*gr_getc)();
        }
 }
 
 /*
+ * Get command character.
+ */
+       public int
+getcc()
+{
+    /* Replace kent (keypad Enter) with a newline. */
+    return getcc_repl(kent, "\n", getccu, ungetcc);
+}
+
+/*
  * "Unget" a command character.
  * The next getcc() will return this character.
  */
        public void
 ungetcc(c)
-       int c;
+       LWCHAR c;
 {
        struct ungot *ug = (struct ungot *) ecalloc(1, sizeof(struct ungot));
 
-       ug->ug_char = (char) c;
-       ug->ug_end_command = (c == CHAR_END_COMMAND);
+       ug->ug_char = c;
        ug->ug_next = ungot;
        ungot = ug;
 }
@@ -849,13 +907,24 @@ ungetcc(c)
 ungetsc(s)
        char *s;
 {
-       register char *p;
+       char *p;
 
        for (p = s + strlen(s) - 1;  p >= s;  p--)
                ungetcc(*p);
 }
 
 /*
+ * Peek the next command character, without consuming it.
+ */
+       public LWCHAR
+peekcc()
+{
+       LWCHAR c = getcc();
+       ungetcc(c);
+       return c;
+}
+
+/*
  * Search for a pattern, possibly in multiple files.
  * If SRCH_FIRST_FILE is set, begin searching at the first file.
  * If SRCH_PAST_EOF is set, continue the search thru multiple files.
@@ -866,7 +935,7 @@ multi_search(pattern, n, silent)
        int n;
        int silent;
 {
-       register int nomore;
+       int nomore;
        IFILE save_ifile;
        int changed_file;
 
@@ -1001,9 +1070,9 @@ forw_loop(until_hilite)
        public void
 commands()
 {
-       register int c;
-       register int action;
-       register char *cbuf;
+       int c;
+       int action;
+       char *cbuf;
        int newaction;
        int save_search_type;
        char *extra;
@@ -1471,6 +1540,9 @@ commands()
                        break;
 
                case A_UNDO_SEARCH:
+                       /*
+                        * Clear search string highlighting.
+                        */
                        undo_search();
                        break;
 
@@ -1489,60 +1561,54 @@ commands()
                        break;
 
                case A_EXAMINE:
-#if EXAMINE
                        /*
                         * Edit a new file.  Get the filename.
                         */
-                       if (secure)
+#if EXAMINE
+                       if (!secure)
                        {
-                               error("Command not available", NULL_PARG);
-                               break;
+                               start_mca(A_EXAMINE, "Examine: ", ml_examine, 0);
+                               c = getcc();
+                               goto again;
                        }
-                       start_mca(A_EXAMINE, "Examine: ", ml_examine, 0);
-                       c = getcc();
-                       goto again;
-#else
+#endif
                        error("Command not available", NULL_PARG);
                        break;
-#endif
                        
                case A_VISUAL:
                        /*
                         * Invoke an editor on the input file.
                         */
 #if EDITOR
-                       if (secure)
+                       if (!secure)
                        {
-                               error("Command not available", NULL_PARG);
-                               break;
-                       }
-                       if (ch_getflags() & CH_HELPFILE)
-                               break;
-                       if (strcmp(get_filename(curr_ifile), "-") == 0)
-                       {
-                               error("Cannot edit standard input", NULL_PARG);
+                               if (ch_getflags() & CH_HELPFILE)
+                                       break;
+                               if (strcmp(get_filename(curr_ifile), "-") == 0)
+                               {
+                                       error("Cannot edit standard input", NULL_PARG);
+                                       break;
+                               }
+                               if (get_altfilename(curr_ifile) != NULL)
+                               {
+                                       error("WARNING: This file was viewed via LESSOPEN",
+                                               NULL_PARG);
+                               }
+                               start_mca(A_SHELL, "!", ml_shell, 0);
+                               /*
+                                * Expand the editor prototype string
+                                * and pass it to the system to execute.
+                                * (Make sure the screen is displayed so the
+                                * expansion of "+%lm" works.)
+                                */
+                               make_display();
+                               cmd_exec();
+                               lsystem(pr_expand(editproto, 0), (char*)NULL);
                                break;
                        }
-                       if (curr_altfilename != NULL)
-                       {
-                               error("WARNING: This file was viewed via LESSOPEN",
-                                       NULL_PARG);
-                       }
-                       start_mca(A_SHELL, "!", ml_shell, 0);
-                       /*
-                        * Expand the editor prototype string
-                        * and pass it to the system to execute.
-                        * (Make sure the screen is displayed so the
-                        * expansion of "+%lm" works.)
-                        */
-                       make_display();
-                       cmd_exec();
-                       lsystem(pr_expand(editproto, 0), (char*)NULL);
-                       break;
-#else
+#endif
                        error("Command not available", NULL_PARG);
                        break;
-#endif
 
                case A_NEXT_FILE:
                        /*
@@ -1588,6 +1654,9 @@ commands()
                        break;
 
                case A_NEXT_TAG:
+                       /*
+                        * Jump to the next tag in the current tag list.
+                        */
 #if TAGS
                        if (number <= 0)
                                number = 1;
@@ -1597,6 +1666,7 @@ commands()
                                error("No next tag", NULL_PARG);
                                break;
                        }
+                       cmd_exec();
                        if (edit(tagfile) == 0)
                        {
                                POSITION pos = tagsearch();
@@ -1609,6 +1679,9 @@ commands()
                        break;
 
                case A_PREV_TAG:
+                       /*
+                        * Jump to the previous tag in the current tag list.
+                        */
 #if TAGS
                        if (number <= 0)
                                number = 1;
@@ -1618,6 +1691,7 @@ commands()
                                error("No previous tag", NULL_PARG);
                                break;
                        }
+                       cmd_exec();
                        if (edit(tagfile) == 0)
                        {
                                POSITION pos = tagsearch();
@@ -1640,6 +1714,9 @@ commands()
                        break;
 
                case A_REMOVE_FILE:
+                       /*
+                        * Remove a file from the input file list.
+                        */
                        if (ch_getflags() & CH_HELPFILE)
                                break;
                        old_ifile = curr_ifile;
@@ -1658,6 +1735,9 @@ commands()
                        break;
 
                case A_OPT_TOGGLE:
+                       /*
+                        * Change the setting of an  option.
+                        */
                        optflag = OPT_TOGGLE;
                        optgetname = FALSE;
                        mca_opt_toggle();
@@ -1666,7 +1746,7 @@ commands()
 
                case A_DISP_OPTION:
                        /*
-                        * Report a flag setting.
+                        * Report the setting of an option.
                         */
                        optflag = OPT_NO_TOGGLE;
                        optgetname = FALSE;
@@ -1687,69 +1767,78 @@ commands()
                         * Shell escape.
                         */
 #if SHELL_ESCAPE
-                       if (secure)
+                       if (!secure)
                        {
-                               error("Command not available", NULL_PARG);
-                               break;
+                               start_mca(A_SHELL, "!", ml_shell, 0);
+                               c = getcc();
+                               goto again;
                        }
-                       start_mca(A_SHELL, "!", ml_shell, 0);
-                       c = getcc();
-                       goto again;
-#else
+#endif
                        error("Command not available", NULL_PARG);
                        break;
-#endif
 
                case A_SETMARK:
+               case A_SETMARKBOT:
                        /*
                         * Set a mark.
                         */
                        if (ch_getflags() & CH_HELPFILE)
                                break;
-                       start_mca(A_SETMARK, "mark: ", (void*)NULL, 0);
+                       start_mca(A_SETMARK, "set mark: ", (void*)NULL, 0);
                        c = getcc();
-                       if (c == erase_char || c == erase2_char ||
-                           c == kill_char || c == '\n' || c == '\r')
+                       if (is_erase_char(c) || is_newline_char(c))
                                break;
-                       setmark(c);
+                       setmark(c, action == A_SETMARKBOT ? BOTTOM : TOP);
+                       repaint();
+                       break;
+
+               case A_CLRMARK:
+                       /*
+                        * Clear a mark.
+                        */
+                       start_mca(A_CLRMARK, "clear mark: ", (void*)NULL, 0);
+                       c = getcc();
+                       if (is_erase_char(c) || is_newline_char(c))
+                               break;
+                       clrmark(c);
+                       repaint();
                        break;
 
                case A_GOMARK:
                        /*
-                        * Go to a mark.
+                        * Jump to a marked position.
                         */
                        start_mca(A_GOMARK, "goto mark: ", (void*)NULL, 0);
                        c = getcc();
-                       if (c == erase_char || c == erase2_char ||
-                           c == kill_char || c == '\n' || c == '\r')
+                       if (is_erase_char(c) || is_newline_char(c))
                                break;
                        cmd_exec();
                        gomark(c);
                        break;
 
                case A_PIPE:
+                       /*
+                        * Write part of the input to a pipe to a shell command.
+                        */
 #if PIPEC
-                       if (secure)
+                       if (!secure)
                        {
-                               error("Command not available", NULL_PARG);
-                               break;
+                               start_mca(A_PIPE, "|mark: ", (void*)NULL, 0);
+                               c = getcc();
+                               if (is_erase_char(c))
+                                       break;
+                               if (is_newline_char(c))
+                                       c = '.';
+                               if (badmark(c))
+                                       break;
+                               pipec = c;
+                               start_mca(A_PIPE, "!", ml_shell, 0);
+                               c = getcc();
+                               goto again;
                        }
-                       start_mca(A_PIPE, "|mark: ", (void*)NULL, 0);
-                       c = getcc();
-                       if (c == erase_char || c == erase2_char || c == kill_char)
-                               break;
-                       if (c == '\n' || c == '\r')
-                               c = '.';
-                       if (badmark(c))
-                               break;
-                       pipec = c;
-                       start_mca(A_PIPE, "!", ml_shell, 0);
-                       c = getcc();
-                       goto again;
-#else
+#endif
                        error("Command not available", NULL_PARG);
                        break;
-#endif
 
                case A_B_BRACKET:
                case A_F_BRACKET:
@@ -1758,6 +1847,9 @@ commands()
                        goto again;
 
                case A_LSHIFT:
+                       /*
+                        * Shift view left.
+                        */
                        if (number > 0)
                                shift_count = number;
                        else
@@ -1770,6 +1862,9 @@ commands()
                        break;
 
                case A_RSHIFT:
+                       /*
+                        * Shift view right.
+                        */
                        if (number > 0)
                                shift_count = number;
                        else
@@ -1780,11 +1875,17 @@ commands()
                        break;
 
                case A_LLSHIFT:
+                       /*
+                        * Shift view left to margin.
+                        */
                        hshift = 0;
                        screen_trashed = 1;
                        break;
 
                case A_RRSHIFT:
+                       /*
+                        * Shift view right to view rightmost char on screen.
+                        */
                        hshift = rrshift();
                        screen_trashed = 1;
                        break;
index e3e1fa4..2a4b180 100644 (file)
@@ -1,4 +1,5 @@
-/* Generated by "./mkutable -f2 Mn Me -- unicode/UnicodeData.txt" on Tue Sep 20 10:51:43 PDT 2016 */
+/* Generated by "./mkutable -f2 Mn Me Cf -- unicode/UnicodeData.txt" on Tue Jul 25 09:04:35 PDT 2017 */
+       { 0x00ad, 0x00ad }, /* Cf */
        { 0x0300, 0x036f }, /* Mn */
        { 0x0483, 0x0487 }, /* Mn */
        { 0x0488, 0x0489 }, /* Me */
@@ -7,13 +8,17 @@
        { 0x05c1, 0x05c2 }, /* Mn */
        { 0x05c4, 0x05c5 }, /* Mn */
        { 0x05c7, 0x05c7 }, /* Mn */
+       { 0x0600, 0x0605 }, /* Cf */
        { 0x0610, 0x061a }, /* Mn */
+       { 0x061c, 0x061c }, /* Cf */
        { 0x064b, 0x065f }, /* Mn */
        { 0x0670, 0x0670 }, /* Mn */
        { 0x06d6, 0x06dc }, /* Mn */
+       { 0x06dd, 0x06dd }, /* Cf */
        { 0x06df, 0x06e4 }, /* Mn */
        { 0x06e7, 0x06e8 }, /* Mn */
        { 0x06ea, 0x06ed }, /* Mn */
+       { 0x070f, 0x070f }, /* Cf */
        { 0x0711, 0x0711 }, /* Mn */
        { 0x0730, 0x074a }, /* Mn */
        { 0x07a6, 0x07b0 }, /* Mn */
@@ -24,6 +29,7 @@
        { 0x0829, 0x082d }, /* Mn */
        { 0x0859, 0x085b }, /* Mn */
        { 0x08d4, 0x08e1 }, /* Mn */
+       { 0x08e2, 0x08e2 }, /* Cf */
        { 0x08e3, 0x0902 }, /* Mn */
        { 0x093a, 0x093a }, /* Mn */
        { 0x093c, 0x093c }, /* Mn */
@@ -50,6 +56,7 @@
        { 0x0ac7, 0x0ac8 }, /* Mn */
        { 0x0acd, 0x0acd }, /* Mn */
        { 0x0ae2, 0x0ae3 }, /* Mn */
+       { 0x0afa, 0x0aff }, /* Mn */
        { 0x0b01, 0x0b01 }, /* Mn */
        { 0x0b3c, 0x0b3c }, /* Mn */
        { 0x0b3f, 0x0b3f }, /* Mn */
@@ -72,7 +79,8 @@
        { 0x0cc6, 0x0cc6 }, /* Mn */
        { 0x0ccc, 0x0ccd }, /* Mn */
        { 0x0ce2, 0x0ce3 }, /* Mn */
-       { 0x0d01, 0x0d01 }, /* Mn */
+       { 0x0d00, 0x0d01 }, /* Mn */
+       { 0x0d3b, 0x0d3c }, /* Mn */
        { 0x0d41, 0x0d44 }, /* Mn */
        { 0x0d4d, 0x0d4d }, /* Mn */
        { 0x0d62, 0x0d63 }, /* Mn */
        { 0x17c9, 0x17d3 }, /* Mn */
        { 0x17dd, 0x17dd }, /* Mn */
        { 0x180b, 0x180d }, /* Mn */
+       { 0x180e, 0x180e }, /* Cf */
        { 0x1885, 0x1886 }, /* Mn */
        { 0x18a9, 0x18a9 }, /* Mn */
        { 0x1920, 0x1922 }, /* Mn */
        { 0x1ced, 0x1ced }, /* Mn */
        { 0x1cf4, 0x1cf4 }, /* Mn */
        { 0x1cf8, 0x1cf9 }, /* Mn */
-       { 0x1dc0, 0x1df5 }, /* Mn */
+       { 0x1dc0, 0x1df9 }, /* Mn */
        { 0x1dfb, 0x1dff }, /* Mn */
+       { 0x200b, 0x200f }, /* Cf */
+       { 0x202a, 0x202e }, /* Cf */
+       { 0x2060, 0x2064 }, /* Cf */
+       { 0x2066, 0x206f }, /* Cf */
        { 0x20d0, 0x20dc }, /* Mn */
        { 0x20dd, 0x20e0 }, /* Me */
        { 0x20e1, 0x20e1 }, /* Mn */
        { 0xfb1e, 0xfb1e }, /* Mn */
        { 0xfe00, 0xfe0f }, /* Mn */
        { 0xfe20, 0xfe2f }, /* Mn */
+       { 0xfeff, 0xfeff }, /* Cf */
+       { 0xfff9, 0xfffb }, /* Cf */
        { 0x101fd, 0x101fd }, /* Mn */
        { 0x102e0, 0x102e0 }, /* Mn */
        { 0x10376, 0x1037a }, /* Mn */
        { 0x1107f, 0x11081 }, /* Mn */
        { 0x110b3, 0x110b6 }, /* Mn */
        { 0x110b9, 0x110ba }, /* Mn */
+       { 0x110bd, 0x110bd }, /* Cf */
        { 0x11100, 0x11102 }, /* Mn */
        { 0x11127, 0x1112b }, /* Mn */
        { 0x1112d, 0x11134 }, /* Mn */
        { 0x1171d, 0x1171f }, /* Mn */
        { 0x11722, 0x11725 }, /* Mn */
        { 0x11727, 0x1172b }, /* Mn */
+       { 0x11a01, 0x11a06 }, /* Mn */
+       { 0x11a09, 0x11a0a }, /* Mn */
+       { 0x11a33, 0x11a38 }, /* Mn */
+       { 0x11a3b, 0x11a3e }, /* Mn */
+       { 0x11a47, 0x11a47 }, /* Mn */
+       { 0x11a51, 0x11a56 }, /* Mn */
+       { 0x11a59, 0x11a5b }, /* Mn */
+       { 0x11a8a, 0x11a96 }, /* Mn */
+       { 0x11a98, 0x11a99 }, /* Mn */
        { 0x11c30, 0x11c36 }, /* Mn */
        { 0x11c38, 0x11c3d }, /* Mn */
        { 0x11c3f, 0x11c3f }, /* Mn */
        { 0x11caa, 0x11cb0 }, /* Mn */
        { 0x11cb2, 0x11cb3 }, /* Mn */
        { 0x11cb5, 0x11cb6 }, /* Mn */
+       { 0x11d31, 0x11d36 }, /* Mn */
+       { 0x11d3a, 0x11d3a }, /* Mn */
+       { 0x11d3c, 0x11d3d }, /* Mn */
+       { 0x11d3f, 0x11d45 }, /* Mn */
+       { 0x11d47, 0x11d47 }, /* Mn */
        { 0x16af0, 0x16af4 }, /* Mn */
        { 0x16b30, 0x16b36 }, /* Mn */
        { 0x16f8f, 0x16f92 }, /* Mn */
        { 0x1bc9d, 0x1bc9e }, /* Mn */
+       { 0x1bca0, 0x1bca3 }, /* Cf */
        { 0x1d167, 0x1d169 }, /* Mn */
+       { 0x1d173, 0x1d17a }, /* Cf */
        { 0x1d17b, 0x1d182 }, /* Mn */
        { 0x1d185, 0x1d18b }, /* Mn */
        { 0x1d1aa, 0x1d1ad }, /* Mn */
        { 0x1e026, 0x1e02a }, /* Mn */
        { 0x1e8d0, 0x1e8d6 }, /* Mn */
        { 0x1e944, 0x1e94a }, /* Mn */
+       { 0xe0001, 0xe0001 }, /* Cf */
+       { 0xe0020, 0xe007f }, /* Cf */
        { 0xe0100, 0xe01ef }, /* Mn */
index 53b4634..10a0305 100755 (executable)
--- a/configure
+++ b/configure
@@ -4713,6 +4713,30 @@ $as_echo "no" >&6; }
 fi
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
+# Checks for ANSI function prototypes.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI function prototypes" >&5
+$as_echo_n "checking for ANSI function prototypes... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+int f(int a) { return a; }
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }; $as_echo "#define HAVE_ANSI_PROTOS 1" >>confdefs.h
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
 # Checks for library functions.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5
 $as_echo_n "checking return type of signal handlers... " >&6; }
index 42bdd6b..3616ef0 100644 (file)
@@ -251,6 +251,11 @@ AC_TRY_COMPILE([#include <sys/types.h>
   [struct stat s; dev_t dev = s.st_dev; ino_t ino = s.st_ino;],
   [AC_MSG_RESULT(yes); AC_DEFINE(HAVE_STAT_INO)], [AC_MSG_RESULT(no)])
 
+# Checks for ANSI function prototypes.
+AC_MSG_CHECKING(for ANSI function prototypes)
+AC_TRY_COMPILE([], [int f(int a) { return a; }],
+  [AC_MSG_RESULT(yes); AC_DEFINE(HAVE_ANSI_PROTOS)], [AC_MSG_RESULT(no)])
+
 # Checks for library functions.
 AC_TYPE_SIGNAL
 AC_CHECK_FUNCS([fsync popen _setjmp sigprocmask sigsetmask snprintf stat system fchmod])
@@ -621,6 +626,11 @@ AH_TOP([
 #define TGETENT_OK  1
 
 /*
+ * HAVE_ANSI_PROTOS    is 1 if your compiler supports ANSI function prototypes.
+ */
+#define HAVE_ANSI_PROTOS       1
+
+/*
  * HAVE_SYS_TYPES_H is 1 if your system has <sys/types.h>.
  */
 #define HAVE_SYS_TYPES_H       1
@@ -649,7 +659,7 @@ AH_TOP([
 /*
  * Default shell metacharacters and meta-escape character.
  */
-#define        DEF_METACHARS   "; *?\t\n'\"()<>[]|&^`#\\$%=~"
+#define        DEF_METACHARS   "; *?\t\n'\"()<>[]|&^`#\\$%=~{},"
 #define        DEF_METAESCAPE  "\\"
 
 /* 
diff --git a/cvt.c b/cvt.c
index dc20b9c..3a77949 100644 (file)
--- a/cvt.c
+++ b/cvt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -65,7 +65,7 @@ cvt_text(odst, osrc, chpos, lenp, ops)
        char *dst;
        char *edst = odst;
        char *src;
-       register char *src_end;
+       char *src_end;
        LWCHAR ch;
 
        if (lenp != NULL)
@@ -83,7 +83,7 @@ cvt_text(odst, osrc, chpos, lenp, ops)
                        /* Delete backspace and preceding char. */
                        do {
                                dst--;
-                       } while (dst > odst &&
+                       } while (dst > odst && utf_mode &&
                                !IS_ASCII_OCTET(*dst) && !IS_UTF8_LEAD(*dst));
                } else if ((ops & CVT_ANSI) && IS_CSI_START(ch))
                {
index a24f6ef..80f47f9 100644 (file)
--- a/decode.c
+++ b/decode.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -140,6 +140,8 @@ static unsigned char cmdtable[] =
        ESC,'N',0,                      A_T_REVERSE_SEARCH,
        '&',0,                          A_FILTER,
        'm',0,                          A_SETMARK,
+       'M',0,                          A_SETMARKBOT,
+       ESC,'m',0,                      A_CLRMARK,
        '\'',0,                         A_GOMARK,
        CONTROL('X'),CONTROL('X'),0,    A_GOMARK,
        'E',0,                          A_EXAMINE,
@@ -237,9 +239,9 @@ expand_special_keys(table, len)
        char *table;
        int len;
 {
-       register char *fm;
-       register char *to;
-       register int a;
+       char *fm;
+       char *to;
+       int a;
        char *repl;
        int klen;
 
@@ -291,6 +293,33 @@ expand_special_keys(table, len)
 }
 
 /*
+ * Expand special key abbreviations in a list of command tables.
+ */
+       static void
+expand_cmd_table(tlist)
+       struct tablelist *tlist;
+{
+       struct tablelist *t;
+       for (t = tlist;  t != NULL;  t = t->t_next)
+       {
+               expand_special_keys(t->t_start, t->t_end - t->t_start);
+       }
+}
+
+/*
+ * Expand special key abbreviations in all command tables.
+ */
+       public void
+expand_cmd_tables()
+{
+       expand_cmd_table(list_fcmd_tables);
+       expand_cmd_table(list_ecmd_tables);
+       expand_cmd_table(list_var_tables);
+       expand_cmd_table(list_sysvar_tables);
+}
+
+
+/*
  * Initialize the command lists.
  */
        public void
@@ -329,7 +358,7 @@ add_cmd_table(tlist, buf, len)
        char *buf;
        int len;
 {
-       register struct tablelist *t;
+       struct tablelist *t;
 
        if (len == 0)
                return (0);
@@ -342,7 +371,6 @@ add_cmd_table(tlist, buf, len)
        {
                return (-1);
        }
-       expand_special_keys(buf, len);
        t->t_start = buf;
        t->t_end = buf + len;
        t->t_next = *tlist;
@@ -397,9 +425,9 @@ cmd_search(cmd, table, endtable, sp)
        char *endtable;
        char **sp;
 {
-       register char *p;
-       register char *q;
-       register int a;
+       char *p;
+       char *q;
+       int a;
 
        *sp = NULL;
        for (p = table, q = cmd;  p < endtable;  p++, q++)
@@ -488,8 +516,8 @@ cmd_decode(tlist, cmd, sp)
        char *cmd;
        char **sp;
 {
-       register struct tablelist *t;
-       register int action = A_INVALID;
+       struct tablelist *t;
+       int action = A_INVALID;
 
        /*
         * Search thru all the command tables.
@@ -599,8 +627,8 @@ new_lesskey(buf, len, sysvar)
        int sysvar;
 {
        char *p;
-       register int c;
-       register int n;
+       int c;
+       int n;
 
        /*
         * New-style lesskey file.
@@ -651,19 +679,17 @@ lesskey(filename, sysvar)
        char *filename;
        int sysvar;
 {
-       register char *buf;
-       register POSITION len;
-       register long n;
-       register int f;
+       char *buf;
+       POSITION len;
+       long n;
+       int f;
 
        if (secure)
                return (1);
        /*
         * Try to open the lesskey file.
         */
-       filename = shell_unquote(filename);
        f = open(filename, OPEN_READ);
-       free(filename);
        if (f < 0)
                return (1);
 
index 6009129..80a2d7b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
 #define        PATHNAME_SEP    "\\"
 
 /*
+ * HAVE_ANSI_PROTOS    is 1 if your compiler supports ANSI function prototypes.
+ */
+#define HAVE_ANSI_PROTOS       1
+
+/*
  * HAVE_SYS_TYPES_H is 1 if your system has <sys/types.h>.
  */
 #define HAVE_SYS_TYPES_H       1
index 46232c0..874c150 100644 (file)
 #define TGETENT_OK  1
 
 /*
+ * HAVE_ANSI_PROTOS    is 1 if your compiler supports ANSI function prototypes.
+ */
+#define HAVE_ANSI_PROTOS       1
+
+/*
  * HAVE_SYS_TYPES_H is 1 if your system has <sys/types.h>.
  */
 #define HAVE_SYS_TYPES_H       1
 /*
  * Default shell metacharacters and meta-escape character.
  */
-#define        DEF_METACHARS   "; *?\t\n'\"()<>[]|&^`#\\$%=~"
+#define        DEF_METACHARS   "; *?\t\n'\"()<>[]|&^`#\\$%=~{},"
 #define        DEF_METAESCAPE  "\\"
 
 /* 
index 615686b..4dba142 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
 #define        PATHNAME_SEP    "\\"
 
 /*
+ * HAVE_ANSI_PROTOS    is 1 if your compiler supports ANSI function prototypes.
+ */
+#define HAVE_ANSI_PROTOS       1
+
+/*
  * HAVE_SYS_TYPES_H is 1 if your system has <sys/types.h>.
  */
 #define HAVE_SYS_TYPES_H       1
index 2e7b957..99983d7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
 #define        PATHNAME_SEP    "/"
 
 /*
+ * HAVE_ANSI_PROTOS    is 1 if your compiler supports ANSI function prototypes.
+ */
+#define HAVE_ANSI_PROTOS       1
+
+/*
  * HAVE_SYS_TYPES_H is 1 if your system has <sys/types.h>.
  */
 #define HAVE_SYS_TYPES_H 0
index 6d6e242..98ca990 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
 #define        PATHNAME_SEP    "\\"
 
 /*
+ * HAVE_ANSI_PROTOS    is 1 if your compiler supports ANSI function prototypes.
+ */
+#define HAVE_ANSI_PROTOS       1
+
+/*
  * HAVE_SYS_TYPES_H is 1 if your system has <sys/types.h>.
  */
 #define HAVE_SYS_TYPES_H       1
diff --git a/edit.c b/edit.c
index c508f94..7dc80bb 100644 (file)
--- a/edit.c
+++ b/edit.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -9,9 +9,13 @@
 
 
 #include "less.h"
+#include "position.h"
 #if HAVE_STAT
 #include <sys/stat.h>
 #endif
+#if OS2
+#include <signal.h>
+#endif
 
 public int fd0 = 0;
 
@@ -26,7 +30,7 @@ extern int sigs;
 extern IFILE curr_ifile;
 extern IFILE old_ifile;
 extern struct scrpos initial_scrpos;
-extern void constant *ml_examine;
+extern void *ml_examine;
 #if SPACES_IN_FILENAMES
 extern char openquote;
 extern char closequote;
@@ -43,9 +47,6 @@ public dev_t curr_dev;
 public ino_t curr_ino;
 #endif
 
-char *curr_altfilename = NULL;
-static void *curr_altpipe;
-
 
 /*
  * Textlist functions deal with a list of words separated by spaces.
@@ -149,12 +150,33 @@ back_textlist(tlist, prev)
 }
 
 /*
+ * Close a pipe opened via popen.
+ */
+       static void
+close_pipe(FILE *pipefd)
+{
+       if (pipefd == NULL)
+               return;
+#if OS2
+       /*
+        * The pclose function of OS/2 emx sometimes fails.
+        * Send SIGINT to the piped process before closing it.
+        */
+       kill(pipefd->_pid, SIGINT);
+#endif
+       pclose(pipefd);
+}
+
+/*
  * Close the current input file.
  */
        static void
 close_file()
 {
        struct scrpos scrpos;
+       int chflags;
+       FILE *altpipe;
+       char *altfilename;
        
        if (curr_ifile == NULL_IFILE)
                return;
@@ -163,7 +185,7 @@ close_file()
         * Save the current position so that we can return to
         * the same position if we edit this file again.
         */
-       get_scrpos(&scrpos);
+       get_scrpos(&scrpos, TOP);
        if (scrpos.pos != NULL_POSITION)
        {
                store_pos(curr_ifile, &scrpos);
@@ -172,17 +194,23 @@ close_file()
        /*
         * Close the file descriptor, unless it is a pipe.
         */
+       chflags = ch_getflags();
        ch_close();
        /*
         * If we opened a file using an alternate name,
         * do special stuff to close it.
         */
-       if (curr_altfilename != NULL)
+       altfilename = get_altfilename(curr_ifile);
+       if (altfilename != NULL)
        {
-               close_altfile(curr_altfilename, get_filename(curr_ifile),
-                               curr_altpipe);
-               free(curr_altfilename);
-               curr_altfilename = NULL;
+               altpipe = get_altpipe(curr_ifile);
+               if (altpipe != NULL && !(chflags & CH_KEEPOPEN))
+               {
+                       close_pipe(altpipe);
+                       set_altpipe(curr_ifile, NULL);
+               }
+               close_altfile(altfilename, get_filename(curr_ifile));
+               set_altfilename(curr_ifile, NULL);
        }
        curr_ifile = NULL_IFILE;
 #if HAVE_STAT_INO
@@ -218,9 +246,8 @@ edit_ifile(ifile)
        int chflags;
        char *filename;
        char *open_filename;
-       char *qopen_filename;
        char *alt_filename;
-       void *alt_pipe;
+       void *altpipe;
        IFILE was_curr_ifile;
        PARG parg;
                
@@ -270,107 +297,129 @@ edit_ifile(ifile)
        }
 
        filename = save(get_filename(ifile));
+
        /*
         * See if LESSOPEN specifies an "alternate" file to open.
         */
-       alt_pipe = NULL;
-       alt_filename = open_altfile(filename, &f, &alt_pipe);
-       open_filename = (alt_filename != NULL) ? alt_filename : filename;
-       qopen_filename = shell_unquote(open_filename);
-
-       chflags = 0;
-       if (alt_pipe != NULL)
+       altpipe = get_altpipe(ifile);
+       if (altpipe != NULL)
        {
                /*
-                * The alternate "file" is actually a pipe.
-                * f has already been set to the file descriptor of the pipe
-                * in the call to open_altfile above.
-                * Keep the file descriptor open because it was opened 
-                * via popen(), and pclose() wants to close it.
+                * File is already open.
+                * chflags and f are not used by ch_init if ifile has 
+                * filestate which should be the case if we're here. 
+                * Set them here to avoid uninitialized variable warnings.
                 */
-               chflags |= CH_POPENED;
-       } else if (strcmp(open_filename, "-") == 0)
-       {
-               /* 
-                * Use standard input.
-                * Keep the file descriptor open because we can't reopen it.
-                */
-               f = fd0;
-               chflags |= CH_KEEPOPEN;
-               /*
-                * Must switch stdin to BINARY mode.
-                */
-               SET_BINARY(f);
-#if MSDOS_COMPILER==DJGPPC
-               /*
-                * Setting stdin to binary by default causes
-                * Ctrl-C to not raise SIGINT.  We must undo
-                * that side-effect.
-                */
-               __djgpp_set_ctrl_c(1);
-#endif
-       } else if (strcmp(open_filename, FAKE_EMPTYFILE) == 0)
-       {
+               chflags = 0; 
                f = -1;
-               chflags |= CH_NODATA;
-       } else if (strcmp(open_filename, FAKE_HELPFILE) == 0)
-       {
-               f = -1;
-               chflags |= CH_HELPFILE;
-       } else if ((parg.p_string = bad_file(open_filename)) != NULL)
+               alt_filename = get_altfilename(ifile);
+               open_filename = (alt_filename != NULL) ? alt_filename : filename;
+       } else
        {
-               /*
-                * It looks like a bad file.  Don't try to open it.
-                */
-               error("%s", &parg);
-               free(parg.p_string);
-           err1:
-               if (alt_filename != NULL)
+               if (strcmp(filename, FAKE_HELPFILE) == 0 ||
+                        strcmp(filename, FAKE_EMPTYFILE) == 0)
+                       alt_filename = NULL;
+               else
+                       alt_filename = open_altfile(filename, &f, &altpipe);
+
+               open_filename = (alt_filename != NULL) ? alt_filename : filename;
+
+               chflags = 0;
+               if (altpipe != NULL)
                {
-                       close_altfile(alt_filename, filename, alt_pipe);
-                       free(alt_filename);
-               }
-               del_ifile(ifile);
-               free(qopen_filename);
-               free(filename);
-               /*
-                * Re-open the current file.
-                */
-               if (was_curr_ifile == ifile)
+                       /*
+                        * The alternate "file" is actually a pipe.
+                        * f has already been set to the file descriptor of the pipe
+                        * in the call to open_altfile above.
+                        * Keep the file descriptor open because it was opened 
+                        * via popen(), and pclose() wants to close it.
+                        */
+                       chflags |= CH_POPENED;
+                       if (strcmp(filename, "-") == 0)
+                               chflags |= CH_KEEPOPEN;
+               } else if (strcmp(filename, "-") == 0)
                {
+                       /* 
+                        * Use standard input.
+                        * Keep the file descriptor open because we can't reopen it.
+                        */
+                       f = fd0;
+                       chflags |= CH_KEEPOPEN;
                        /*
-                        * Whoops.  The "current" ifile is the one we just deleted.
-                        * Just give up.
+                        * Must switch stdin to BINARY mode.
                         */
-                       quit(QUIT_ERROR);
-               }
-               reedit_ifile(was_curr_ifile);
-               return (1);
-       } else if ((f = open(qopen_filename, OPEN_READ)) < 0)
-       {
-               /*
-                * Got an error trying to open it.
-                */
-               parg.p_string = errno_message(filename);
-               error("%s", &parg);
-               free(parg.p_string);
-               goto err1;
-       } else 
-       {
-               chflags |= CH_CANSEEK;
-               if (!force_open && !opened(ifile) && bin_file(f))
+                       SET_BINARY(f);
+#if MSDOS_COMPILER==DJGPPC
+                       /*
+                        * Setting stdin to binary by default causes
+                        * Ctrl-C to not raise SIGINT.  We must undo
+                        * that side-effect.
+                        */
+                       __djgpp_set_ctrl_c(1);
+#endif
+               } else if (strcmp(open_filename, FAKE_EMPTYFILE) == 0)
+               {
+                       f = -1;
+                       chflags |= CH_NODATA;
+               } else if (strcmp(open_filename, FAKE_HELPFILE) == 0)
+               {
+                       f = -1;
+                       chflags |= CH_HELPFILE;
+               } else if ((parg.p_string = bad_file(open_filename)) != NULL)
                {
                        /*
-                        * Looks like a binary file.  
-                        * Ask user if we should proceed.
+                        * It looks like a bad file.  Don't try to open it.
                         */
-                       parg.p_string = filename;
-                       answer = query("\"%s\" may be a binary file.  See it anyway? ",
-                               &parg);
-                       if (answer != 'y' && answer != 'Y')
+                       error("%s", &parg);
+                       free(parg.p_string);
+                       err1:
+                       if (alt_filename != NULL)
                        {
-                               close(f);
+                               close_pipe(altpipe);
+                               close_altfile(alt_filename, filename);
+                               free(alt_filename);
+                       }
+                       del_ifile(ifile);
+                       free(filename);
+                       /*
+                        * Re-open the current file.
+                        */
+                       if (was_curr_ifile == ifile)
+                       {
+                               /*
+                                * Whoops.  The "current" ifile is the one we just deleted.
+                                * Just give up.
+                                */
+                               quit(QUIT_ERROR);
+                       }
+                       reedit_ifile(was_curr_ifile);
+                       return (1);
+               } else if ((f = open(open_filename, OPEN_READ)) < 0)
+               {
+                       /*
+                        * Got an error trying to open it.
+                        */
+                       parg.p_string = errno_message(filename);
+                       error("%s", &parg);
+                       free(parg.p_string);
                                goto err1;
+               } else 
+               {
+                       chflags |= CH_CANSEEK;
+                       if (!force_open && !opened(ifile) && bin_file(f))
+                       {
+                               /*
+                                * Looks like a binary file.  
+                                * Ask user if we should proceed.
+                                */
+                               parg.p_string = filename;
+                               answer = query("\"%s\" may be a binary file.  See it anyway? ",
+                                       &parg);
+                               if (answer != 'y' && answer != 'Y')
+                               {
+                                       close(f);
+                                       goto err1;
+                               }
                        }
                }
        }
@@ -385,8 +434,8 @@ edit_ifile(ifile)
                unsave_ifile(was_curr_ifile);
        }
        curr_ifile = ifile;
-       curr_altfilename = alt_filename;
-       curr_altpipe = alt_pipe;
+       set_altfilename(curr_ifile, alt_filename);
+       set_altpipe(curr_ifile, altpipe);
        set_open(curr_ifile); /* File has been opened */
        get_pos(curr_ifile, &initial_scrpos);
        new_file = TRUE;
@@ -400,9 +449,10 @@ edit_ifile(ifile)
 #endif
 #if HAVE_STAT_INO
                /* Remember the i-number and device of the opened file. */
+               if (strcmp(open_filename, "-") != 0)
                {
                        struct stat statbuf;
-                       int r = stat(qopen_filename, &statbuf);
+                       int r = stat(open_filename, &statbuf);
                        if (r == 0)
                        {
                                curr_ino = statbuf.st_ino;
@@ -417,7 +467,6 @@ edit_ifile(ifile)
                }
        }
 
-       free(qopen_filename);
        no_display = !any_display;
        flush();
        any_display = TRUE;
@@ -468,6 +517,7 @@ edit_list(filelist)
        char *filename;
        char *gfilelist;
        char *gfilename;
+       char *qfilename;
        struct textlist tl_files;
        struct textlist tl_gfiles;
 
@@ -489,8 +539,10 @@ edit_list(filelist)
                gfilename = NULL;
                while ((gfilename = forw_textlist(&tl_gfiles, gfilename)) != NULL)
                {
-                       if (edit(gfilename) == 0 && good_filename == NULL)
+                       qfilename = shell_unquote(gfilename);
+                       if (edit(qfilename) == 0 && good_filename == NULL)
                                good_filename = get_filename(curr_ifile);
+                       free(qfilename);
                }
                free(gfilelist);
        }
@@ -716,7 +768,7 @@ edit_stdin()
        public void
 cat_file()
 {
-       register int c;
+       int c;
 
        while ((c = ch_forw_get()) != EOI)
                putchr(c);
@@ -734,8 +786,8 @@ cat_file()
 use_logfile(filename)
        char *filename;
 {
-       register int exists;
-       register int answer;
+       int exists;
+       int answer;
        PARG parg;
 
        if (ch_getflags() & CH_CANSEEK)
@@ -747,7 +799,6 @@ use_logfile(filename)
        /*
         * {{ We could use access() here. }}
         */
-       filename = shell_unquote(filename);
        exists = open(filename, OPEN_READ);
        if (exists >= 0)
                close(exists);
@@ -816,10 +867,8 @@ loop:
                 */
                parg.p_string = filename;
                error("Cannot write to \"%s\"", &parg);
-               free(filename);
                return;
        }
-       free(filename);
        SET_BINARY(logfile);
 }
 
index 62cc6e5..983a02b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -32,9 +32,6 @@
 #include <modes.h>
 #endif
 #endif
-#if OS2
-#include <signal.h>
-#endif
 
 #if HAVE_STAT
 #include <sys/stat.h>
@@ -46,7 +43,6 @@
 #endif
 #endif
 
-
 extern int force_open;
 extern int secure;
 extern int use_lessopen;
@@ -226,7 +222,6 @@ dirfile(dirname, filename)
        char *filename;
 {
        char *pathname;
-       char *qpathname;
        int len;
        int f;
 
@@ -243,8 +238,7 @@ dirfile(dirname, filename)
        /*
         * Make sure the file exists.
         */
-       qpathname = shell_unquote(pathname);
-       f = open(qpathname, OPEN_READ);
+       f = open(pathname, OPEN_READ);
        if (f < 0)
        {
                free(pathname);
@@ -253,7 +247,6 @@ dirfile(dirname, filename)
        {
                close(f);
        }
-       free(qpathname);
        return (pathname);
 }
 
@@ -264,7 +257,7 @@ dirfile(dirname, filename)
 homefile(filename)
        char *filename;
 {
-       register char *pathname;
+       char *pathname;
 
        /*
         * Try $HOME/filename.
@@ -314,9 +307,9 @@ homefile(filename)
 fexpand(s)
        char *s;
 {
-       register char *fr, *to;
-       register int n;
-       register char *e;
+       char *fr, *to;
+       int n;
+       char *e;
        IFILE ifile;
 
 #define        fchar_ifile(c) \
@@ -474,7 +467,7 @@ bin_file(f)
        int bin_count = 0;
        char data[256];
        char* p;
-       char* pend;
+       char* edata;
 
        if (!seekable(f))
                return (0);
@@ -483,21 +476,19 @@ bin_file(f)
        n = read(f, data, sizeof(data));
        if (n <= 0)
                return (0);
-       if (utf_mode)
+       edata = &data[n];
+       for (p = data;  p < edata;  )
        {
-               bin_count = utf_bin_count(data, n);
-       } else
-       {
-               pend = &data[n];
-               for (p = data;  p < pend;  )
+               if (utf_mode && !is_utf8_well_formed(p, edata-data))
                {
-                       LWCHAR c = step_char(&p, +1, pend);
+                       bin_count++;
+                       utf_skip_to_lead(&p, edata);
+               } else 
+               {
+                       LWCHAR c = step_char(&p, +1, edata);
                        if (ctldisp == OPT_ONPLUS && IS_CSI_START(c))
-                       {
-                               do {
-                                       c = step_char(&p, +1, pend);
-                               } while (p < pend && is_ansi_middle(c));
-                       } else if (binary_char(c))
+                               skip_ansi(&p, edata);
+                       else if (binary_char(c))
                                bin_count++;
                }
        }
@@ -632,12 +623,10 @@ lglob(filename)
        char *filename;
 {
        char *gfilename;
-       char *ofilename;
 
-       ofilename = fexpand(filename);
+       filename = fexpand(filename);
        if (secure)
-               return (ofilename);
-       filename = shell_unquote(ofilename);
+               return (filename);
 
 #ifdef DECL_GLOB_LIST
 {
@@ -652,8 +641,7 @@ lglob(filename)
        GLOB_LIST(filename, list);
        if (GLOB_LIST_FAILED(list))
        {
-               free(filename);
-               return (ofilename);
+               return (filename);
        }
        length = 1; /* Room for trailing null byte */
        for (SCAN_GLOB_LIST(list, p))
@@ -690,18 +678,17 @@ lglob(filename)
         * The globbing function returns a single name, and
         * is called multiple times to walk thru all names.
         */
-       register char *p;
-       register int len;
-       register int n;
-       char *pathname;
-       char *qpathname;
+       char *p;
+       int len;
+       int n;
+       char *pfilename;
+       char *qfilename;
        DECL_GLOB_NAME(fnd,drive,dir,fname,ext,handle)
        
        GLOB_FIRST_NAME(filename, &fnd, handle);
        if (GLOB_FIRST_FAILED(handle))
        {
-               free(filename);
-               return (ofilename);
+               return (filename);
        }
 
        _splitpath(filename, drive, dir, fname, ext);
@@ -710,13 +697,13 @@ lglob(filename)
        p = gfilename;
        do {
                n = (int) (strlen(drive) + strlen(dir) + strlen(fnd.GLOB_NAME) + 1);
-               pathname = (char *) ecalloc(n, sizeof(char));
-               SNPRINTF3(pathname, n, "%s%s%s", drive, dir, fnd.GLOB_NAME);
-               qpathname = shell_quote(pathname);
-               free(pathname);
-               if (qpathname != NULL)
+               pfilename = (char *) ecalloc(n, sizeof(char));
+               SNPRINTF3(pfilename, n, "%s%s%s", drive, dir, fnd.GLOB_NAME);
+               qfilename = shell_quote(pfilename);
+               free(pfilename);
+               if (qfilename != NULL)
                {
-                       n = (int) strlen(qpathname);
+                       n = (int) strlen(qfilename);
                        while (p - gfilename + n + 2 >= len)
                        {
                                /*
@@ -731,8 +718,8 @@ lglob(filename)
                                gfilename = p;
                                p = gfilename + strlen(gfilename);
                        }
-                       strcpy(p, qpathname);
-                       free(qpathname);
+                       strcpy(p, qfilename);
+                       free(qfilename);
                        p += n;
                        *p++ = ' ';
                }
@@ -764,8 +751,7 @@ lglob(filename)
        esc = shell_quote(esc);
        if (esc == NULL)
        {
-               free(filename);
-               return (ofilename);
+               return (filename);
        }
        lessecho = lgetenv("LESSECHO");
        if (lessecho == NULL || *lessecho == '\0')
@@ -773,13 +759,13 @@ lglob(filename)
        /*
         * Invoke lessecho, and read its output (a globbed list of filenames).
         */
-       len = (int) (strlen(lessecho) + strlen(ofilename) + (7*strlen(metachars())) + 24);
+       len = (int) (strlen(lessecho) + strlen(filename) + (7*strlen(metachars())) + 24);
        cmd = (char *) ecalloc(len, sizeof(char));
        SNPRINTF4(cmd, len, "%s -p0x%x -d0x%x -e%s ", lessecho, openquote, closequote, esc);
        free(esc);
        for (s = metachars();  *s != '\0';  s++)
                sprintf(cmd + strlen(cmd), "-n0x%x ", *s);
-       sprintf(cmd + strlen(cmd), "-- %s", ofilename);
+       sprintf(cmd + strlen(cmd), "-- %s", filename);
        fd = shellcmd(cmd);
        free(cmd);
        if (fd == NULL)
@@ -788,16 +774,14 @@ lglob(filename)
                 * Cannot create the pipe.
                 * Just return the original (fexpanded) filename.
                 */
-               free(filename);
-               return (ofilename);
+               return (filename);
        }
        gfilename = readfd(fd);
        pclose(fd);
        if (*gfilename == '\0')
        {
                free(gfilename);
-               free(filename);
-               return (ofilename);
+               return (save(filename));
        }
 }
 #else
@@ -809,7 +793,6 @@ lglob(filename)
 #endif
 #endif
        free(filename);
-       free(ofilename);
        return (gfilename);
 }
 
@@ -853,6 +836,7 @@ open_altfile(filename, pf, pfd)
        return (NULL);
 #else
        char *lessopen;
+       char *qfilename;
        char *cmd;
        int len;
        FILE *fd;
@@ -879,24 +863,28 @@ open_altfile(filename, pf, pfd)
                returnfd++;
 #endif
        }
-       if (*lessopen == '-') {
+       if (*lessopen == '-')
+       {
                /*
                 * Lessopen preprocessor will accept "-" as a filename.
                 */
                lessopen++;
-       } else {
+       } else
+       {
                if (strcmp(filename, "-") == 0)
                        return (NULL);
        }
-       if (num_pct_s(lessopen) > 1)
+       if (num_pct_s(lessopen) != 1)
        {
-               error("Invalid LESSOPEN variable", NULL_PARG);
+               error("LESSOPEN ignored: must contain exactly one %%s", NULL_PARG);
                return (NULL);
        }
 
-       len = (int) (strlen(lessopen) + strlen(filename) + 2);
+       qfilename = shell_quote(filename);
+       len = (int) (strlen(lessopen) + strlen(qfilename) + 2);
        cmd = (char *) ecalloc(len, sizeof(char));
-       SNPRINTF1(cmd, len, lessopen, filename);
+       SNPRINTF1(cmd, len, lessopen, qfilename);
+       free(qfilename);
        fd = shellcmd(cmd);
        free(cmd);
        if (fd == NULL)
@@ -909,11 +897,12 @@ open_altfile(filename, pf, pfd)
 #if HAVE_FILENO
        if (returnfd)
        {
-               int f;
                char c;
+               int f;
 
                /*
-                * Read one char to see if the pipe will produce any data.
+                * The first time we open the file, read one char 
+                * to see if the pipe will produce any data.
                 * If it does, push the char back on the pipe.
                 */
                f = fileno(fd);
@@ -956,10 +945,9 @@ open_altfile(filename, pf, pfd)
  * Close a replacement file.
  */
        public void
-close_altfile(altfilename, filename, pipefd)
+close_altfile(altfilename, filename)
        char *altfilename;
        char *filename;
-       void *pipefd;
 {
 #if HAVE_POPEN
        char *lessclose;
@@ -969,22 +957,12 @@ close_altfile(altfilename, filename, pipefd)
        
        if (secure)
                return;
-       if (pipefd != NULL)
-       {
-#if OS2
-               /*
-                * The pclose function of OS/2 emx sometimes fails.
-                * Send SIGINT to the piped process before closing it.
-                */
-               kill(((FILE*)pipefd)->_pid, SIGINT);
-#endif
-               pclose((FILE*) pipefd);
-       }
+       ch_ungetchar(-1);
        if ((lessclose = lgetenv("LESSCLOSE")) == NULL)
                return;
        if (num_pct_s(lessclose) > 2) 
        {
-               error("Invalid LESSCLOSE variable", NULL_PARG);
+               error("LESSCLOSE ignored; must contain no more than 2 %%s", NULL_PARG);
                return;
        }
        len = (int) (strlen(lessclose) + strlen(filename) + strlen(altfilename) + 2);
@@ -1006,7 +984,6 @@ is_dir(filename)
 {
        int isdir = 0;
 
-       filename = shell_unquote(filename);
 #if HAVE_STAT
 {
        int r;
@@ -1018,7 +995,7 @@ is_dir(filename)
 #else
 #ifdef _OSK
 {
-       register int f;
+       int f;
 
        f = open(filename, S_IREAD | S_IFDIR);
        if (f >= 0)
@@ -1027,7 +1004,6 @@ is_dir(filename)
 }
 #endif
 #endif
-       free(filename);
        return (isdir);
 }
 
@@ -1040,9 +1016,8 @@ is_dir(filename)
 bad_file(filename)
        char *filename;
 {
-       register char *m = NULL;
+       char *m = NULL;
 
-       filename = shell_unquote(filename);
        if (!force_open && is_dir(filename))
        {
                static char is_a_dir[] = " is a directory";
@@ -1074,7 +1049,6 @@ bad_file(filename)
                }
 #endif
        }
-       free(filename);
        return (m);
 }
 
diff --git a/fmt.uni b/fmt.uni
new file mode 100644 (file)
index 0000000..a0bad77
--- /dev/null
+++ b/fmt.uni
@@ -0,0 +1,19 @@
+/* Generated by "./mkutable -f2 Cf -- unicode/UnicodeData.txt" on Sun Nov 12 16:13:49 PST 2017 */
+       { 0x00ad, 0x00ad }, /* Cf */
+       { 0x0600, 0x0605 }, /* Cf */
+       { 0x061c, 0x061c }, /* Cf */
+       { 0x06dd, 0x06dd }, /* Cf */
+       { 0x070f, 0x070f }, /* Cf */
+       { 0x08e2, 0x08e2 }, /* Cf */
+       { 0x180e, 0x180e }, /* Cf */
+       { 0x200b, 0x200f }, /* Cf */
+       { 0x202a, 0x202e }, /* Cf */
+       { 0x2060, 0x2064 }, /* Cf */
+       { 0x2066, 0x206f }, /* Cf */
+       { 0xfeff, 0xfeff }, /* Cf */
+       { 0xfff9, 0xfffb }, /* Cf */
+       { 0x110bd, 0x110bd }, /* Cf */
+       { 0x1bca0, 0x1bca3 }, /* Cf */
+       { 0x1d173, 0x1d17a }, /* Cf */
+       { 0xe0001, 0xe0001 }, /* Cf */
+       { 0xe0020, 0xe007f }, /* Cf */
index 83ae78e..680fa25 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -124,7 +124,7 @@ squish_check()
  */
        public void
 forw(n, pos, force, only_last, nblank)
-       register int n;
+       int n;
        POSITION pos;
        int force;
        int only_last;
@@ -285,7 +285,7 @@ forw(n, pos, force, only_last, nblank)
                forw_prompt = 1;
        }
 
-       if (nlines == 0 && same_pos_bell)
+       if (nlines == 0 && !ignore_eoi && same_pos_bell)
                eof_bell();
        else if (do_repaint)
                repaint();
@@ -298,7 +298,7 @@ forw(n, pos, force, only_last, nblank)
  */
        public void
 back(n, pos, force, only_last)
-       register int n;
+       int n;
        POSITION pos;
        int force;
        int only_last;
@@ -444,3 +444,21 @@ get_back_scroll()
                return (sc_height - 2);
        return (10000); /* infinity */
 }
+
+/*
+ * Return number of displayable lines in the file.
+ * Stop counting at screen height + 1.
+ */
+       public int
+get_line_count()
+{
+       int nlines;
+       POSITION pos = ch_zero();
+
+       for (nlines = 0;  nlines <= sc_height;  nlines++)
+       {
+               pos = forw_line(pos);
+               if (pos == NULL_POSITION) break;
+       }
+       return nlines;
+}
diff --git a/funcs.h b/funcs.h
index ac63c37..d70c359 100644 (file)
--- a/funcs.h
+++ b/funcs.h
-       public char * save ();
-       public VOID_POINTER ecalloc ();
-       public char * skipsp ();
-       public int sprefix ();
-       public void quit ();
-       public void raw_mode ();
-       public void scrsize ();
-       public char * special_key_str ();
-       public void get_term ();
-       public void init ();
-       public void deinit ();
-       public void home ();
-       public void add_line ();
-       public void remove_top ();
-       public void win32_scroll_up ();
-       public void lower_left ();
-       public void line_left ();
-       public void check_winch ();
-       public void goto_line ();
-       public void vbell ();
-       public void bell ();
-       public void clear ();
-       public void clear_eol ();
-       public void clear_bot ();
-       public void at_enter ();
-       public void at_exit ();
-       public void at_switch ();
-       public int is_at_equiv ();
-       public int apply_at_specials ();
-       public void backspace ();
-       public void putbs ();
-       public char WIN32getch ();
-       public void WIN32setcolors ();
-       public void WIN32textout ();
-       public void match_brac ();
-       public void ch_ungetchar ();
-       public void end_logfile ();
-       public void sync_logfile ();
-       public int ch_seek ();
-       public int ch_end_seek ();
-       public int ch_end_buffer_seek ();
-       public int ch_beg_seek ();
-       public POSITION ch_length ();
-       public POSITION ch_tell ();
-       public int ch_forw_get ();
-       public int ch_back_get ();
-       public void ch_setbufspace ();
-       public void ch_flush ();
-       public int seekable ();
-       public void ch_set_eof ();
-       public void ch_init ();
-       public void ch_close ();
-       public int ch_getflags ();
-       public void ch_dump ();
-       public void init_charset ();
-       public int binary_char ();
-       public int control_char ();
-       public char * prchar ();
-       public char * prutfchar ();
-       public int utf_len ();
-       public int is_utf8_well_formed ();
-       public int utf_bin_count ();
-       public LWCHAR get_wchar ();
-       public void put_wchar ();
-       public LWCHAR step_char ();
-       public int is_composing_char ();
-       public int is_ubin_char ();
-       public int is_wide_char ();
-       public int is_combining_char ();
-       public void cmd_reset ();
-       public void clear_cmd ();
-       public void cmd_putstr ();
-       public int len_cmdbuf ();
-       public void set_mlist ();
-       public void cmd_addhist ();
-       public void cmd_accept ();
-       public int cmd_char ();
-       public LINENUM cmd_int ();
-       public char * get_cmdbuf ();
-       public char * cmd_lastpattern ();
-       public void init_cmdhist ();
-       public void save_cmdhist ();
-       public int in_mca ();
-       public void dispversion ();
-       public int getcc ();
-       public void ungetcc ();
-       public void ungetsc ();
-       public void commands ();
-       public int cvt_length ();
-       public int * cvt_alloc_chpos ();
-       public void cvt_text ();
-       public void init_cmds ();
-       public void add_fcmd_table ();
-       public void add_ecmd_table ();
-       public int fcmd_decode ();
-       public int ecmd_decode ();
-       public char * lgetenv ();
-       public int lesskey ();
-       public void add_hometable ();
-       public int editchar ();
-       public void init_textlist ();
-       public char * forw_textlist ();
-       public char * back_textlist ();
-       public int edit ();
-       public int edit_ifile ();
-       public int edit_list ();
-       public int edit_first ();
-       public int edit_last ();
-       public int edit_next ();
-       public int edit_prev ();
-       public int edit_index ();
-       public IFILE save_curr_ifile ();
-       public void unsave_ifile ();
-       public void reedit_ifile ();
-       public void reopen_curr_ifile ();
-       public int edit_stdin ();
-       public void cat_file ();
-       public void use_logfile ();
-       public char * shell_unquote ();
-       public char * get_meta_escape ();
-       public char * shell_quote ();
-       public char * homefile ();
-       public char * fexpand ();
-       public char * fcomplete ();
-       public int bin_file ();
-       public char * lglob ();
-       public char * open_altfile ();
-       public void close_altfile ();
-       public int is_dir ();
-       public char * bad_file ();
-       public POSITION filesize ();
-       public char * shell_coption ();
-       public char * last_component ();
-       public int eof_displayed ();
-       public int entire_file_displayed ();
-       public void squish_check ();
-       public void forw ();
-       public void back ();
-       public void forward ();
-       public void backward ();
-       public int get_back_scroll ();
-       public void del_ifile ();
-       public IFILE next_ifile ();
-       public IFILE prev_ifile ();
-       public IFILE getoff_ifile ();
-       public int nifile ();
-       public IFILE get_ifile ();
-       public char * get_filename ();
-       public int get_index ();
-       public void store_pos ();
-       public void get_pos ();
-       public void set_open ();
-       public int opened ();
-       public void hold_ifile ();
-       public int held_ifile ();
-       public void * get_filestate ();
-       public void set_filestate ();
-       public void if_dump ();
-       public POSITION forw_line ();
-       public POSITION back_line ();
-       public void set_attnpos ();
-       public void jump_forw ();
-       public void jump_forw_buffered ();
-       public void jump_back ();
-       public void repaint ();
-       public void jump_percent ();
-       public void jump_line_loc ();
-       public void jump_loc ();
-       public void init_line ();
-       public int is_ascii_char ();
-       public void prewind ();
-       public void plinenum ();
-       public void pshift_all ();
-       public int is_ansi_end ();
-       public int is_ansi_middle ();
-       public int pappend ();
-       public int pflushmbc ();
-       public void pdone ();
-       public void set_status_col ();
-       public int gline ();
-       public void null_line ();
-       public POSITION forw_raw_line ();
-       public POSITION back_raw_line ();
-       public int rrshift ();
-       public void clr_linenum ();
-       public void add_lnum ();
-       public LINENUM find_linenum ();
-       public POSITION find_pos ();
-       public LINENUM currline ();
-       public void lsystem ();
-       public int pipe_mark ();
-       public int pipe_data ();
-       public void init_mark ();
-       public int badmark ();
-       public void setmark ();
-       public void lastmark ();
-       public void gomark ();
-       public POSITION markpos ();
-       public void unmark ();
-       public void opt_o ();
-       public void opt__O ();
-       public void opt_j ();
-       public void calc_jump_sline ();
-       public void opt_shift ();
-       public void calc_shift_count ();
-       public void opt_k ();
-       public void opt_t ();
-       public void opt__T ();
-       public void opt_p ();
-       public void opt__P ();
-       public void opt_b ();
-       public void opt_i ();
-       public void opt__V ();
-       public void opt_D ();
-       public void opt_x ();
-       public void opt_quote ();
-       public void opt_query ();
-       public int get_swindow ();
-       public char * propt ();
-       public void scan_option ();
-       public void toggle_option ();
-       public int opt_has_param ();
-       public char * opt_prompt ();
-       public int isoptpending ();
-       public void nopendopt ();
-       public int getnum ();
-       public long getfraction ();
-       public int get_quit_at_eof ();
-       public void init_option ();
-       public struct loption * findopt ();
-       public struct loption * findopt_name ();
-       public int iread ();
-       public void intread ();
-       public time_type get_time ();
-       public char * errno_message ();
-       public int percentage ();
-       public POSITION percent_pos ();
-       public int  os9_signal ();
-       public void put_line ();
-       public void flush ();
-       public int putchr ();
-       public void putstr ();
-       public void get_return ();
-       public void error ();
-       public void ierror ();
-       public int query ();
-       public int compile_pattern ();
-       public void uncompile_pattern ();
-       public int valid_pattern ();
-       public int is_null_pattern ();
-       public int match_pattern ();
-       public POSITION position ();
-       public void add_forw_pos ();
-       public void add_back_pos ();
-       public void pos_clear ();
-       public void pos_init ();
-       public int onscreen ();
-       public int empty_screen ();
-       public int empty_lines ();
-       public void get_scrpos ();
-       public int adjsline ();
-       public void init_prompt ();
-       public char * pr_expand ();
-       public char * eq_message ();
-       public char * pr_string ();
-       public char * wait_message ();
-       public void init_search ();
-       public void repaint_hilite ();
-       public void clear_attn ();
-       public void undo_search ();
-       public void clr_hlist ();
-       public void clr_hilite ();
-       public void clr_filter ();
-       public int is_filtered ();
-       public POSITION next_unfiltered ();
-       public POSITION prev_unfiltered ();
-       public int is_hilited ();
-       public void chg_hilite ();
-       public void chg_caseless ();
-       public int search ();
-       public void prep_hilite ();
-       public void set_filter_pattern ();
-       public int is_filtering ();
-       public RETSIGTYPE winch ();
-       public RETSIGTYPE winch ();
-       public void init_signals ();
-       public void psignals ();
-       public void cleantags ();
-       public int gettagtype ();
-       public void findtag ();
-       public POSITION tagsearch ();
-       public char * nexttag ();
-       public char * prevtag ();
-       public int ntags ();
-       public int curr_tag ();
-       public int edit_tagfile ();
-       public void open_getchr ();
-       public void close_getchr ();
-       public int getchr ();
+public char * save LESSPARAMS ((constant char *s));
+public VOID_POINTER ecalloc LESSPARAMS ((int count, unsigned int size));
+public char * skipsp LESSPARAMS ((char *s));
+public int sprefix LESSPARAMS ((char *ps, char *s, int uppercase));
+public void quit LESSPARAMS ((int status));
+public void raw_mode LESSPARAMS ((int on));
+public void scrsize LESSPARAMS ((VOID_PARAM));
+public char * special_key_str LESSPARAMS ((int key));
+public void get_term LESSPARAMS ((VOID_PARAM));
+public void init LESSPARAMS ((VOID_PARAM));
+public void deinit LESSPARAMS ((VOID_PARAM));
+public void home LESSPARAMS ((VOID_PARAM));
+public void add_line LESSPARAMS ((VOID_PARAM));
+public void remove_top LESSPARAMS ((int n));
+public void win32_scroll_up LESSPARAMS ((int n));
+public void lower_left LESSPARAMS ((VOID_PARAM));
+public void line_left LESSPARAMS ((VOID_PARAM));
+public void check_winch LESSPARAMS ((VOID_PARAM));
+public void goto_line LESSPARAMS ((int sindex));
+public void vbell LESSPARAMS ((VOID_PARAM));
+public void bell LESSPARAMS ((VOID_PARAM));
+public void clear LESSPARAMS ((VOID_PARAM));
+public void clear_eol LESSPARAMS ((VOID_PARAM));
+public void clear_bot LESSPARAMS ((VOID_PARAM));
+public void at_enter LESSPARAMS ((int attr));
+public void at_exit LESSPARAMS ((VOID_PARAM));
+public void at_switch LESSPARAMS ((int attr));
+public int is_at_equiv LESSPARAMS ((int attr1, int attr2));
+public int apply_at_specials LESSPARAMS ((int attr));
+public void backspace LESSPARAMS ((VOID_PARAM));
+public void putbs LESSPARAMS ((VOID_PARAM));
+public char WIN32getch LESSPARAMS ((int tty));
+public void WIN32setcolors LESSPARAMS ((int fg, int bg));
+public void WIN32textout LESSPARAMS ((char *text, int len));
+public void match_brac LESSPARAMS ((int obrac, int cbrac, int forwdir, int n));
+public void ch_ungetchar LESSPARAMS ((int c));
+public void end_logfile LESSPARAMS ((VOID_PARAM));
+public void sync_logfile LESSPARAMS ((VOID_PARAM));
+public int ch_seek LESSPARAMS ((POSITION pos));
+public int ch_end_seek LESSPARAMS ((VOID_PARAM));
+public int ch_end_buffer_seek LESSPARAMS ((VOID_PARAM));
+public int ch_beg_seek LESSPARAMS ((VOID_PARAM));
+public POSITION ch_length LESSPARAMS ((VOID_PARAM));
+public POSITION ch_tell LESSPARAMS ((VOID_PARAM));
+public int ch_forw_get LESSPARAMS ((VOID_PARAM));
+public int ch_back_get LESSPARAMS ((VOID_PARAM));
+public void ch_setbufspace LESSPARAMS ((int bufspace));
+public void ch_flush LESSPARAMS ((VOID_PARAM));
+public int seekable LESSPARAMS ((int f));
+public void ch_set_eof LESSPARAMS ((VOID_PARAM));
+public void ch_init LESSPARAMS ((int f, int flags));
+public void ch_close LESSPARAMS ((VOID_PARAM));
+public int ch_getflags LESSPARAMS ((VOID_PARAM));
+public void ch_dump LESSPARAMS ((VOID_PARAM));
+public void setfmt LESSPARAMS ((char *s, char **fmtvarptr, int *attrptr, char *default_fmt));
+public void init_charset LESSPARAMS ((VOID_PARAM));
+public int binary_char LESSPARAMS ((LWCHAR c));
+public int control_char LESSPARAMS ((LWCHAR c));
+public char * prchar LESSPARAMS ((LWCHAR c));
+public char * prutfchar LESSPARAMS ((LWCHAR ch));
+public int utf_len LESSPARAMS ((unsigned char ch));
+public int is_utf8_well_formed LESSPARAMS ((char *ss, int slen));
+public void utf_skip_to_lead LESSPARAMS ((char **pp, char *limit));
+public LWCHAR get_wchar LESSPARAMS ((constant char *p));
+public void put_wchar LESSPARAMS ((char **pp, LWCHAR ch));
+public LWCHAR step_char LESSPARAMS ((char **pp, signed int dir, constant char *limit));
+public int is_composing_char LESSPARAMS ((LWCHAR ch));
+public int is_ubin_char LESSPARAMS ((LWCHAR ch));
+public int is_wide_char LESSPARAMS ((LWCHAR ch));
+public int is_combining_char LESSPARAMS ((LWCHAR ch1, LWCHAR ch2));
+public void cmd_reset LESSPARAMS ((VOID_PARAM));
+public void clear_cmd LESSPARAMS ((VOID_PARAM));
+public void cmd_putstr LESSPARAMS ((constant char *s));
+public int len_cmdbuf LESSPARAMS ((VOID_PARAM));
+public void set_mlist LESSPARAMS ((void *mlist, int cmdflags));
+public void cmd_addhist LESSPARAMS ((struct mlist *mlist, constant char *cmd, int modified));
+public void cmd_accept LESSPARAMS ((VOID_PARAM));
+public int cmd_char LESSPARAMS ((int c));
+public LINENUM cmd_int LESSPARAMS ((long *frac));
+public char * get_cmdbuf LESSPARAMS ((VOID_PARAM));
+public char * cmd_lastpattern LESSPARAMS ((VOID_PARAM));
+public void init_cmdhist LESSPARAMS ((VOID_PARAM));
+public void save_cmdhist LESSPARAMS ((VOID_PARAM));
+public int in_mca LESSPARAMS ((VOID_PARAM));
+public void dispversion LESSPARAMS ((VOID_PARAM));
+public int getcc LESSPARAMS ((VOID_PARAM));
+public void ungetcc LESSPARAMS ((LWCHAR c));
+public void ungetsc LESSPARAMS ((char *s));
+public LWCHAR peekcc LESSPARAMS ((VOID_PARAM));
+public void commands LESSPARAMS ((VOID_PARAM));
+public int cvt_length LESSPARAMS ((int len, int ops));
+public int * cvt_alloc_chpos LESSPARAMS ((int len));
+public void cvt_text LESSPARAMS ((char *odst, char *osrc, int *chpos, int *lenp, int ops));
+public void expand_cmd_tables LESSPARAMS ((VOID_PARAM));
+public void init_cmds LESSPARAMS ((VOID_PARAM));
+public void add_fcmd_table LESSPARAMS ((char *buf, int len));
+public void add_ecmd_table LESSPARAMS ((char *buf, int len));
+public int fcmd_decode LESSPARAMS ((char *cmd, char **sp));
+public int ecmd_decode LESSPARAMS ((char *cmd, char **sp));
+public char * lgetenv LESSPARAMS ((char *var));
+public int lesskey LESSPARAMS ((char *filename, int sysvar));
+public void add_hometable LESSPARAMS ((char *envname, char *def_filename, int sysvar));
+public int editchar LESSPARAMS ((int c, int flags));
+public void init_textlist LESSPARAMS ((struct textlist *tlist, char *str));
+public char * forw_textlist LESSPARAMS ((struct textlist *tlist, char *prev));
+public char * back_textlist LESSPARAMS ((struct textlist *tlist, char *prev));
+public int edit LESSPARAMS ((char *filename));
+public int edit_ifile LESSPARAMS ((IFILE ifile));
+public int edit_list LESSPARAMS ((char *filelist));
+public int edit_first LESSPARAMS ((VOID_PARAM));
+public int edit_last LESSPARAMS ((VOID_PARAM));
+public int edit_next LESSPARAMS ((int n));
+public int edit_prev LESSPARAMS ((int n));
+public int edit_index LESSPARAMS ((int n));
+public IFILE save_curr_ifile LESSPARAMS ((VOID_PARAM));
+public void unsave_ifile LESSPARAMS ((IFILE save_ifile));
+public void reedit_ifile LESSPARAMS ((IFILE save_ifile));
+public void reopen_curr_ifile LESSPARAMS ((VOID_PARAM));
+public int edit_stdin LESSPARAMS ((VOID_PARAM));
+public void cat_file LESSPARAMS ((VOID_PARAM));
+public void use_logfile LESSPARAMS ((char *filename));
+public char * shell_unquote LESSPARAMS ((char *str));
+public char * get_meta_escape LESSPARAMS ((VOID_PARAM));
+public char * shell_quote LESSPARAMS ((char *s));
+public char * homefile LESSPARAMS ((char *filename));
+public char * fexpand LESSPARAMS ((char *s));
+public char * fcomplete LESSPARAMS ((char *s));
+public int bin_file LESSPARAMS ((int f));
+public char * lglob LESSPARAMS ((char *filename));
+public char * open_altfile LESSPARAMS ((char *filename, int *pf, void **pfd));
+public void close_altfile LESSPARAMS ((char *altfilename, char *filename));
+public int is_dir LESSPARAMS ((char *filename));
+public char * bad_file LESSPARAMS ((char *filename));
+public POSITION filesize LESSPARAMS ((int f));
+public char * shell_coption LESSPARAMS ((VOID_PARAM));
+public char * last_component LESSPARAMS ((char *name));
+public int eof_displayed LESSPARAMS ((VOID_PARAM));
+public int entire_file_displayed LESSPARAMS ((VOID_PARAM));
+public void squish_check LESSPARAMS ((VOID_PARAM));
+public void forw LESSPARAMS ((int n, POSITION pos, int force, int only_last, int nblank));
+public void back LESSPARAMS ((int n, POSITION pos, int force, int only_last));
+public void forward LESSPARAMS ((int n, int force, int only_last));
+public void backward LESSPARAMS ((int n, int force, int only_last));
+public int get_back_scroll LESSPARAMS ((VOID_PARAM));
+public int get_line_count LESSPARAMS ((VOID_PARAM));
+public void del_ifile LESSPARAMS ((IFILE h));
+public IFILE next_ifile LESSPARAMS ((IFILE h));
+public IFILE prev_ifile LESSPARAMS ((IFILE h));
+public IFILE getoff_ifile LESSPARAMS ((IFILE ifile));
+public int nifile LESSPARAMS ((VOID_PARAM));
+public IFILE get_ifile LESSPARAMS ((char *filename, IFILE prev));
+public char * get_filename LESSPARAMS ((IFILE ifile));
+public int get_index LESSPARAMS ((IFILE ifile));
+public void store_pos LESSPARAMS ((IFILE ifile, struct scrpos *scrpos));
+public void get_pos LESSPARAMS ((IFILE ifile, struct scrpos *scrpos));
+public void set_open LESSPARAMS ((IFILE ifile));
+public int opened LESSPARAMS ((IFILE ifile));
+public void hold_ifile LESSPARAMS ((IFILE ifile, int incr));
+public int held_ifile LESSPARAMS ((IFILE ifile));
+public void * get_filestate LESSPARAMS ((IFILE ifile));
+public void set_filestate LESSPARAMS ((IFILE ifile, void *filestate));
+public void set_altpipe LESSPARAMS ((IFILE ifile, void *p));
+public void * get_altpipe LESSPARAMS ((IFILE ifile));
+public void set_altfilename LESSPARAMS ((IFILE ifile, char *altfilename));
+public char * get_altfilename LESSPARAMS ((IFILE ifile));
+public void if_dump LESSPARAMS ((VOID_PARAM));
+public POSITION forw_line LESSPARAMS ((POSITION curr_pos));
+public POSITION back_line LESSPARAMS ((POSITION curr_pos));
+public void set_attnpos LESSPARAMS ((POSITION pos));
+public void jump_forw LESSPARAMS ((VOID_PARAM));
+public void jump_forw_buffered LESSPARAMS ((VOID_PARAM));
+public void jump_back LESSPARAMS ((LINENUM linenum));
+public void repaint LESSPARAMS ((VOID_PARAM));
+public void jump_percent LESSPARAMS ((int percent, long fraction));
+public void jump_line_loc LESSPARAMS ((POSITION pos, int sline));
+public void jump_loc LESSPARAMS ((POSITION pos, int sline));
+public void init_line LESSPARAMS ((VOID_PARAM));
+public int is_ascii_char LESSPARAMS ((LWCHAR ch));
+public void prewind LESSPARAMS ((VOID_PARAM));
+public void plinenum LESSPARAMS ((POSITION pos));
+public void pshift_all LESSPARAMS ((VOID_PARAM));
+public int is_ansi_end LESSPARAMS ((LWCHAR ch));
+public int is_ansi_middle LESSPARAMS ((LWCHAR ch));
+public void skip_ansi LESSPARAMS ((char **pp, constant char *limit));
+public int pappend LESSPARAMS ((unsigned char c, POSITION pos));
+public int pflushmbc LESSPARAMS ((VOID_PARAM));
+public void pdone LESSPARAMS ((int endline, int chopped, int forw));
+public void set_status_col LESSPARAMS ((char c));
+public int gline LESSPARAMS ((int i, int *ap));
+public void null_line LESSPARAMS ((VOID_PARAM));
+public POSITION forw_raw_line LESSPARAMS ((POSITION curr_pos, char **linep, int *line_lenp));
+public POSITION back_raw_line LESSPARAMS ((POSITION curr_pos, char **linep, int *line_lenp));
+public int rrshift LESSPARAMS ((VOID_PARAM));
+public void clr_linenum LESSPARAMS ((VOID_PARAM));
+public void add_lnum LESSPARAMS ((LINENUM linenum, POSITION pos));
+public LINENUM find_linenum LESSPARAMS ((POSITION pos));
+public POSITION find_pos LESSPARAMS ((LINENUM linenum));
+public LINENUM currline LESSPARAMS ((int where));
+public void lsystem LESSPARAMS ((char *cmd, char *donemsg));
+public int pipe_mark LESSPARAMS ((int c, char *cmd));
+public int pipe_data LESSPARAMS ((char *cmd, POSITION spos, POSITION epos));
+public void init_mark LESSPARAMS ((VOID_PARAM));
+public int badmark LESSPARAMS ((int c));
+public void setmark LESSPARAMS ((int c, int where));
+public void clrmark LESSPARAMS ((int c));
+public void lastmark LESSPARAMS ((VOID_PARAM));
+public void gomark LESSPARAMS ((int c));
+public POSITION markpos LESSPARAMS ((int c));
+public char posmark LESSPARAMS ((POSITION pos));
+public void unmark LESSPARAMS ((IFILE ifile));
+public void opt_o LESSPARAMS ((int type, char *s));
+public void opt__O LESSPARAMS ((int type, char *s));
+public void opt_j LESSPARAMS ((int type, char *s));
+public void calc_jump_sline LESSPARAMS ((VOID_PARAM));
+public void opt_shift LESSPARAMS ((int type, char *s));
+public void calc_shift_count LESSPARAMS ((VOID_PARAM));
+public void opt_k LESSPARAMS ((int type, char *s));
+public void opt_t LESSPARAMS ((int type, char *s));
+public void opt__T LESSPARAMS ((int type, char *s));
+public void opt_p LESSPARAMS ((int type, char *s));
+public void opt__P LESSPARAMS ((int type, char *s));
+public void opt_b LESSPARAMS ((int type, char *s));
+public void opt_i LESSPARAMS ((int type, char *s));
+public void opt__V LESSPARAMS ((int type, char *s));
+public void opt_D LESSPARAMS ((int type, char *s));
+public void opt_x LESSPARAMS ((int type, char *s));
+public void opt_quote LESSPARAMS ((int type, char *s));
+public void opt_rscroll LESSPARAMS ((int type, char *s));
+public void opt_query LESSPARAMS ((int type, char *s));
+public int get_swindow LESSPARAMS ((VOID_PARAM));
+public char * propt LESSPARAMS ((int c));
+public void scan_option LESSPARAMS ((char *s));
+public void toggle_option LESSPARAMS ((struct loption *o, int lower, char *s, int how_toggle));
+public int opt_has_param LESSPARAMS ((struct loption *o));
+public char * opt_prompt LESSPARAMS ((struct loption *o));
+public int isoptpending LESSPARAMS ((VOID_PARAM));
+public void nopendopt LESSPARAMS ((VOID_PARAM));
+public int getnum LESSPARAMS ((char **sp, char *printopt, int *errp));
+public long getfraction LESSPARAMS ((char **sp, char *printopt, int *errp));
+public int get_quit_at_eof LESSPARAMS ((VOID_PARAM));
+public void init_option LESSPARAMS ((VOID_PARAM));
+public struct loption * findopt LESSPARAMS ((int c));
+public struct loption * findopt_name LESSPARAMS ((char **p_optname, char **p_oname, int *p_err));
+public int iread LESSPARAMS ((int fd, unsigned char *buf, unsigned int len));
+public void intread LESSPARAMS ((VOID_PARAM));
+public time_type get_time LESSPARAMS ((VOID_PARAM));
+public char * errno_message LESSPARAMS ((char *filename));
+public int percentage LESSPARAMS ((POSITION num, POSITION den));
+public POSITION percent_pos LESSPARAMS ((POSITION pos, int percent, long fraction));
+public int  os9_signal LESSPARAMS ((int type, RETSIGTYPE (*handler)()));
+public void put_line LESSPARAMS ((VOID_PARAM));
+public void flush LESSPARAMS ((VOID_PARAM));
+public int putchr LESSPARAMS ((int c));
+public void putstr LESSPARAMS ((constant char *s));
+public void get_return LESSPARAMS ((VOID_PARAM));
+public void error LESSPARAMS ((char *fmt, PARG *parg));
+public void ierror LESSPARAMS ((char *fmt, PARG *parg));
+public int query LESSPARAMS ((char *fmt, PARG *parg));
+public int compile_pattern LESSPARAMS ((char *pattern, int search_type, PATTERN_TYPE *comp_pattern));
+public void uncompile_pattern LESSPARAMS ((PATTERN_TYPE *pattern));
+public int valid_pattern LESSPARAMS ((char *pattern));
+public int is_null_pattern LESSPARAMS ((PATTERN_TYPE pattern));
+public int match_pattern LESSPARAMS ((PATTERN_TYPE pattern, char *tpattern, char *line, int line_len, char **sp, char **ep, int notbol, int search_type));
+public POSITION position LESSPARAMS ((int sindex));
+public void add_forw_pos LESSPARAMS ((POSITION pos));
+public void add_back_pos LESSPARAMS ((POSITION pos));
+public void pos_clear LESSPARAMS ((VOID_PARAM));
+public void pos_init LESSPARAMS ((VOID_PARAM));
+public int onscreen LESSPARAMS ((POSITION pos));
+public int empty_screen LESSPARAMS ((VOID_PARAM));
+public int empty_lines LESSPARAMS ((int s, int e));
+public void get_scrpos LESSPARAMS ((struct scrpos *scrpos, int where));
+public int sindex_from_sline LESSPARAMS ((int sline));
+public void init_prompt LESSPARAMS ((VOID_PARAM));
+public char * pr_expand LESSPARAMS ((constant char *proto, int maxwidth));
+public char * eq_message LESSPARAMS ((VOID_PARAM));
+public char * pr_string LESSPARAMS ((VOID_PARAM));
+public char * wait_message LESSPARAMS ((VOID_PARAM));
+public void init_search LESSPARAMS ((VOID_PARAM));
+public void repaint_hilite LESSPARAMS ((int on));
+public void clear_attn LESSPARAMS ((VOID_PARAM));
+public void undo_search LESSPARAMS ((VOID_PARAM));
+public void clr_hlist LESSPARAMS ((struct hilite_tree *anchor));
+public void clr_hilite LESSPARAMS ((VOID_PARAM));
+public void clr_filter LESSPARAMS ((VOID_PARAM));
+public int is_filtered LESSPARAMS ((POSITION pos));
+public POSITION next_unfiltered LESSPARAMS ((POSITION pos));
+public POSITION prev_unfiltered LESSPARAMS ((POSITION pos));
+public int is_hilited LESSPARAMS ((POSITION pos, POSITION epos, int nohide, int *p_matches));
+public void chg_hilite LESSPARAMS ((VOID_PARAM));
+public void chg_caseless LESSPARAMS ((VOID_PARAM));
+public int search LESSPARAMS ((int search_type, char *pattern, int n));
+public void prep_hilite LESSPARAMS ((POSITION spos, POSITION epos, int maxlines));
+public void set_filter_pattern LESSPARAMS ((char *pattern, int search_type));
+public int is_filtering LESSPARAMS ((VOID_PARAM));
+public RETSIGTYPE winch LESSPARAMS ((int type));
+public void init_signals LESSPARAMS ((int on));
+public void psignals LESSPARAMS ((VOID_PARAM));
+public void cleantags LESSPARAMS ((VOID_PARAM));
+public int gettagtype LESSPARAMS ((VOID_PARAM));
+public void findtag LESSPARAMS ((char *tag));
+public POSITION tagsearch LESSPARAMS ((VOID_PARAM));
+public char * nexttag LESSPARAMS ((int n));
+public char * prevtag LESSPARAMS ((int n));
+public int ntags LESSPARAMS ((VOID_PARAM));
+public int curr_tag LESSPARAMS ((VOID_PARAM));
+public int edit_tagfile LESSPARAMS ((VOID_PARAM));
+public void open_getchr LESSPARAMS ((VOID_PARAM));
+public void close_getchr LESSPARAMS ((VOID_PARAM));
+public int getchr LESSPARAMS ((VOID_PARAM));
diff --git a/help.c b/help.c
index 3b0d1bd..efa236a 100644 (file)
--- a/help.c
+++ b/help.c
@@ -1,4 +1,4 @@
-/* This file was generated by mkhelp from less.hlp */
+/* This file was generated by mkhelp.pl from less.hlp at 22:56 on 2017/12/5 */
 #include "less.h"
 constant char helpdata[] = {
 '\n',
@@ -72,10 +72,12 @@ constant char helpdata[] = {
 ' ',' ',' ',' ',' ',' ',' ',' ','E','a','c','h',' ','"','f','i','n','d',' ','o','p','e','n',' ','b','r','a','c','k','e','t','"',' ','c','o','m','m','a','n','d',' ','g','o','e','s',' ','b','a','c','k','w','a','r','d',' ','t','o',' ','t','h','e',' ','o','p','e','n',' ','b','r','a','c','k','e','t',' ','\n',
 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','m','a','t','c','h','i','n','g',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','c','l','o','s','e',' ','b','r','a','c','k','e','t',' ','i','n',' ','t','h','e',' ','b','o','t','t','o','m',' ','l','i','n','e','.','\n',
 '\n',
-' ',' ','m','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','M','a','r','k',' ','t','h','e',' ','c','u','r','r','e','n','t',' ','p','o','s','i','t','i','o','n',' ','w','i','t','h',' ','<','l','e','t','t','e','r','>','.','\n',
+' ',' ','m','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','M','a','r','k',' ','t','h','e',' ','c','u','r','r','e','n','t',' ','t','o','p',' ','l','i','n','e',' ','w','i','t','h',' ','<','l','e','t','t','e','r','>','.','\n',
+' ',' ','M','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','M','a','r','k',' ','t','h','e',' ','c','u','r','r','e','n','t',' ','b','o','t','t','o','m',' ','l','i','n','e',' ','w','i','t','h',' ','<','l','e','t','t','e','r','>','.','\n',
 ' ',' ','\'','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','G','o',' ','t','o',' ','a',' ','p','r','e','v','i','o','u','s','l','y',' ','m','a','r','k','e','d',' ','p','o','s','i','t','i','o','n','.','\n',
 ' ',' ','\'','\'',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','G','o',' ','t','o',' ','t','h','e',' ','p','r','e','v','i','o','u','s',' ','p','o','s','i','t','i','o','n','.','\n',
 ' ',' ','^','X','^','X',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','a','m','e',' ','a','s',' ','\'','.','\n',
+' ',' ','E','S','C','-','M','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ','C','l','e','a','r',' ','a',' ','m','a','r','k','.','\n',
 ' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
 ' ',' ',' ',' ',' ',' ',' ',' ','A',' ','m','a','r','k',' ','i','s',' ','a','n','y',' ','u','p','p','e','r','-','c','a','s','e',' ','o','r',' ','l','o','w','e','r','-','c','a','s','e',' ','l','e','t','t','e','r','.','\n',
 ' ',' ',' ',' ',' ',' ',' ',' ','C','e','r','t','a','i','n',' ','m','a','r','k','s',' ','a','r','e',' ','p','r','e','d','e','f','i','n','e','d',':','\n',
diff --git a/ifile.c b/ifile.c
index c733332..613312b 100644 (file)
--- a/ifile.c
+++ b/ifile.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
 extern IFILE   curr_ifile;
 
 struct ifile {
-       struct ifile *h_next;           /* Links for command line list */
+       struct ifile *h_next;           /* Links for command line list */
        struct ifile *h_prev;
-       char *h_filename;               /* Name of the file */
-       void *h_filestate;              /* File state (used in ch.c) */
-       int h_index;                    /* Index within command line list */
-       int h_hold;                     /* Hold count */
-       char h_opened;                  /* Has this ifile been opened? */
-       struct scrpos h_scrpos;         /* Saved position within the file */
+       char *h_filename;               /* Name of the file */
+       void *h_filestate;              /* File state (used in ch.c) */
+       int h_index;                    /* Index within command line list */
+       int h_hold;                     /* Hold count */
+       char h_opened;                  /* Has this ifile been opened? */
+       struct scrpos h_scrpos;         /* Saved position within the file */
+       void *h_altpipe;                /* Alt pipe */
+       char *h_altfilename;            /* Alt filename */
 };
 
 /*
@@ -50,7 +52,7 @@ static int ifiles = 0;
 
        static void
 incr_index(p, incr)
-       register struct ifile *p;
+       struct ifile *p;
        int incr;
 {
        for (;  p != &anchor;  p = p->h_next)
@@ -107,7 +109,7 @@ new_ifile(filename, prev)
        char *filename;
        struct ifile *prev;
 {
-       register struct ifile *p;
+       struct ifile *p;
 
        /*
         * Allocate and initialize structure.
@@ -129,7 +131,7 @@ new_ifile(filename, prev)
 del_ifile(h)
        IFILE h;
 {
-       register struct ifile *p;
+       struct ifile *p;
 
        if (h == NULL_IFILE)
                return;
@@ -153,7 +155,7 @@ del_ifile(h)
 next_ifile(h)
        IFILE h;
 {
-       register struct ifile *p;
+       struct ifile *p;
 
        p = (h == NULL_IFILE) ? &anchor : int_ifile(h);
        if (p->h_next == &anchor)
@@ -168,7 +170,7 @@ next_ifile(h)
 prev_ifile(h)
        IFILE h;
 {
-       register struct ifile *p;
+       struct ifile *p;
 
        p = (h == NULL_IFILE) ? &anchor : int_ifile(h);
        if (p->h_prev == &anchor)
@@ -208,7 +210,7 @@ nifile()
 find_ifile(filename)
        char *filename;
 {
-       register struct ifile *p;
+       struct ifile *p;
 
        for (p = anchor.h_next;  p != &anchor;  p = p->h_next)
                if (strcmp(filename, p->h_filename) == 0)
@@ -226,7 +228,7 @@ get_ifile(filename, prev)
        char *filename;
        IFILE prev;
 {
-       register struct ifile *p;
+       struct ifile *p;
 
        if ((p = find_ifile(filename)) == NULL)
                p = new_ifile(filename, int_ifile(prev));
@@ -328,11 +330,44 @@ set_filestate(ifile, filestate)
        int_ifile(ifile)->h_filestate = filestate;
 }
 
+       public void
+set_altpipe(ifile, p)
+       IFILE ifile;
+       void *p;
+{
+       int_ifile(ifile)->h_altpipe = p;
+}
+
+       public void *
+get_altpipe(ifile)
+       IFILE ifile;
+{
+       return (int_ifile(ifile)->h_altpipe);
+}
+
+       public void
+set_altfilename(ifile, altfilename)
+       IFILE ifile;
+       char *altfilename;
+{
+       struct ifile *p = int_ifile(ifile);
+       if (p->h_altfilename != NULL)
+               free(p->h_altfilename);
+       p->h_altfilename = altfilename;
+}
+
+       public char *
+get_altfilename(ifile)
+       IFILE ifile;
+{
+       return (int_ifile(ifile)->h_altfilename);
+}
+
 #if 0
        public void
 if_dump()
 {
-       register struct ifile *p;
+       struct ifile *p;
 
        for (p = anchor.h_next;  p != &anchor;  p = p->h_next)
        {
diff --git a/input.c b/input.c
index 26ab7c0..27be124 100644 (file)
--- a/input.c
+++ b/input.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -7,7 +7,6 @@
  * For more information, see the README file.
  */
 
-
 /*
  * High level routines dealing with getting lines of input 
  * from the file being viewed.
@@ -47,9 +46,10 @@ forw_line(curr_pos)
 {
        POSITION base_pos;
        POSITION new_pos;
-       register int c;
+       int c;
        int blankline;
        int endline;
+       int chopped;
        int backchars;
 
 get_forw_line:
@@ -143,6 +143,7 @@ get_forw_line:
        /*
         * Read each character in the line and append to the line buffer.
         */
+       chopped = FALSE;
        for (;;)
        {
                if (ABORT_SIGS())
@@ -193,6 +194,7 @@ get_forw_line:
                                new_pos = ch_tell();
                                endline = TRUE;
                                quit_if_one_screen = FALSE;
+                               chopped = TRUE;
                        } else
                        {
                                new_pos = ch_tell() - backchars;
@@ -203,7 +205,7 @@ get_forw_line:
                c = ch_forw_get();
        }
 
-       pdone(endline, 1);
+       pdone(endline, chopped, 1);
 
 #if HILITE_SEARCH
        if (is_filtered(base_pos))
@@ -255,6 +257,7 @@ back_line(curr_pos)
        POSITION new_pos, begin_new_pos, base_pos;
        int c;
        int endline;
+       int chopped;
        int backchars;
 
 get_back_line:
@@ -359,6 +362,7 @@ get_back_line:
     loop:
        begin_new_pos = new_pos;
        (void) ch_seek(new_pos);
+       chopped = FALSE;
 
        do
        {
@@ -391,6 +395,7 @@ get_back_line:
                        if (chopline || hshift > 0)
                        {
                                endline = TRUE;
+                               chopped = TRUE;
                                quit_if_one_screen = FALSE;
                                break;
                        }
@@ -405,7 +410,7 @@ get_back_line:
                }
        } while (new_pos < curr_pos);
 
-       pdone(endline, 0);
+       pdone(endline, chopped, 0);
 
 #if HILITE_SEARCH
        if (is_filtered(base_pos))
old mode 100755 (executable)
new mode 100644 (file)
diff --git a/jump.c b/jump.c
index b5ec9dd..2c7d28b 100644 (file)
--- a/jump.c
+++ b/jump.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -51,7 +51,7 @@ jump_forw()
        end_pos = ch_tell();
        pos = back_line(end_pos);
        if (pos == NULL_POSITION)
-               jump_loc((POSITION)0, sc_height-1);
+               jump_loc(ch_zero(), sc_height-1);
        else
        {
                jump_loc(pos, sc_height-1);
@@ -122,11 +122,11 @@ repaint()
         * Start at the line currently at the top of the screen
         * and redisplay the screen.
         */
-       get_scrpos(&scrpos);
+       get_scrpos(&scrpos, TOP);
        pos_clear();
        if (scrpos.pos == NULL_POSITION)
                /* Screen hasn't been drawn yet. */
-               jump_loc(0, 0);
+               jump_loc(ch_zero(), 1);
        else
                jump_loc(scrpos.pos, scrpos.ln);
 }
@@ -200,14 +200,15 @@ jump_loc(pos, sline)
        POSITION pos;
        int sline;
 {
-       register int nline;
+       int nline;
+       int sindex;
        POSITION tpos;
        POSITION bpos;
 
        /*
         * Normalize sline.
         */
-       sline = adjsline(sline);
+       sindex = sindex_from_sline(sline);
 
        if ((nline = onscreen(pos)) >= 0)
        {
@@ -215,10 +216,10 @@ jump_loc(pos, sline)
                 * The line is currently displayed.  
                 * Just scroll there.
                 */
-               nline -= sline;
+               nline -= sindex;
                if (nline > 0)
                        forw(nline, position(BOTTOM_PLUS_ONE), 1, 0, 0);
-               else
+               else if (nline < 0)
                        back(-nline, position(TOP), 1, 0);
 #if HILITE_SEARCH
                if (show_attn)
@@ -251,7 +252,7 @@ jump_loc(pos, sline)
                 * call forw() and put the desired line at the 
                 * sline-th line on the screen.
                 */
-               for (nline = 0;  nline < sline;  nline++)
+               for (nline = 0;  nline < sindex;  nline++)
                {
                        if (bpos != NULL_POSITION && pos <= bpos)
                        {
@@ -260,7 +261,7 @@ jump_loc(pos, sline)
                                 * close enough to the current screen
                                 * that we can just scroll there after all.
                                 */
-                               forw(sc_height-sline+nline-1, bpos, 1, 0, 0);
+                               forw(sc_height-sindex+nline-1, bpos, 1, 0, 0);
 #if HILITE_SEARCH
                                if (show_attn)
                                        repaint_hilite(1);
@@ -282,16 +283,16 @@ jump_loc(pos, sline)
                lastmark();
                squished = 0;
                screen_trashed = 0;
-               forw(sc_height-1, pos, 1, 0, sline-nline);
+               forw(sc_height-1, pos, 1, 0, sindex-nline);
        } else
        {
                /*
                 * The desired line is before the current screen.
                 * Move forward in the file far enough so that we
                 * can call back() and put the desired line at the 
-                * sline-th line on the screen.
+                * sindex-th line on the screen.
                 */
-               for (nline = sline;  nline < sc_height - 1;  nline++)
+               for (nline = sindex;  nline < sc_height - 1;  nline++)
                {
                        pos = forw_line(pos);
                        if (pos == NULL_POSITION)
diff --git a/less.h b/less.h
index 79ce721..39ca65e 100644 (file)
--- a/less.h
+++ b/less.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
 /*
  * Language details.
  */
+#if HAVE_ANSI_PROTOS
+#define LESSPARAMS(a) a
+#else
+#define LESSPARAMS(a) ()
+#endif
 #if HAVE_VOID
 #define        VOID_POINTER    void *
+#define        VOID_PARAM      void
 #else
 #define        VOID_POINTER    char *
+#define        VOID_PARAM
 #define        void  int
 #endif
 #if HAVE_CONST
@@ -507,7 +514,6 @@ struct wchar_range_table
 #define        CH_HELPFILE     010
 #define        CH_NODATA       020     /* Special case for zero length files */
 
-
 #define        ch_zero()       ((POSITION)0)
 
 #define        FAKE_HELPFILE   "@/\\less/\\help/\\file/\\@"
@@ -525,9 +531,13 @@ struct wchar_range_table
 #define        time_type       long
 #endif
 
+struct mlist;
+struct loption;
+struct hilite_tree;
+#include "pattern.h"
 #include "funcs.h"
 
 /* Functions not included in funcs.h */
-void postoa();
-void linenumtoa();
-void inttoa();
+void postoa LESSPARAMS ((POSITION, char*));
+void linenumtoa LESSPARAMS ((LINENUM, char*));
+void inttoa LESSPARAMS ((int, char*));
index 255dc7e..0bbada9 100644 (file)
--- a/less.hlp
+++ b/less.hlp
         Each "find open bracket" command goes backward to the open bracket 
           matching the (_\bN-th) close bracket in the bottom line.
 
-  m_\b<_\bl_\be_\bt_\bt_\be_\br_\b>            Mark the current position with <letter>.
+  m_\b<_\bl_\be_\bt_\bt_\be_\br_\b>            Mark the current top line with <letter>.
+  M_\b<_\bl_\be_\bt_\bt_\be_\br_\b>            Mark the current bottom line with <letter>.
   '_\b<_\bl_\be_\bt_\bt_\be_\br_\b>            Go to a previously marked position.
   ''                   Go to the previous position.
   ^X^X                 Same as '.
+  ESC-M_\b<_\bl_\be_\bt_\bt_\be_\br_\b>        Clear a mark.
         ---------------------------------------------------
         A mark is any upper-case or lower-case letter.
         Certain marks are predefined:
index 0705407..84420a4 100644 (file)
--- a/less.man
+++ b/less.man
@@ -29,7 +29,7 @@ LESS(1)                     General Commands Manual                    LESS(1)
        a hardcopy terminal, lines which should be printed at the  top  of  the
        screen are prefixed with a caret.)
 
-       Commands  are based on both \e[4mmore\e[24m and \e[4mvi.\e[24m  Commands may be preceded by a
+       Commands  are based on both \e[4mmore\e[24m and \e[4mvi\e[24m.  Commands may be preceded by a
        decimal number, called N in the descriptions below.  The number is used
        by some commands, as indicated.
 
@@ -175,19 +175,27 @@ LESS(1)                     General Commands Manual                    LESS(1)
               "ESC ^B < >" could be used to go backward to the < which matches
               the > in the bottom displayed line.
 
-       m      Followed  by  any  lowercase  letter, marks the current position
-              with that letter.
+       m      Followed  by  any lowercase or uppercase letter, marks the first
+              displayed line with  that  letter.   If  the  status  column  is
+              enabled  via  the  -J option, the status column shows the marked
+              line.
 
-       '      (Single quote.)  Followed by any lowercase  letter,  returns  to
-              the position which was previously marked with that letter.  Fol-
-              lowed by another single quote, returns to the position at  which
-              the last "large" movement command was executed.  Followed by a ^
-              or $, jumps to the beginning or end of  the  file  respectively.
-              Marks  are  preserved when a new file is examined, so the ' com-
-              mand can be used to switch between input files.
+       M      Acts like m, except the last displayed  line  is  marked  rather
+              than the first displayed line.
+
+       '      (Single  quote.)  Followed by any lowercase or uppercase letter,
+              returns to the position which was previously  marked  with  that
+              letter.   Followed by another single quote, returns to the posi-
+              tion at which the last "large" movement  command  was  executed.
+              Followed  by a ^ or $, jumps to the beginning or end of the file
+              respectively.  Marks are preserved when a new file is  examined,
+              so the ' command can be used to switch between input files.
 
        ^X^X   Same as single quote.
 
+       ESC-m  Followed  by  any lowercase or uppercase letter, clears the mark
+              identified by that letter.
+
        /pattern
               Search forward in the file for the N-th line containing the pat-
               tern.  N defaults to 1.  The pattern is a regular expression, as
@@ -388,7 +396,7 @@ LESS(1)                     General Commands Manual                    LESS(1)
        V      Prints the version number of \e[4mless\e[24m being run.
 
        q or Q or :q or :Q or ZZ
-              Exits \e[4mless.\e[0m
+              Exits \e[4mless\e[24m.
 
        The following four commands may or may not be valid, depending on  your
        particular installation.
@@ -412,10 +420,12 @@ LESS(1)                     General Commands Manual                    LESS(1)
        | <m> shell-command
               <m> represents any mark letter.  Pipes a section  of  the  input
               file  to the given shell command.  The section of the file to be
-              piped is between the first line on the current  screen  and  the
-              position  marked by the letter.  <m> may also be ^ or $ to indi-
-              cate beginning or end of file respectively.  If <m> is . or new-
-              line, the current screen is piped.
+              piped is between the position marked by the letter and the  cur-
+              rent  screen.  The entire current screen is included, regardless
+              of whether the marked position is before or  after  the  current
+              screen.   <m> may also be ^ or $ to indicate beginning or end of
+              file respectively.  If <m> is . or newline, the  current  screen
+              is piped.
 
        s filename
               Save  the  input  to  a file.  This only works if the input is a
@@ -437,11 +447,11 @@ LESS(1)                     General Commands Manual                    LESS(1)
 
        Options are also taken from the environment variable "LESS".  For exam-
        ple, to avoid typing "less -options ..." each time \e[4mless\e[24m is invoked, you
-       might tell \e[4mcsh:\e[0m
+       might tell \e[4mcsh\e[24m:
 
        setenv LESS "-options"
 
-       or if you use \e[4msh:\e[0m
+       or if you use \e[4msh\e[24m:
 
        LESS="-options"; export LESS
 
@@ -518,7 +528,7 @@ LESS(1)                     General Commands Manual                    LESS(1)
               from the bottom of the screen.
 
        -C or --CLEAR-SCREEN
-              Same as -c, for compatibility with older versions of \e[4mless.\e[0m
+              Same as -c, for compatibility with older versions of \e[4mless\e[24m.
 
        -d or --dumb
               The -d option suppresses the error message normally displayed if
@@ -534,8 +544,10 @@ LESS(1)                     General Commands Manual                    LESS(1)
               \e[4mcolor\e[24m is a pair of numbers separated by  a  period.   The  first
               number  selects  the foreground color and the second selects the
               background color of the text.  A single number \e[4mN\e[24m is the same  as
-              \e[4mN.M\e[24m, where \e[4mM\e[24m is the normal background color.  \e[1mx \e[22mmay also be \e[1ma \e[22mto
-              toggle strict ANSI sequence rendering (SGR mode).
+              \e[4mN.M\e[24m,  where  \e[4mM\e[24m  is  the  normal background color.  The color may
+              start or end with \e[1mu \e[22mto use underline (with the normal color,  if
+              by  itself),  if  the  system supports it (Windows only).  \e[1mx \e[22mmay
+              also be \e[1ma \e[22mto toggle strict ANSI sequence rendering (SGR mode).
 
 
        -e or --quit-at-eof
@@ -613,9 +625,9 @@ LESS(1)                     General Commands Manual                    LESS(1)
 
        -J or --status-column
               Displays  a  status  column at the left edge of the screen.  The
-              status column shows the lines that matched the  current  search.
-              The  status  column  is  also  used if the -w or -W option is in
-              effect.
+              status column shows the lines that matched the  current  search,
+              and  any  lines  that  are marked (via the m or M command).  The
+              status column is also used if the -w or -W option is in effect.
 
        -k\e[4mfilename\e[24m or --lesskey-file=\e[4mfilename\e[0m
               Causes \e[4mless\e[24m to open and interpret the named file  as  a  \e[4mlesskey\e[0m
@@ -642,7 +654,7 @@ LESS(1)                     General Commands Manual                    LESS(1)
               into the file.  By default, \e[4mless\e[24m prompts with a colon.
 
        -M or --LONG-PROMPT
-              Causes \e[4mless\e[24m to prompt even more verbosely than \e[4mmore.\e[0m
+              Causes \e[4mless\e[24m to prompt even more verbosely than \e[4mmore\e[24m.
 
        -n or --line-numbers
               Suppresses line numbers.  The default (to use line numbers)  may
@@ -671,7 +683,7 @@ LESS(1)                     General Commands Manual                    LESS(1)
               If no log file has been specified, the -o and -O options can  be
               used  from  within  \e[4mless\e[24m  to specify a log file.  Without a file
               name, they will simply report the name of the log file.  The "s"
-              command is equivalent to specifying -o from within \e[4mless.\e[0m
+              command is equivalent to specifying -o from within \e[4mless\e[24m.
 
        -p\e[4mpattern\e[24m or --pattern=\e[4mpattern\e[0m
               The  -p  option  on the command line is equivalent to specifying
@@ -691,110 +703,111 @@ LESS(1)                     General Commands Manual                    LESS(1)
                -Ph changes the prompt for the help screen.
                -P= changes the message printed by the = command.
                -Pw changes the message printed while waiting for data (in  the
-              F command).  All prompt strings consist of a sequence of letters
-              and special escape sequences.  See the section  on  PROMPTS  for
-              more details.
+              F command).
+
+              All  prompt strings consist of a sequence of letters and special
+              escape sequences.  See the section on PROMPTS for more details.
 
        -q or --quiet or --silent
-              Causes  moderately  "quiet"  operation: the terminal bell is not
+              Causes moderately "quiet" operation: the terminal  bell  is  not
               rung if an attempt is made to scroll past the end of the file or
               before the beginning of the file.  If the terminal has a "visual
-              bell", it is used instead.  The bell will  be  rung  on  certain
-              other  errors, such as typing an invalid character.  The default
+              bell",  it  is  used  instead.  The bell will be rung on certain
+              other errors, such as typing an invalid character.  The  default
               is to ring the terminal bell in all such cases.
 
        -Q or --QUIET or --SILENT
-              Causes totally "quiet" operation: the  terminal  bell  is  never
+              Causes  totally  "quiet"  operation:  the terminal bell is never
               rung.
 
        -r or --raw-control-chars
               Causes "raw" control characters to be displayed.  The default is
-              to display control characters  using  the  caret  notation;  for
+              to  display  control  characters  using  the caret notation; for
               example, a control-A (octal 001) is displayed as "^A".  Warning:
               when the -r option is used, \e[4mless\e[24m cannot keep track of the actual
-              appearance  of  the screen (since this depends on how the screen
+              appearance of the screen (since this depends on how  the  screen
               responds to each type of control character).  Thus, various dis-
-              play  problems may result, such as long lines being split in the
+              play problems may result, such as long lines being split in  the
               wrong place.
 
        -R or --RAW-CONTROL-CHARS
-              Like -r, but only ANSI "color" escape sequences  are  output  in
+              Like  -r,  but  only ANSI "color" escape sequences are output in
               "raw" form.  Unlike -r, the screen appearance is maintained cor-
               rectly  in  most  cases.   ANSI  "color"  escape  sequences  are
               sequences of the form:
 
                    ESC [ ... m
 
-              where  the  "..." is zero or more color specification characters
-              For the purpose of keeping  track  of  screen  appearance,  ANSI
-              color  escape sequences are assumed to not move the cursor.  You
-              can make \e[4mless\e[24m think that characters other than "m" can end  ANSI
-              color  escape  sequences  by  setting  the  environment variable
+              where the "..." is zero or more color  specification  characters
+              For  the  purpose  of  keeping  track of screen appearance, ANSI
+              color escape sequences are assumed to not move the cursor.   You
+              can  make \e[4mless\e[24m think that characters other than "m" can end ANSI
+              color escape  sequences  by  setting  the  environment  variable
               LESSANSIENDCHARS to the list of characters which can end a color
-              escape  sequence.   And  you can make \e[4mless\e[24m think that characters
-              other than the standard ones may appear between the ESC and  the
-              m  by  setting  the environment variable LESSANSIMIDCHARS to the
+              escape sequence.  And you can make \e[4mless\e[24m  think  that  characters
+              other  than the standard ones may appear between the ESC and the
+              m by setting the environment variable  LESSANSIMIDCHARS  to  the
               list of characters which can appear.
 
        -s or --squeeze-blank-lines
-              Causes consecutive blank lines to  be  squeezed  into  a  single
+              Causes  consecutive  blank  lines  to  be squeezed into a single
               blank line.  This is useful when viewing \e[4mnroff\e[24m output.
 
        -S or --chop-long-lines
-              Causes  lines  longer than the screen width to be chopped (trun-
+              Causes lines longer than the screen width to be  chopped  (trun-
               cated) rather than wrapped.  That is, the portion of a long line
               that does not fit in the screen width is not shown.  The default
-              is to wrap long lines; that is, display  the  remainder  on  the
+              is  to  wrap  long  lines; that is, display the remainder on the
               next line.
 
        -t\e[4mtag\e[24m or --tag=\e[4mtag\e[0m
               The -t option, followed immediately by a TAG, will edit the file
-              containing that tag.  For this to work, tag information must  be
-              available;  for  example,  there  may  be  a file in the current
+              containing  that tag.  For this to work, tag information must be
+              available; for example, there may  be  a  file  in  the  current
               directory called "tags", which was previously built by \e[4mctags\e[24m (1)
               or an equivalent command.  If the environment variable LESSGLOB-
-              ALTAGS is set, it is taken to be the name of a command  compati-
-              ble  with  \e[4mglobal\e[24m  (1), and that command is executed to find the
+              ALTAGS  is set, it is taken to be the name of a command compati-
+              ble with \e[4mglobal\e[24m (1), and that command is executed  to  find  the
               tag.  (See http://www.gnu.org/software/global/global.html).  The
-              -t  option  may  also be specified from within \e[4mless\e[24m (using the -
-              command) as a way of examining a new file.  The command ":t"  is
-              equivalent to specifying -t from within \e[4mless.\e[0m
+              -t option may also be specified from within \e[4mless\e[24m  (using  the  -
+              command)  as a way of examining a new file.  The command ":t" is
+              equivalent to specifying -t from within \e[4mless\e[24m.
 
        -T\e[4mtagsfile\e[24m or --tag-file=\e[4mtagsfile\e[0m
               Specifies a tags file to be used instead of "tags".
 
        -u or --underline-special
-              Causes  backspaces  and carriage returns to be treated as print-
-              able characters; that is, they are sent  to  the  terminal  when
+              Causes backspaces and carriage returns to be treated  as  print-
+              able  characters;  that  is,  they are sent to the terminal when
               they appear in the input.
 
        -U or --UNDERLINE-SPECIAL
-              Causes  backspaces,  tabs  and carriage returns to be treated as
-              control characters; that is, they are handled  as  specified  by
-              the -r option.
-
-              By  default,  if  neither  -u  nor -U is given, backspaces which
-              appear adjacent to an  underscore  character  are  treated  spe-
-              cially:  the  underlined  text is displayed using the terminal's
-              hardware underlining capability.  Also, backspaces which  appear
-              between  two  identical  characters  are  treated specially: the
-              overstruck text is printed using the terminal's  hardware  bold-
-              face  capability.   Other backspaces are deleted, along with the
+              Causes backspaces, tabs, carriage returns and "formatting  char-
+              acters" (as defined by Unicode) to be treated as control charac-
+              ters; that is, they are handled as specified by the -r option.
+
+              By default, if neither -u nor  -U  is  given,  backspaces  which
+              appear  adjacent  to  an  underscore  character are treated spe-
+              cially: the underlined text is displayed  using  the  terminal's
+              hardware  underlining capability.  Also, backspaces which appear
+              between two identical  characters  are  treated  specially:  the
+              overstruck  text  is printed using the terminal's hardware bold-
+              face capability.  Other backspaces are deleted, along  with  the
               preceding character.  Carriage returns immediately followed by a
-              newline  are  deleted.   Other  carriage  returns are handled as
-              specified by the -r option.  Text which is overstruck or  under-
+              newline are deleted.  Other  carriage  returns  are  handled  as
+              specified  by the -r option.  Text which is overstruck or under-
               lined can be searched for if neither -u nor -U is in effect.
 
        -V or --version
-              Displays the version number of \e[4mless.\e[0m
+              Displays the version number of \e[4mless\e[24m.
 
        -w or --hilite-unread
-              Temporarily  highlights  the  first  "new"  line after a forward
+              Temporarily highlights the first  "new"  line  after  a  forward
               movement of a full page.  The first "new" line is the line imme-
-              diately  following  the  line  previously  at  the bottom of the
+              diately following the line  previously  at  the  bottom  of  the
               screen.  Also highlights the target line after a g or p command.
-              The  highlight is removed at the next command which causes move-
-              ment.  The entire line is highlighted, unless the -J  option  is
+              The highlight is removed at the next command which causes  move-
+              ment.   The  entire line is highlighted, unless the -J option is
               in effect, in which case only the status column is highlighted.
 
        -W or --HILITE-UNREAD
@@ -802,48 +815,48 @@ LESS(1)                     General Commands Manual                    LESS(1)
               forward movement command larger than one line.
 
        -x\e[4mn\e[24m,... or --tabs=\e[4mn\e[24m,...
-              Sets tab stops.  If only one \e[4mn\e[24m is specified, tab stops  are  set
-              at  multiples  of \e[4mn\e[24m.  If multiple values separated by commas are
-              specified, tab stops are set at those positions, and  then  con-
-              tinue  with  the  same  spacing  as  the last two.  For example,
-              \e[4m-x9,17\e[24m will set tabs at positions  9,  17,  25,  33,  etc.   The
+              Sets  tab  stops.  If only one \e[4mn\e[24m is specified, tab stops are set
+              at multiples of \e[4mn\e[24m.  If multiple values separated by  commas  are
+              specified,  tab  stops are set at those positions, and then con-
+              tinue with the same spacing  as  the  last  two.   For  example,
+              \e[4m-x9,17\e[24m  will  set  tabs  at  positions  9, 17, 25, 33, etc.  The
               default for \e[4mn\e[24m is 8.
 
        -X or --no-init
               Disables sending the termcap initialization and deinitialization
-              strings to the terminal.  This is  sometimes  desirable  if  the
-              deinitialization  string does something unnecessary, like clear-
+              strings  to  the  terminal.   This is sometimes desirable if the
+              deinitialization string does something unnecessary, like  clear-
               ing the screen.
 
        -y\e[4mn\e[24m or --max-forw-scroll=\e[4mn\e[0m
               Specifies a maximum number of lines to scroll forward.  If it is
-              necessary  to  scroll  forward  more than \e[4mn\e[24m lines, the screen is
-              repainted instead.  The -c or -C option may be used  to  repaint
-              from  the top of the screen if desired.  By default, any forward
+              necessary to scroll forward more than \e[4mn\e[24m  lines,  the  screen  is
+              repainted  instead.   The -c or -C option may be used to repaint
+              from the top of the screen if desired.  By default, any  forward
               movement causes scrolling.
 
-       -[z]\e[4mn\e[24m or --window=\e[4mn\e[0m
-              Changes the default scrolling  window  size  to  \e[4mn\e[24m  lines.   The
+       -z\e[4mn\e[24m or --window=\e[4mn\e[24m or -\e[4mn\e[0m
+              Changes  the  default  scrolling  window  size  to \e[4mn\e[24m lines.  The
               default is one screenful.  The z and w commands can also be used
-              to change the window size.  The "z" may be omitted for  compati-
-              bility with some versions of \e[4mmore.\e[24m  If the number \e[4mn\e[24m is negative,
-              it indicates \e[4mn\e[24m lines less than the  current  screen  size.   For
+              to  change the window size.  The "z" may be omitted for compati-
+              bility with some versions of \e[4mmore\e[24m.  If the number \e[4mn\e[24m is negative,
+              it  indicates  \e[4mn\e[24m  lines  less than the current screen size.  For
               example, if the screen is 24 lines, \e[4m-z-4\e[24m sets the scrolling win-
-              dow to 20 lines.  If the screen is  resized  to  40  lines,  the
+              dow  to  20  lines.   If  the screen is resized to 40 lines, the
               scrolling window automatically changes to 36 lines.
 
-       -\e[4m"cc\e[24m or --quotes=\e[4mcc\e[0m
-              Changes  the  filename quoting character.  This may be necessary
-              if you are trying to name a file which contains both spaces  and
-              quote  characters.  Followed by a single character, this changes
-              the quote character to that character.  Filenames  containing  a
+       -"\e[4mcc\e[24m or --quotes=\e[4mcc\e[0m
+              Changes the filename quoting character.  This may  be  necessary
+              if  you are trying to name a file which contains both spaces and
+              quote characters.  Followed by a single character, this  changes
+              the  quote  character to that character.  Filenames containing a
               space should then be surrounded by that character rather than by
-              double quotes.  Followed by two  characters,  changes  the  open
-              quote  to the first character, and the close quote to the second
+              double  quotes.   Followed  by  two characters, changes the open
+              quote to the first character, and the close quote to the  second
               character.  Filenames containing a space should then be preceded
-              by  the  open  quote  character  and followed by the close quote
-              character.  Note  that  even  after  the  quote  characters  are
-              changed,  this  option  remains  -" (a dash followed by a double
+              by the open quote character and  followed  by  the  close  quote
+              character.   Note  that  even  after  the  quote  characters are
+              changed, this option remains -" (a dash  followed  by  a  double
               quote).
 
        -~ or --tilde
@@ -853,46 +866,52 @@ LESS(1)                     General Commands Manual                    LESS(1)
 
        -# or --shift
               Specifies the default number of positions to scroll horizontally
-              in  the RIGHTARROW and LEFTARROW commands.  If the number speci-
-              fied is zero, it sets the default number  of  positions  to  one
+              in the RIGHTARROW and LEFTARROW commands.  If the number  speci-
+              fied  is  zero,  it  sets the default number of positions to one
               half of the screen width.  Alternately, the number may be speci-
-              fied as a fraction of the width of the screen, starting  with  a
-              decimal  point:  .5  is  half  of  the screen width, .3 is three
-              tenths of the screen width, and so on.  If the number is  speci-
-              fied  as  a  fraction,  the actual number of scroll positions is
-              recalculated if the terminal window  is  resized,  so  that  the
-              actual  scroll  remains  at the specified fraction of the screen
+              fied  as  a fraction of the width of the screen, starting with a
+              decimal point: .5 is half of  the  screen  width,  .3  is  three
+              tenths  of the screen width, and so on.  If the number is speci-
+              fied as a fraction, the actual number  of  scroll  positions  is
+              recalculated  if  the  terminal  window  is resized, so that the
+              actual scroll remains at the specified fraction  of  the  screen
               width.
 
        --follow-name
-              Normally, if the input file is renamed while  an  F  command  is
-              executing,  \e[4mless\e[24m  will  continue  to display the contents of the
-              original file despite its  name  change.   If  --follow-name  is
+              Normally,  if  the  input  file is renamed while an F command is
+              executing, \e[4mless\e[24m will continue to display  the  contents  of  the
+              original  file  despite  its  name  change.  If --follow-name is
               specified, during an F command \e[4mless\e[24m will periodically attempt to
               reopen the file by name.  If the reopen succeeds and the file is
-              a  different file from the original (which means that a new file
-              has been created  with  the  same  name  as  the  original  (now
+              a different file from the original (which means that a new  file
+              has  been  created  with  the  same  name  as  the original (now
               renamed) file), \e[4mless\e[24m will display the contents of that new file.
 
        --no-keypad
-              Disables  sending the keypad initialization and deinitialization
+              Disables sending the keypad initialization and  deinitialization
               strings to the terminal.  This is sometimes useful if the keypad
               strings make the numeric keypad behave in an undesirable manner.
 
        --use-backslash
-              This  option changes the interpretations of options which follow
+              This option changes the interpretations of options which  follow
               this one.  After the --use-backslash option, any backslash in an
-              option  string  is  removed and the following character is taken
-              literally.  This allows a dollar sign to be included  in  option
+              option string is removed and the following  character  is  taken
+              literally.   This  allows a dollar sign to be included in option
               strings.
 
+       --rscroll
+              This option changes the character used to mark truncated  lines.
+              It may begin with a two-character attribute indicator like LESS-
+              BINFMT does.  If there is no attribute  indicator,  standout  is
+              used.  If set to "-", truncated lines are not marked.
+
        --     A  command  line  argument of "--" marks the end of option argu-
               ments.  Any arguments following this are  interpreted  as  file-
               names.  This can be useful when viewing a file whose name begins
               with a "-" or "+".
 
        +      If a command line option begins with \e[1m+\e[22m, the  remainder  of  that
-              option  is taken to be an initial command to \e[4mless.\e[24m  For example,
+              option  is taken to be an initial command to \e[4mless\e[24m.  For example,
               +G tells \e[4mless\e[24m to start at the end of the file  rather  than  the
               beginning,  and  +/xyz tells it to start at the first occurrence
               of "xyz" in the file.  As a special case,  +<number>  acts  like
@@ -1019,7 +1038,7 @@ LESS(1)                     General Commands Manual                    LESS(1)
 
 
 \e[1mINPUT PREPROCESSOR\e[0m
-       You may define an "input preprocessor" for \e[4mless.\e[24m  Before \e[4mless\e[24m  opens  a
+       You may define an "input preprocessor" for \e[4mless\e[24m.  Before \e[4mless\e[24m  opens  a
        file, it first gives your input preprocessor a chance to modify the way
        the contents of the file are displayed.  An input preprocessor is  sim-
        ply  an executable program (or shell script), which writes the contents
@@ -1077,7 +1096,7 @@ LESS(1)                     General Commands Manual                    LESS(1)
        types of compressed files, and so on.
 
        It  is  also  possible to set up an input preprocessor to pipe the file
-       data directly to \e[4mless,\e[24m rather than putting the data into a  replacement
+       data directly to \e[4mless\e[24m, rather than putting the data into a  replacement
        file.  This avoids the need to decompress the entire file before start-
        ing to view it.  An input preprocessor that works this way is called an
        input  pipe.   An input pipe, instead of writing the name of a replace-
@@ -1087,7 +1106,9 @@ LESS(1)                     General Commands Manual                    LESS(1)
        ment  file and \e[4mless\e[24m uses the original file, as normal.  To use an input
        pipe, make the first character in the LESSOPEN environment  variable  a
        vertical  bar  (|)  to  signify that the input preprocessor is an input
-       pipe.
+       pipe.  As with non-pipe input preprocessors, the  command  string  must
+       contain  one  occurrence  of %s, which is replaced with the filename of
+       the input file.
 
        For example, on many Unix systems, this script will work like the  pre-
        vious example scripts:
@@ -1108,10 +1129,10 @@ LESS(1)                     General Commands Manual                    LESS(1)
        interpreted  as  meaning there is no replacement, and the original file
        is used.  To avoid this, if LESSOPEN starts with two vertical bars, the
        exit  status  of  the script becomes meaningful.  If the exit status is
-       zero, the output is considered to  be  replacement  text,  even  if  it
+       zero, the output is considered to be replacement text, even  if  it  is
        empty.   If  the  exit status is nonzero, any output is ignored and the
        original file is used.  For compatibility  with  previous  versions  of
-       \e[4mless,\e[24m if LESSOPEN starts with only one vertical bar, the exit status of
+       \e[4mless\e[24m, if LESSOPEN starts with only one vertical bar, the exit status of
        the preprocessor is ignored.
 
        When an input pipe is used, a LESSCLOSE postprocessor can be used,  but
@@ -1119,7 +1140,7 @@ LESS(1)                     General Commands Manual                    LESS(1)
        up.  In this case, the replacement file name passed  to  the  LESSCLOSE
        postprocessor is "-".
 
-       For  compatibility with previous versions of \e[4mless,\e[24m the input preproces-
+       For  compatibility with previous versions of \e[4mless\e[24m, the input preproces-
        sor or pipe is not used if \e[4mless\e[24m is viewing standard input.  However, if
        the  first  character of LESSOPEN is a dash (-), the input preprocessor
        is used on standard input as well as other files.  In  this  case,  the
@@ -1550,7 +1571,7 @@ LESS(1)                     General Commands Manual                    LESS(1)
 
        LESSHISTFILE
               Name of the history file used to remember  search  commands  and
-              shell  commands  between  invocations of \e[4mless.\e[24m  If set to "-" or
+              shell  commands  between  invocations of \e[4mless\e[24m.  If set to "-" or
               "/dev/null", a  history  file  is  not  used.   The  default  is
               "$HOME/.lesshst"  on  Unix  systems, "$HOME/_lesshst" on DOS and
               Windows systems, or "$HOME/lesshst.ini"  or  "$INIT/lesshst.ini"
@@ -1617,7 +1638,7 @@ LESS(1)                     General Commands Manual                    LESS(1)
 
 
 \e[1mCOPYRIGHT\e[0m
-       Copyright (C) 1984-2016  Mark Nudelman
+       Copyright (C) 1984-2017  Mark Nudelman
 
        less is part of the GNU project and is free software.  You  can  redis-
        tribute  it and/or modify it under the terms of either (1) the GNU Gen-
@@ -1645,4 +1666,4 @@ LESS(1)                     General Commands Manual                    LESS(1)
 
 
 
-                           Version 487: 25 Oct 2016                    LESS(1)
+                           Version 530: 05 Dec 2017                    LESS(1)
index c08ffd6..fa0b4ff 100644 (file)
--- a/less.nro
+++ b/less.nro
@@ -1,4 +1,4 @@
-.TH LESS 1 "Version 487: 25 Oct 2016"
+.TH LESS 1 "Version 530: 05 Dec 2017"
 .SH NAME
 less \- opposite of more
 .SH SYNOPSIS
@@ -44,7 +44,7 @@ of the screen are prefixed with a caret.)
 Commands are based on both
 .I more
 and
-.I vi.
+.IR vi .
 Commands may be preceded by a decimal number,
 called N in the descriptions below.
 The number is used by some commands, as indicated.
@@ -174,11 +174,16 @@ respectively.
 For example, "ESC ^B < >" could be used to
 go backward to the < which matches the > in the bottom displayed line.
 .IP m
-Followed by any lowercase letter,
-marks the current position with that letter.
+Followed by any lowercase or uppercase letter,
+marks the first displayed line with that letter.
+If the status column is enabled via the \-J option,
+the status column shows the marked line.
+.IP M
+Acts like m, except the last displayed line is marked
+rather than the first displayed line.
 .IP "'"
 (Single quote.)
-Followed by any lowercase letter, returns to the position which
+Followed by any lowercase or uppercase letter, returns to the position which
 was previously marked with that letter.
 Followed by another single quote, returns to the position at
 which the last "large" movement command was executed.
@@ -188,6 +193,9 @@ Marks are preserved when a new file is examined,
 so the ' command can be used to switch between input files.
 .IP "^X^X"
 Same as single quote.
+.IP "ESC-m"
+Followed by any lowercase or uppercase letter,
+clears the mark identified by that letter.
 .IP /pattern
 Search forward in the file for the N-th line containing the pattern.
 N defaults to 1.
@@ -392,7 +400,7 @@ Prints the version number of
 being run.
 .IP "q or Q or :q or :Q or ZZ"
 Exits
-.I less.
+.IR less .
 .PP
 The following
 four
@@ -417,8 +425,10 @@ On MS-DOS and OS/2 systems, the shell is the normal command processor.
 .IP "| <m> shell-command"
 <m> represents any mark letter.
 Pipes a section of the input file to the given shell command.
-The section of the file to be piped is between the first line on
-the current screen and the position marked by the letter.
+The section of the file to be piped is between the position marked by 
+the letter and the current screen.
+The entire current screen is included, regardless of whether the
+marked position is before or after the current screen.
 <m> may also be ^ or $ to indicate beginning or end of file respectively.
 If <m> is \&.\& or newline, the current screen is piped.
 .IP "s filename"
@@ -449,12 +459,12 @@ For example,
 to avoid typing "less \-options \&...\&" each time
 .I less
 is invoked, you might tell
-.I csh:
+.IR csh :
 .sp
 setenv LESS "\-options"
 .sp
 or if you use
-.I sh:
+.IR sh :
 .sp
 LESS="\-options"; export LESS
 .sp
@@ -532,7 +542,7 @@ By default,
 full screen repaints are done by scrolling from the bottom of the screen.
 .IP "\-C or \-\-CLEAR-SCREEN"
 Same as \-c, for compatibility with older versions of
-.I less.
+.IR less .
 .IP "\-d or \-\-dumb"
 The \-d option suppresses the error message
 normally displayed if the terminal is dumb;
@@ -551,6 +561,8 @@ The first number selects the foreground color and the second selects
 the background color of the text.
 A single number \fIN\fP is the same as \fIN.M\fP,
 where \fIM\fP is the normal background color.
+The color may start or end with \fBu\fP to use underline (with the normal
+color, if by itself), if the system supports it (Windows only).
 \fBx\fP may also be \fBa\fP to toggle strict ANSI sequence rendering (SGR mode).
 
 .IP "\-e or \-\-quit-at-eof"
@@ -635,7 +647,8 @@ However nonrepeated searches (invoked with "/" or "?")
 always begin at the start or end of the current screen respectively.
 .IP "\-J or \-\-status-column"
 Displays a status column at the left edge of the screen.
-The status column shows the lines that matched the current search.
+The status column shows the lines that matched the current search,
+and any lines that are marked (via the m or M command).
 The status column is also used if the \-w or \-W option is in effect.
 .IP "\-k\fIfilename\fP or \-\-lesskey-file=\fIfilename\fP"
 Causes
@@ -677,7 +690,7 @@ prompts with a colon.
 Causes
 .I less
 to prompt even more verbosely than
-.I more.
+.IR more .
 .IP "\-n or \-\-line-numbers"
 Suppresses line numbers.
 The default (to use line numbers) may cause
@@ -710,7 +723,7 @@ the \-o and \-O options can be used from within
 to specify a log file.
 Without a file name, they will simply report the name of the log file.
 The "s" command is equivalent to specifying \-o from within
-.I less.
+.IR less .
 .IP "\-p\fIpattern\fP or \-\-pattern=\fIpattern\fP"
 The \-p option on the command line is equivalent to
 specifying +/\fIpattern\fP;
@@ -733,6 +746,7 @@ to that string.
  \-Ph changes the prompt for the help screen.
  \-P= changes the message printed by the = command.
  \-Pw changes the message printed while waiting for data (in the F command).
+
 All prompt strings consist of a sequence of
 letters and special escape sequences.
 See the section on PROMPTS for more details.
@@ -808,15 +822,15 @@ The \-t option may also be specified from within
 .I less
 (using the \- command) as a way of examining a new file.
 The command ":t" is equivalent to specifying \-t from within
-.I less.
+.IR less .
 .IP "\-T\fItagsfile\fP or \-\-tag-file=\fItagsfile\fP"
 Specifies a tags file to be used instead of "tags".
 .IP "\-u or \-\-underline-special"
 Causes backspaces and carriage returns to be treated as printable characters;
 that is, they are sent to the terminal when they appear in the input.
 .IP "\-U or \-\-UNDERLINE-SPECIAL"
-Causes backspaces, tabs and carriage returns to be
-treated as control characters;
+Causes backspaces, tabs, carriage returns and "formatting characters"
+(as defined by Unicode) to be treated as control characters;
 that is, they are handled as specified by the \-r option.
 .sp
 By default, if neither \-u nor \-U is given,
@@ -835,7 +849,7 @@ Text which is overstruck or underlined can be searched for
 if neither \-u nor \-U is in effect.
 .IP "\-V or \-\-version"
 Displays the version number of
-.I less.
+.IR less .
 .IP "\-w or \-\-hilite-unread"
 Temporarily highlights the first "new" line after a forward movement
 of a full page.
@@ -868,12 +882,12 @@ the screen is repainted instead.
 The \-c or \-C option may be used to repaint from the top of
 the screen if desired.
 By default, any forward movement causes scrolling.
-.IP "\-[z]\fIn\fP or \-\-window=\fIn\fP"
+.IP "\-z\fIn\fP or \-\-window=\fIn\fP or \-\fIn\fP"
 Changes the default scrolling window size to \fIn\fP lines.
 The default is one screenful.
 The z and w commands can also be used to change the window size.
 The "z" may be omitted for compatibility with some versions of
-.I more.
+.IR more .
 If the number
 .I n
 is negative, it indicates
@@ -882,7 +896,7 @@ 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 "\-\fI\(dqcc\fP\ or\ \-\-quotes=\fIcc\fP"
+.IP "\-\(dq\fIcc\fP\ or\ \-\-quotes=\fIcc\fP"
 Changes the filename quoting character.
 This may be necessary if you are trying to name a file
 which contains both spaces and quote characters.
@@ -934,6 +948,11 @@ This option changes the interpretations of options which follow this one.
 After the \-\-use-backslash option, any backslash in an option string is
 removed and the following character is taken literally.
 This allows a dollar sign to be included in option strings.
+.IP "\-\-rscroll"
+This option changes the character used to mark truncated lines.
+It may begin with a two-character attribute indicator like LESSBINFMT does.
+If there is no attribute indicator, standout is used.
+If set to "-", truncated lines are not marked.
 .IP \-\-
 A command line argument of "\-\-" marks the end of option arguments.
 Any arguments following this are interpreted as filenames.
@@ -941,7 +960,7 @@ This can be useful when viewing a file whose name begins with a "\-" or "+".
 .IP +
 If a command line option begins with \fB+\fP,
 the remainder of that option is taken to be an initial command to
-.I less.
+.IR less .
 For example, +G tells
 .I less
 to start at the end of the file rather than the beginning,
@@ -1080,7 +1099,7 @@ On OS/2 systems, the system-wide lesskey file is c:\esysless.ini.
 
 .SH "INPUT PREPROCESSOR"
 You may define an "input preprocessor" for
-.I less.
+.IR less .
 Before
 .I less
 opens a file, it first gives your input preprocessor a chance to modify the
@@ -1165,7 +1184,7 @@ to accept other types of compressed files, and so on.
 .PP
 It is also possible to set up an input preprocessor to
 pipe the file data directly to
-.I less,
+.IR less ,
 rather than putting the data into a replacement file.
 This avoids the need to decompress the entire file before
 starting to view it.
@@ -1180,6 +1199,8 @@ uses the original file, as normal.
 To use an input pipe,
 make the first character in the LESSOPEN environment variable a
 vertical bar (|) to signify that the input preprocessor is an input pipe.
+As with non-pipe input preprocessors, the command string must contain one
+occurrence of %s, which is replaced with the filename of the input file.
 .PP
 For example, on many Unix systems, this script will work like the
 previous example scripts:
@@ -1210,11 +1231,11 @@ the original file is used.
 To avoid this, if LESSOPEN starts with two vertical bars,
 the exit status of the script becomes meaningful.
 If the exit status is zero, the output is considered to be
-replacement text, even if it empty.
+replacement text, even if it is empty.
 If the exit status is nonzero, any output is ignored and the
 original file is used.
 For compatibility with previous versions of
-.I less,
+.IR less ,
 if LESSOPEN starts with only one vertical bar, the exit status
 of the preprocessor is ignored.
 .PP
@@ -1225,7 +1246,7 @@ In this case, the replacement file name passed to the LESSCLOSE
 postprocessor is "\-".
 .PP
 For compatibility with previous versions of
-.I less,
+.IR less ,
 the input preprocessor or pipe is not used if
 .I less
 is viewing standard input.
@@ -1685,7 +1706,7 @@ Normally should be set to "global" if your system has the
 .IP LESSHISTFILE
 Name of the history file used to remember search commands and
 shell commands between invocations of
-.I less.
+.IR less .
 If set to "\-" or "/dev/null", a history file is not used.
 The default is "$HOME/.lesshst" on Unix systems, "$HOME/_lesshst" on
 DOS and Windows systems, or "$HOME/lesshst.ini" or "$INIT/lesshst.ini"
@@ -1745,7 +1766,7 @@ The name of the editor (used for the v command).
 lesskey(1)
 
 .SH COPYRIGHT
-Copyright (C) 1984-2016  Mark Nudelman
+Copyright (C) 1984-2017  Mark Nudelman
 .PP
 less is part of the GNU project and is free software.
 You can redistribute it and/or modify it
index ec7e080..4ed4830 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
index 5f26d4a..de4200c 100644 (file)
@@ -51,4 +51,4 @@ LESSECHO(1)                 General Commands Manual                LESSECHO(1)
 
 
 
-                           Version 487: 25 Oct 2016                LESSECHO(1)
+                           Version 530: 05 Dec 2017                LESSECHO(1)
index d1302c8..49a97ff 100644 (file)
@@ -1,4 +1,4 @@
-.TH LESSECHO 1 "Version 487: 25 Oct 2016"
+.TH LESSECHO 1 "Version 530: 05 Dec 2017"
 .SH NAME
 lessecho \- expand metacharacters
 .SH SYNOPSIS
index f565ec6..fa1ab6d 100644 (file)
--- a/lesskey.c
+++ b/lesskey.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -99,6 +99,7 @@ struct cmdname cmdnames[] =
        { "back-scroll",          A_B_SCROLL },
        { "back-search",          A_B_SEARCH },
        { "back-window",          A_B_WINDOW },
+       { "clear-mark",           A_CLRMARK },
        { "debug",                A_DEBUG },
        { "digit",                A_DIGIT },
        { "display-flag",         A_DISP_OPTION },
@@ -146,6 +147,7 @@ struct cmdname cmdnames[] =
        { "reverse-search-all",   A_T_REVERSE_SEARCH },
        { "right-scroll",         A_RSHIFT },
        { "set-mark",             A_SETMARK },
+       { "set-mark-bottom",      A_SETMARKBOT },
        { "shell",                A_SHELL },
        { "status",               A_STAT },
        { "toggle-flag",          A_OPT_TOGGLE },
@@ -361,9 +363,9 @@ tstr(pp, xlate)
        char **pp;
        int xlate;
 {
-       register char *p;
-       register char ch;
-       register int i;
+       char *p;
+       char ch;
+       int i;
        static char buf[10];
        static char tstr_control_k[] =
                { SK_SPECIAL_KEY, SK_CONTROL_K, 6, 1, 1, 1, '\0' };
@@ -423,7 +425,7 @@ tstr(pp, xlate)
                                case 'e': ch = SK_END; break;
                                case 'x': ch = SK_DELETE; break;
                                default:
-                                       error("illegal char after \\k");
+                                       error("illegal char after \\k", NULL_PARG);
                                        *pp = p+1;
                                        return ("");
                                }
@@ -474,7 +476,7 @@ tstr(pp, xlate)
  */
        public char *
 skipsp(s)
-       register char *s;
+       char *s;
 {
        while (*s == ' ' || *s == '\t') 
                s++;
@@ -486,7 +488,7 @@ skipsp(s)
  */
        public char *
 skipnsp(s)
-       register char *s;
+       char *s;
 {
        while (*s != '\0' && *s != ' ' && *s != '\t')
                s++;
@@ -501,7 +503,7 @@ skipnsp(s)
 clean_line(s)
        char *s;
 {
-       register int i;
+       int i;
 
        s = skipsp(s);
        for (i = 0;  s[i] != '\n' && s[i] != '\r' && s[i] != '\0';  i++)
@@ -520,7 +522,7 @@ add_cmd_char(c)
 {
        if (currtable->pbuffer >= currtable->buffer + MAX_USERCMD)
        {
-               error("too many commands");
+               error("too many commands", NULL_PARG);
                exit(1);
        }
        *(currtable->pbuffer)++ = c;
@@ -620,16 +622,18 @@ findaction(actname)
        for (i = 0;  currtable->names[i].cn_name != NULL;  i++)
                if (strcmp(currtable->names[i].cn_name, actname) == 0)
                        return (currtable->names[i].cn_action);
-       error("unknown action");
+       error("unknown action", NULL_PARG);
        return (A_INVALID);
 }
 
        void
-error(s)
+error(s, parg)
        char *s;
+       PARG *parg;
 {
        fprintf(stderr, "line %d: %s\n", linenum, s);
        errors++;
+       (void) parg;
 }
 
 
@@ -652,7 +656,7 @@ parse_cmdline(p)
                s = tstr(&p, 1);
                cmdlen += (int) strlen(s);
                if (cmdlen > MAX_CMDLEN)
-                       error("command too long");
+                       error("command too long", NULL_PARG);
                else
                        add_cmd_str(s);
        } while (*p != ' ' && *p != '\t' && *p != '\0');
@@ -669,7 +673,7 @@ parse_cmdline(p)
        p = skipsp(p);
        if (*p == '\0')
        {
-               error("missing action");
+               error("missing action", NULL_PARG);
                return;
        }
        actname = p;
@@ -722,7 +726,7 @@ parse_varline(p)
        p = skipsp(p);
        if (*p++ != '=')
        {
-               error("missing =");
+               error("missing =", NULL_PARG);
                return;
        }
 
index 1b6f350..92d4d93 100644 (file)
--- a/lesskey.h
+++ b/lesskey.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
index 9811e8e..99e5f16 100644 (file)
@@ -191,6 +191,8 @@ LESSKEY(1)                  General Commands Manual                 LESSKEY(1)
             \eN       reverse-search-all
             &         filter
             m         set-mark
+            M         set-mark-bottom
+            \em       clear-mark
             '         goto-mark
             ^X^X      goto-mark
             E         examine
@@ -335,7 +337,7 @@ LESSKEY(1)                  General Commands Manual                 LESSKEY(1)
 
 
 \e[1mCOPYRIGHT\e[0m
-       Copyright (C) 1984-2016  Mark Nudelman
+       Copyright (C) 1984-2017  Mark Nudelman
 
        less  is  part of the GNU project and is free software.  You can redis-
        tribute it and/or modify it under the terms of either (1) the GNU  Gen-
@@ -359,4 +361,4 @@ LESSKEY(1)                  General Commands Manual                 LESSKEY(1)
 
 
 
-                           Version 487: 25 Oct 2016                 LESSKEY(1)
+                           Version 530: 05 Dec 2017                 LESSKEY(1)
index 252496c..ffe520b 100644 (file)
@@ -1,4 +1,4 @@
-.TH LESSKEY 1 "Version 487: 25 Oct 2016"
+.TH LESSKEY 1 "Version 530: 05 Dec 2017"
 .SH NAME
 lesskey \- specify key bindings for less
 .SH SYNOPSIS
@@ -208,6 +208,8 @@ default command keys used by less:
        \eeN            reverse-search-all 
        &               filter
        m               set-mark 
+       M               set-mark-bottom
+       \eem            clear-mark
        '               goto-mark 
        ^X^X            goto-mark 
        E               examine 
@@ -361,7 +363,7 @@ which start with a NUL character (0).
 This NUL character should be represented as \e340 in a lesskey file.
 
 .SH COPYRIGHT
-Copyright (C) 1984-2016  Mark Nudelman
+Copyright (C) 1984-2017  Mark Nudelman
 .PP
 less is part of the GNU project and is free software.
 You can redistribute it and/or modify it
diff --git a/lglob.h b/lglob.h
index 0ebf1f6..0d9fb5b 100644 (file)
--- a/lglob.h
+++ b/lglob.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
diff --git a/line.c b/line.c
index f09a13a..dd890f3 100644 (file)
--- a/line.c
+++ b/line.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -7,7 +7,6 @@
  * For more information, see the README file.
  */
 
-
 /*
  * Routines to manipulate the "line buffer".
  * The line buffer holds a line of output as it is being built
 #include "charset.h"
 #include "position.h"
 
+#if MSDOS_COMPILER==WIN32C
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
 static char *linebuf = NULL;   /* Buffer which holds the current output line */
 static char *attr = NULL;      /* Extension of linebuf to hold attributes */
 public int size_linebuf = 0;   /* Size of line buffer (and attr buffer) */
@@ -32,6 +36,8 @@ public POSITION highest_hilite;       /* Pos of last hilite in file found so far */
 static int curr;               /* Index into linebuf */
 static int column;             /* Printable length, accounting for
                                   backspaces, etc. */
+static int right_curr;
+static int right_column;
 static int overstrike;         /* Next char should overstrike previous char */
 static int last_overstrike = AT_NORMAL;
 static int is_null_line;       /* There is no current line */
@@ -41,9 +47,9 @@ static POSITION pendpos;
 static char *end_ansi_chars;
 static char *mid_ansi_chars;
 
-static int attr_swidth();
-static int attr_ewidth();
-static int do_append();
+static int attr_swidth LESSPARAMS ((int a));
+static int attr_ewidth LESSPARAMS ((int a));
+static int do_append LESSPARAMS ((LWCHAR ch, char *rep, POSITION pos));
 
 extern int sigs;
 extern int bs_mode;
@@ -61,6 +67,8 @@ extern int sc_width, sc_height;
 extern int utf_mode;
 extern POSITION start_attnpos;
 extern POSITION end_attnpos;
+extern LWCHAR rscroll_char;
+extern int rscroll_attr;
 
 static char mbc_buf[MAX_UTF_CHAR_LEN];
 static int mbc_buf_len = 0;
@@ -152,6 +160,8 @@ prewind()
 {
        curr = 0;
        column = 0;
+       right_curr = 0;
+       right_column = 0;
        cshift = 0;
        overstrike = 0;
        last_overstrike = AT_NORMAL;
@@ -160,7 +170,33 @@ prewind()
        pendc = '\0';
        lmargin = 0;
        if (status_col)
-               lmargin += 1;
+               lmargin += 2;
+}
+
+/*
+ * Set a character in the line buffer.
+ */
+       static void
+set_linebuf(n, ch, a)
+       int n;
+       LWCHAR ch;
+       char a;
+{
+       linebuf[n] = ch;
+       attr[n] = a;
+}
+
+/*
+ * Append a character to the line buffer.
+ */
+       static void
+add_linebuf(ch, a, w)
+       LWCHAR ch;
+       char a;
+       int w;
+{
+       set_linebuf(curr++, ch, a);
+       column += w;
 }
 
 /*
@@ -170,8 +206,8 @@ prewind()
 plinenum(pos)
        POSITION pos;
 {
-       register LINENUM linenum = 0;
-       register int i;
+       LINENUM linenum = 0;
+       int i;
 
        if (linenums == OPT_ONPLUS)
        {
@@ -191,45 +227,48 @@ plinenum(pos)
         */
        if (status_col)
        {
-               linebuf[curr] = ' ';
-               if (start_attnpos != NULL_POSITION &&
-                   pos >= start_attnpos && pos < end_attnpos)
-                       attr[curr] = AT_NORMAL|AT_HILITE;
-               else
-                       attr[curr] = AT_NORMAL;
-               curr++;
-               column++;
+               int a = AT_NORMAL;
+               char c = posmark(pos);
+               if (c != 0)
+                       a |= AT_HILITE;
+               else 
+               {
+                       c = ' ';
+                       if (start_attnpos != NULL_POSITION &&
+                           pos >= start_attnpos && pos <= end_attnpos)
+                               a |= AT_HILITE;
+               }
+               add_linebuf(c, a, 1); /* column 0: status */
+               add_linebuf(' ', AT_NORMAL, 1); /* column 1: empty */
        }
+
        /*
         * Display the line number at the start of each line
         * if the -N option is set.
         */
        if (linenums == OPT_ONPLUS)
        {
-               char buf[INT_STRLEN_BOUND(pos) + 2];
+               char buf[INT_STRLEN_BOUND(linenum) + 2];
+               int pad = 0;
                int n;
 
                linenumtoa(linenum, buf);
                n = (int) strlen(buf);
                if (n < MIN_LINENUM_WIDTH)
-                       n = MIN_LINENUM_WIDTH;
-               sprintf(linebuf+curr, "%*s ", n, buf);
-               n++;  /* One space after the line number. */
+                       pad = MIN_LINENUM_WIDTH - n;
+               for (i = 0; i < pad; i++)
+                       add_linebuf(' ', AT_NORMAL, 1);
                for (i = 0; i < n; i++)
-                       attr[curr+i] = AT_BOLD;
-               curr += n;
-               column += n;
-               lmargin += n;
+                       add_linebuf(buf[i], AT_BOLD, 1);
+               add_linebuf(' ', AT_NORMAL, 1);
+               lmargin += n + pad + 1;
        }
-
        /*
         * Append enough spaces to bring us to the lmargin.
         */
        while (column < lmargin)
        {
-               linebuf[curr] = ' ';
-               attr[curr++] = AT_NORMAL;
-               column++;
+               add_linebuf(' ', AT_NORMAL, 1);
        }
 }
 
@@ -540,7 +579,7 @@ is_ansi_end(ch)
 }
 
 /*
- *
+ * Can a char appear in an ANSI escape sequence, before the end char?
  */
        public int
 is_ansi_middle(ch)
@@ -554,6 +593,23 @@ is_ansi_middle(ch)
 }
 
 /*
+ * Skip past an ANSI escape sequence.
+ * pp is initially positioned just after the CSI_START char.
+ */
+       public void
+skip_ansi(pp, limit)
+       char **pp;
+       constant char *limit;
+{
+       LWCHAR c;
+       do {
+               c = step_char(pp, +1, limit);
+       } while (*pp < limit && is_ansi_middle(c));
+       /* Note that we discard final char, for which is_ansi_middle is false. */
+}
+
+
+/*
  * Append a character and attribute to the line buffer.
  */
 #define        STORE_CHAR(ch,a,rep,pos) \
@@ -648,11 +704,15 @@ store_char(ch, a, rep, pos)
                        return (1);
        }
 
+       if (column > right_column && w > 0)
+       {
+               right_column = column;
+               right_curr = curr;
+       }
+
        while (replen-- > 0)
        {
-               linebuf[curr] = *rep++;
-               attr[curr] = a;
-               curr++;
+               add_linebuf(*rep++, a, 0);
        }
        column += w;
        return (0);
@@ -851,7 +911,7 @@ do_append(ch, rep, pos)
        char *rep;
        POSITION pos;
 {
-       register int a;
+       int a;
        LWCHAR prev_ch;
 
        a = AT_NORMAL;
@@ -1000,11 +1060,26 @@ pflushmbc()
 }
 
 /*
+ * Switch to normal attribute at end of line.
+ */
+       static void
+add_attr_normal()
+{
+       char *p = "\033[m";
+
+       if (ctldisp != OPT_ONPLUS || !is_ansi_end('m'))
+               return;
+       for ( ;  *p != '\0';  p++)
+               add_linebuf(*p, AT_ANSI, 0);
+}
+
+/*
  * Terminate the line in the line buffer.
  */
        public void
-pdone(endline, forw)
+pdone(endline, chopped, forw)
        int endline;
+       int chopped;
        int forw;
 {
        (void) pflushmbc();
@@ -1023,15 +1098,34 @@ pdone(endline, forw)
        if (cshift < hshift)
                pshift(hshift - cshift);
 
-       if (ctldisp == OPT_ONPLUS && is_ansi_end('m'))
+       if (chopped && rscroll_char)
        {
-               /* Switch to normal attribute at end of line. */
-               char *p = "\033[m";
-               for ( ;  *p != '\0';  p++)
+               /*
+                * Display the right scrolling char.
+                * If we've already filled the rightmost screen char 
+                * (in the buffer), overwrite it.
+                */
+               if (column >= sc_width)
                {
-                       linebuf[curr] = *p;
-                       attr[curr++] = AT_ANSI;
+                       /* We've already written in the rightmost char. */
+                       column = right_column;
+                       curr = right_curr;
                }
+               add_attr_normal();
+               while (column < sc_width-1)
+               {
+                       /*
+                        * Space to last (rightmost) char on screen.
+                        * This may be necessary if the char we overwrote
+                        * was double-width.
+                        */
+                       add_linebuf(' ', AT_NORMAL, 1);
+               }
+               /* Print rscroll char. It must be single-width. */
+               add_linebuf(rscroll_char, rscroll_attr, 1);
+       } else
+       {
+               add_attr_normal();
        }
 
        /*
@@ -1049,9 +1143,7 @@ pdone(endline, forw)
         */
        if (column < sc_width || !auto_wrap || (endline && ignaw) || ctldisp == OPT_ON)
        {
-               linebuf[curr] = '\n';
-               attr[curr] = AT_NORMAL;
-               curr++;
+               add_linebuf('\n', AT_NORMAL, 0);
        } 
        else if (ignaw && column >= sc_width && forw)
        {
@@ -1069,13 +1161,10 @@ pdone(endline, forw)
                 * char on the next line.  We don't need to do this "nudge" 
                 * at the top of the screen anyway.
                 */
-               linebuf[curr] = ' ';
-               attr[curr++] = AT_NORMAL;
-               linebuf[curr] = '\b'; 
-               attr[curr++] = AT_NORMAL;
+               add_linebuf(' ', AT_NORMAL, 1);
+               add_linebuf('\b', AT_NORMAL, -1);
        }
-       linebuf[curr] = '\0';
-       attr[curr] = AT_NORMAL;
+       set_linebuf(curr, '\0', AT_NORMAL);
 }
 
 /*
@@ -1085,8 +1174,7 @@ pdone(endline, forw)
 set_status_col(c)
        char c;
 {
-       linebuf[0] = c;
-       attr[0] = AT_NORMAL|AT_HILITE;
+       set_linebuf(0, c, AT_NORMAL|AT_HILITE);
 }
 
 /*
@@ -1096,8 +1184,8 @@ set_status_col(c)
  */
        public int
 gline(i, ap)
-       register int i;
-       register int *ap;
+       int i;
+       int *ap;
 {
        if (is_null_line)
        {
@@ -1144,8 +1232,8 @@ forw_raw_line(curr_pos, linep, line_lenp)
        char **linep;
        int *line_lenp;
 {
-       register int n;
-       register int c;
+       int n;
+       int c;
        POSITION new_pos;
 
        if (curr_pos == NULL_POSITION || ch_seek(curr_pos) ||
@@ -1193,8 +1281,8 @@ back_raw_line(curr_pos, linep, line_lenp)
        char **linep;
        int *line_lenp;
 {
-       register int n;
-       register int c;
+       int n;
+       int c;
        POSITION new_pos;
 
        if (curr_pos == NULL_POSITION || curr_pos <= ch_zero() ||
index c1a8128..4e72637 100644 (file)
--- a/linenum.c
+++ b/linenum.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -75,7 +75,7 @@ extern int screen_trashed;
        public void
 clr_linenum()
 {
-       register struct linenum_info *p;
+       struct linenum_info *p;
 
        /*
         * Put all the entries on the free list.
@@ -102,7 +102,7 @@ clr_linenum()
  */
        static void
 calcgap(p)
-       register struct linenum_info *p;
+       struct linenum_info *p;
 {
        /*
         * Don't bother to compute a gap for the anchor.
@@ -125,11 +125,11 @@ add_lnum(linenum, pos)
        LINENUM linenum;
        POSITION pos;
 {
-       register struct linenum_info *p;
-       register struct linenum_info *new;
-       register struct linenum_info *nextp;
-       register struct linenum_info *prevp;
-       register POSITION mingap;
+       struct linenum_info *p;
+       struct linenum_info *new;
+       struct linenum_info *nextp;
+       struct linenum_info *prevp;
+       POSITION mingap;
 
        /*
         * Find the proper place in the list for the new one.
@@ -265,8 +265,8 @@ abort_long()
 find_linenum(pos)
        POSITION pos;
 {
-       register struct linenum_info *p;
-       register LINENUM linenum;
+       struct linenum_info *p;
+       LINENUM linenum;
        POSITION cpos;
 
        if (!linenums)
@@ -380,7 +380,7 @@ find_linenum(pos)
 find_pos(linenum)
        LINENUM linenum;
 {
-       register struct linenum_info *p;
+       struct linenum_info *p;
        POSITION cpos;
        LINENUM clinenum;
 
index ea3cfb0..10911eb 100644 (file)
--- a/lsystem.c
+++ b/lsystem.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -42,10 +42,10 @@ lsystem(cmd, donemsg)
        char *cmd;
        char *donemsg;
 {
-       register int inp;
+       int inp;
 #if HAVE_SHELL
-       register char *shell;
-       register char *p;
+       char *shell;
+       char *p;
 #endif
        IFILE save_ifile;
 #if MSDOS_COMPILER && MSDOS_COMPILER!=WIN32C
@@ -289,8 +289,8 @@ pipe_data(cmd, spos, epos)
        POSITION spos;
        POSITION epos;
 {
-       register FILE *f;
-       register int c;
+       FILE *f;
+       int c;
        extern FILE *popen();
 
        /*
diff --git a/main.c b/main.c
index 960d120..179bd78 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -53,10 +53,12 @@ extern int  jump_sline;
 static char consoleTitle[256];
 #endif
 
+public int  line_count;
 extern int     less_is_more;
 extern int     missing_cap;
 extern int     know_dumb;
 extern int     pr_type;
+extern int     quit_if_one_screen;
 
 
 /*
@@ -110,8 +112,9 @@ main(argc, argv)
         * Command line arguments override environment arguments.
         */
        is_tty = isatty(1);
-       get_term();
        init_cmds();
+       get_term();
+       expand_cmd_tables();
        init_charset();
        init_line();
        init_cmdhist();
@@ -179,7 +182,6 @@ main(argc, argv)
                ifile = get_ifile(FAKE_HELPFILE, ifile);
        while (argc-- > 0)
        {
-               char *filename;
 #if (MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC)
                /*
                 * Because the "shell" doesn't expand filename patterns,
@@ -188,25 +190,24 @@ main(argc, argv)
                 * Expand the pattern and iterate over the expanded list.
                 */
                struct textlist tlist;
+               char *filename;
                char *gfilename;
+               char *qfilename;
                
                gfilename = lglob(*argv++);
                init_textlist(&tlist, gfilename);
                filename = NULL;
                while ((filename = forw_textlist(&tlist, filename)) != NULL)
                {
-                       (void) get_ifile(filename, ifile);
+                       qfilename = shell_unquote(filename);
+                       (void) get_ifile(qfilename, ifile);
+                       free(qfilename);
                        ifile = prev_ifile(NULL_IFILE);
                }
                free(gfilename);
 #else
-               filename = shell_quote(*argv);
-               if (filename == NULL)
-                       filename = *argv;
-               argv++;
-               (void) get_ifile(filename, ifile);
+               (void) get_ifile(*argv++, ifile);
                ifile = prev_ifile(NULL_IFILE);
-               free(filename);
 #endif
        }
        /*
@@ -273,10 +274,19 @@ main(argc, argv)
        {
                if (edit_stdin())  /* Edit standard input */
                        quit(QUIT_ERROR);
+               if (quit_if_one_screen)
+                       line_count = get_line_count();
        } else 
        {
                if (edit_first())  /* Edit first valid file in cmd line */
                        quit(QUIT_ERROR);
+               if (quit_if_one_screen)
+               {
+                       if (nifile() == 1)
+                               line_count = get_line_count();
+                       else /* If more than one file, -F can not be used */
+                               quit_if_one_screen = FALSE;
+               }
        }
 
        init();
@@ -292,9 +302,9 @@ main(argc, argv)
  */
        public char *
 save(s)
-       char *s;
+       constant char *s;
 {
-       register char *p;
+       char *p;
 
        p = (char *) ecalloc(strlen(s)+1, sizeof(char));
        strcpy(p, s);
@@ -310,7 +320,7 @@ ecalloc(count, size)
        int count;
        unsigned int size;
 {
-       register VOID_POINTER p;
+       VOID_POINTER p;
 
        p = (VOID_POINTER) calloc(count, size);
        if (p != NULL)
@@ -326,7 +336,7 @@ ecalloc(count, size)
  */
        public char *
 skipsp(s)
-       register char *s;
+       char *s;
 {
        while (*s == ' ' || *s == '\t') 
                s++;
@@ -344,9 +354,9 @@ sprefix(ps, s, uppercase)
        char *s;
        int uppercase;
 {
-       register int c;
-       register int sc;
-       register int len = 0;
+       int c;
+       int sc;
+       int len = 0;
 
        for ( ;  *s != '\0';  s++, ps++)
        {
diff --git a/mark.c b/mark.c
index 9d3e049..fbdac6e 100644 (file)
--- a/mark.c
+++ b/mark.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -9,6 +9,7 @@
 
 
 #include "less.h"
+#include "position.h"
 
 extern IFILE curr_ifile;
 extern int sc_height;
@@ -61,7 +62,7 @@ getumark(c)
 getmark(c)
        int c;
 {
-       register struct mark *m;
+       struct mark *m;
        static struct mark sm;
 
        switch (c)
@@ -86,7 +87,7 @@ getmark(c)
                }
                m = &sm;
                m->m_scrpos.pos = ch_tell();
-               m->m_scrpos.ln = sc_height-1;
+               m->m_scrpos.ln = sc_height;
                m->m_ifile = curr_ifile;
                break;
        case '.':
@@ -94,7 +95,7 @@ getmark(c)
                 * Current position in the current file.
                 */
                m = &sm;
-               get_scrpos(&m->m_scrpos);
+               get_scrpos(&m->m_scrpos, TOP);
                m->m_ifile = curr_ifile;
                break;
        case '\'':
@@ -134,21 +135,37 @@ badmark(c)
  * Set a user-defined mark.
  */
        public void
-setmark(c)
+setmark(c, where)
        int c;
+       int where;
 {
-       register struct mark *m;
+       struct mark *m;
        struct scrpos scrpos;
 
        m = getumark(c);
        if (m == NULL)
                return;
-       get_scrpos(&scrpos);
+       get_scrpos(&scrpos, where);
        m->m_scrpos = scrpos;
        m->m_ifile = curr_ifile;
 }
 
 /*
+ * Clear a user-defined mark.
+ */
+       public void
+clrmark(c)
+       int c;
+{
+       struct mark *m;
+
+       m = getumark(c);
+       if (m == NULL)
+               return;
+       m->m_scrpos.pos = NULL_POSITION;
+}
+
+/*
  * Set lmark (the mark named by the apostrophe).
  */
        public void
@@ -158,7 +175,7 @@ lastmark()
 
        if (ch_getflags() & CH_HELPFILE)
                return;
-       get_scrpos(&scrpos);
+       get_scrpos(&scrpos, TOP);
        if (scrpos.pos == NULL_POSITION)
                return;
        marks[LASTMARK].m_scrpos = scrpos;
@@ -172,7 +189,7 @@ lastmark()
 gomark(c)
        int c;
 {
-       register struct mark *m;
+       struct mark *m;
        struct scrpos scrpos;
 
        m = getmark(c);
@@ -220,7 +237,7 @@ gomark(c)
 markpos(c)
        int c;
 {
-       register struct mark *m;
+       struct mark *m;
 
        m = getmark(c);
        if (m == NULL)
@@ -235,6 +252,27 @@ markpos(c)
 }
 
 /*
+ * Return the mark associated with a given position, if any.
+ */
+       public char
+posmark(pos)
+       POSITION pos;
+{
+       int i;
+
+       /* Only lower case and upper case letters */
+       for (i = 0;  i < 26*2;  i++)
+       {
+               if (marks[i].m_ifile == curr_ifile && marks[i].m_scrpos.pos == pos)
+               {
+                       if (i < 26) return 'a' + i;
+                       return 'A' + i - 26;
+               }
+       }
+       return 0;
+}
+
+/*
  * Clear the marks associated with a specified ifile.
  */
        public void
diff --git a/mkfuncs.awk b/mkfuncs.awk
deleted file mode 100755 (executable)
index dea28ac..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-BEGIN { FS="("; state = 0 }
-
-/^     public/ { ftype = $0; state = 1 }
-
-{ if (state == 1)
-       state = 2
-  else if (state == 2)
-       { print ftype,$1,"();"; state = 0 }
-}
diff --git a/mkfuncs.pl b/mkfuncs.pl
new file mode 100644 (file)
index 0000000..3541733
--- /dev/null
@@ -0,0 +1,27 @@
+#! /usr/bin/perl
+use strict;
+
+my $state = 0;
+my $def;
+my $params;
+
+while (<>) {
+       if (/^\tpublic\s+(.*)/) {
+               $def = "public $1";
+               $state = 1;
+               $params = 0;
+       } elsif ($state == 1 and /(\w+)\s*\(/) {
+               $def .= " $1 LESSPARAMS ((";
+               $state = 2;
+       } elsif ($state == 2) {
+               if (/^{/) {
+                       $def .= 'VOID_PARAM' if not $params;
+                       print "$def));\n";
+                       $state = 0;
+               } elsif (/^\s*([^;]*)/) {
+                       $def .= ', ' if substr($def,-1) ne '(';
+                       $def .= $1;
+                       $params = 1;
+               }
+       }
+}
diff --git a/mkhelp.c b/mkhelp.c
deleted file mode 100644 (file)
index fb486ef..0000000
--- a/mkhelp.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 1984-2016  Mark Nudelman
- *
- * You may distribute under the terms of either the GNU General Public
- * License or the Less License, as specified in the README file.
- *
- * For more information, see the README file.
- */
-
-
-/*
- * Silly little program to generate the help.c source file
- * from the less.hlp text file.
- * help.c just contains a char array whose contents are 
- * the contents of less.hlp.
- */
-
-#include <stdio.h>
-
-       int
-main(argc, argv)
-       int argc;
-       char *argv[];
-{
-       int ch;
-       int prevch;
-
-       printf("/* This file was generated by mkhelp from less.hlp */\n");
-       printf("#include \"less.h\"\n");
-       printf("constant char helpdata[] = {\n");
-       ch = 0;
-       while (prevch = ch, (ch = getchar()) != EOF)
-       {
-               switch (ch)
-               {
-               case '\'':
-                       printf("'\\'',");
-                       break;
-               case '\\':
-                       printf("'\\\\',");
-                       break;
-               case '\b':
-                       printf("'\\b',");
-                       break;
-               case '\t':
-                       printf("'\\t',");
-                       break;
-               case '\n':
-                       if (prevch != '\r') 
-                               printf("'\\n',\n");
-                       break;
-               case '\r':
-                       if (prevch != '\n') 
-                               printf("'\\n',\n");
-                       break;
-               default:
-                       if (ch >= ' ' && ch < 0x7f)
-                               printf("'%c',", ch);
-                       else
-                               printf("0x%02x,", ch);
-                       break;
-               }
-       }
-       /* Add an extra null char to avoid having a trailing comma. */
-       printf(" 0 };\n");
-       printf("constant int size_helpdata = sizeof(helpdata) - 1;\n");
-       return (0);
-}
diff --git a/mkhelp.pl b/mkhelp.pl
new file mode 100755 (executable)
index 0000000..a826e20
--- /dev/null
+++ b/mkhelp.pl
@@ -0,0 +1,44 @@
+#! /usr/bin/perl
+use strict;
+
+# Silly little program to generate the help.c source file
+# from the less.hlp text file.
+# The output of this script is a C program defining a char array 
+# whose content is the input to this script.
+
+{
+    my ($sec,$min,$hour,$mday,$mon,$year) = gmtime();
+    printf "/* This file was generated by mkhelp.pl from less.hlp at %d:%02d on %d/%d/%d */\n",
+        $hour, $min, $year+1900, $mon+1, $mday;
+    print "#include \"less.h\"\n";
+    print "constant char helpdata[] = {\n";
+    my $ch = 0;
+    my $prevch;
+    for (;;) {
+        $prevch = $ch;
+        $ch = getc();
+        last if not defined $ch;
+        if ($ch eq "'") {
+            print "'\\'',";
+        } elsif ($ch eq "\\") {
+            print "'\\\\',";
+        } elsif ($ch eq "\b") {
+            print "'\\b',";
+        } elsif ($ch eq "\t") {
+            print "'\\t',";
+        } elsif ($ch eq "\n") {
+            print "'\\n',\n" if $prevch ne "\r";
+        } elsif ($ch eq "\r") {
+            print "'\\n',\n" if $prevch ne "\n";
+        } else {
+            if (ord($ch) >= ord(' ') && ord($ch) < 0x7f) {
+                print "'$ch',";
+            } else {
+                printf "0x%02x,", ord($ch);
+            }
+        }
+    }
+    # Add an extra null char to avoid having a trailing comma.
+    print " 0 };\n";
+    print "constant int size_helpdata = sizeof(helpdata) - 1;\n";
+}
index ff107b5..2760628 100755 (executable)
--- a/mkutable
+++ b/mkutable
@@ -11,6 +11,16 @@ use vars qw( $opt_f $opt_n );
 use Getopt::Std;
 my $type_field = 2;
 
+# Override Unicode tables for certain control chars
+# that are expected to be found in normal text files.
+my %force_space = (
+    0x08 => 1, # backspace
+    0x09 => 1, # tab
+    0x0a => 1, # newline
+    0x0c => 1, # form feed
+    0x0d => 1, # carriage return
+);
+
 exit (main() ? 0 : 1);
 
 sub main {
@@ -47,6 +57,7 @@ sub main {
         my $type = $fields[$type_field];
         $type =~ s/\s//g;
         for ($last_code = $lo_code; $last_code <= $hi_code; ++$last_code) {
+            $type = 'Zs' if $force_space{$last_code};
             output(\%out, $last_code, $type);
         }
     }
index 44f8e5f..9185c01 100644 (file)
--- a/optfunc.c
+++ b/optfunc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -47,9 +47,11 @@ extern char *every_first_cmd;
 extern IFILE curr_ifile;
 extern char version[];
 extern int jump_sline;
-extern int jump_sline_fraction;
+extern long jump_sline_fraction;
 extern int shift_count;
-extern int shift_count_fraction;
+extern long shift_count_fraction;
+extern LWCHAR rscroll_char;
+extern int rscroll_attr;
 extern int less_is_more;
 #if LOGFILE
 extern char *namelogfile;
@@ -68,6 +70,11 @@ extern int ul_fg_color, ul_bg_color;
 extern int so_fg_color, so_bg_color;
 extern int bl_fg_color, bl_bg_color;
 extern int sgr_mode;
+#if MSDOS_COMPILER==WIN32C
+#ifndef COMMON_LVB_UNDERSCORE
+#define COMMON_LVB_UNDERSCORE 0x8000
+#endif
+#endif
 #endif
 
 
@@ -81,6 +88,7 @@ opt_o(type, s)
        char *s;
 {
        PARG parg;
+       char *filename;
 
        if (secure)
        {
@@ -106,7 +114,9 @@ opt_o(type, s)
                s = skipsp(s);
                if (namelogfile != NULL)
                        free(namelogfile);
-               namelogfile = lglob(s);
+               filename = lglob(s);
+               namelogfile = shell_unquote(filename);
+               free(filename);
                use_logfile(namelogfile);
                sync_logfile();
                break;
@@ -180,7 +190,7 @@ opt_j(type, s)
                } else
                {
 
-                       sprintf(buf, ".%06d", jump_sline_fraction);
+                       sprintf(buf, ".%06ld", jump_sline_fraction);
                        len = (int) strlen(buf);
                        while (len > 2 && buf[len-1] == '0')
                                len--;
@@ -245,7 +255,7 @@ opt_shift(type, s)
                } else
                {
 
-                       sprintf(buf, ".%06d", shift_count_fraction);
+                       sprintf(buf, ".%06ld", shift_count_fraction);
                        len = (int) strlen(buf);
                        while (len > 2 && buf[len-1] == '0')
                                len--;
@@ -336,6 +346,7 @@ opt__T(type, s)
        char *s;
 {
        PARG parg;
+       char *filename;
 
        switch (type)
        {
@@ -346,7 +357,9 @@ opt__T(type, s)
                s = skipsp(s);
                if (tags != NULL && tags != ztags)
                        free(tags);
-               tags = lglob(s);
+               filename = lglob(s);
+               tags = shell_unquote(filename);
+               free(filename);
                break;
        case QUERY:
                parg.p_string = tags;
@@ -362,7 +375,7 @@ opt__T(type, s)
        public void
 opt_p(type, s)
        int type;
-       register char *s;
+       char *s;
 {
        switch (type)
        {
@@ -398,9 +411,9 @@ opt_p(type, s)
        public void
 opt__P(type, s)
        int type;
-       register char *s;
+       char *s;
 {
-       register char **proto;
+       char **proto;
        PARG parg;
 
        switch (type)
@@ -518,7 +531,7 @@ opt__V(type, s)
                putstr("no ");
 #endif
                putstr("regular expressions)\n");
-               putstr("Copyright (C) 1984-2016  Mark Nudelman\n\n");
+               putstr("Copyright (C) 1984-2017  Mark Nudelman\n\n");
                putstr("less comes with NO WARRANTY, to the extent permitted by law.\n");
                putstr("For information about the terms of redistribution,\n");
                putstr("see the file named README in the less distribution.\n");
@@ -540,12 +553,27 @@ colordesc(s, fg_color, bg_color)
 {
        int fg, bg;
        int err;
-       
+#if MSDOS_COMPILER==WIN32C
+       int ul = 0;
+       
+       if (*s == 'u')
+       {
+               ul = COMMON_LVB_UNDERSCORE;
+               ++s;
+       }
+#endif
        fg = getnum(&s, "D", &err);
        if (err)
        {
-               error("Missing fg color in -D", NULL_PARG);
-               return;
+#if MSDOS_COMPILER==WIN32C
+               if (ul)
+                       fg = nm_fg_color;
+               else
+#endif
+               {
+                       error("Missing fg color in -D", NULL_PARG);
+                       return;
+               }
        }
        if (*s != '.')
                bg = nm_bg_color;
@@ -559,6 +587,14 @@ colordesc(s, fg_color, bg_color)
                        return;
                }
        }
+#if MSDOS_COMPILER==WIN32C
+       if (*s == 'u')
+       {
+               ul = COMMON_LVB_UNDERSCORE;
+               ++s;
+       }
+       fg |= ul;
+#endif
        if (*s != '\0')
                error("Extra characters at end of -D option", NULL_PARG);
        *fg_color = fg;
@@ -624,7 +660,7 @@ opt_D(type, s)
        public void
 opt_x(type, s)
        int type;
-       register char *s;
+       char *s;
 {
        extern int tabstops[];
        extern int ntabstops;
@@ -682,7 +718,7 @@ opt_x(type, s)
        public void
 opt_quote(type, s)
        int type;
-       register char *s;
+       char *s;
 {
        char buf[3];
        PARG parg;
@@ -718,6 +754,40 @@ opt_quote(type, s)
 }
 
 /*
+ * Handler for the --rscroll option.
+ */
+       /*ARGSUSED*/
+       public void
+opt_rscroll(type, s)
+       int type;
+       char *s;
+{
+       PARG p;
+
+       switch (type)
+       {
+       case INIT:
+       case TOGGLE: {
+               char *fmt;
+               int attr = AT_STANDOUT;
+               setfmt(s, &fmt, &attr, "*s>");
+               if (strcmp(fmt, "-") == 0)
+               {
+                       rscroll_char = 0;
+               } else
+               {
+                       rscroll_char = *fmt ? *fmt : '>';
+                       rscroll_attr = attr;
+               }
+               break; }
+       case QUERY: {
+               p.p_string = rscroll_char ? prchar(rscroll_char) : "-";
+               error("rscroll char is %s", &p);
+               break; }
+       }
+}
+
+/*
  * "-?" means display a help message.
  * If from the command line, exit immediately.
  */
index f0f3b30..8ba67bc 100644 (file)
--- a/option.c
+++ b/option.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -69,8 +69,8 @@ propt(c)
 scan_option(s)
        char *s;
 {
-       register struct loption *o;
-       register int optc;
+       struct loption *o;
+       int optc;
        char *optname;
        char *printopt;
        char *str;
@@ -305,7 +305,7 @@ toggle_option(o, lower, s, how_toggle)
        char *s;
        int how_toggle;
 {
-       register int num;
+       int num;
        int no_prompt;
        int err;
        PARG parg;
@@ -568,8 +568,8 @@ optstring(s, p_str, printopt, validchars)
        char *printopt;
        char *validchars;
 {
-       register char *p;
-       register char *out;
+       char *p;
+       char *out;
 
        if (*s == '\0')
        {
@@ -632,9 +632,9 @@ getnum(sp, printopt, errp)
        char *printopt;
        int *errp;
 {
-       register char *s;
-       register int n;
-       register int neg;
+       char *s;
+       int n;
+       int neg;
 
        s = skipsp(*sp);
        neg = FALSE;
@@ -669,7 +669,7 @@ getfraction(sp, printopt, errp)
        char *printopt;
        int *errp;
 {
-       register char *s;
+       char *s;
        long frac = 0;
        int fraclen = 0;
 
index 38e08f7..b253da8 100644 (file)
--- a/option.h
+++ b/option.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -60,7 +60,7 @@ struct loption
        int otype;              /* Type of the option */
        int odefault;           /* Default value */
        int *ovar;              /* Pointer to the associated variable */
-       void (*ofunc)();        /* Pointer to special handling function */
+       void (*ofunc) LESSPARAMS ((int, char*)); /* Pointer to special handling function */
        char *odesc[3];         /* Description of each value */
 };
 
index 0383837..0c68ccc 100644 (file)
--- a/opttbl.c
+++ b/opttbl.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -53,6 +53,8 @@ public int quit_on_intr;      /* Quit on interrupt */
 public int follow_mode;                /* F cmd Follows file desc or file name? */
 public int oldbot;             /* Old bottom of screen behavior {{REMOVE}} */
 public int opt_use_backslash;  /* Use backslash escaping in option parsing */
+public LWCHAR rscroll_char;    /* Char which marks chopped lines with -S */
+public int rscroll_attr;       /* Attribute of rscroll_char */
 #if HILITE_SEARCH
 public int hilite_search;      /* Highlight matched search patterns? */
 #endif
@@ -117,6 +119,7 @@ static struct optname keypad_optname = { "no-keypad",            NULL };
 static struct optname oldbot_optname = { "old-bot",              NULL };
 static struct optname follow_optname = { "follow-name",          NULL };
 static struct optname use_backslash_optname = { "use-backslash", NULL };
+static struct optname rscroll_optname = { "rscroll", NULL };
 
 
 /*
@@ -456,6 +459,10 @@ static struct loption option[] =
                        NULL
                }
        },
+       { OLETTER_NONE, &rscroll_optname,
+               STRING|REPAINT|INIT_HANDLER, 0, NULL, opt_rscroll,
+               { "right scroll character: ", NULL, NULL }
+       },
        { '\0', NULL, NOVAR, 0, NULL, NULL, { NULL, NULL, NULL } }
 };
 
@@ -466,7 +473,7 @@ static struct loption option[] =
        public void
 init_option()
 {
-       register struct loption *o;
+       struct loption *o;
        char *p;
 
        p = lgetenv("LESS_IS_MORE");
@@ -492,7 +499,7 @@ init_option()
 findopt(c)
        int c;
 {
-       register struct loption *o;
+       struct loption *o;
 
        for (o = option;  o->oletter != '\0';  o++)
        {
@@ -533,9 +540,9 @@ findopt_name(p_optname, p_oname, p_err)
        int *p_err;
 {
        char *optname = *p_optname;
-       register struct loption *o;
-       register struct optname *oname;
-       register int len;
+       struct loption *o;
+       struct optname *oname;
+       int len;
        int uppercase;
        struct loption *maxo = NULL;
        struct optname *maxoname = NULL;
diff --git a/os.c b/os.c
index 61f116b..df11761 100644 (file)
--- a/os.c
+++ b/os.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -62,10 +62,10 @@ extern int sigs;
        public int
 iread(fd, buf, len)
        int fd;
-       char *buf;
+       unsigned char *buf;
        unsigned int len;
 {
-       register int n;
+       int n;
 
 start:
 #if MSDOS_COMPILER==WIN32C
@@ -226,8 +226,8 @@ strerror(err)
 errno_message(filename)
        char *filename;
 {
-       register char *p;
-       register char *m;
+       char *p;
+       char *m;
        int len;
 #if HAVE_ERRNO
 #if MUST_DEFINE_ERRNO
@@ -271,7 +271,8 @@ muldiv(val, num, den)
  */
        public int
 percentage(num, den)
-       POSITION num, den;
+       POSITION num;
+       POSITION den;
 {
        return (int) muldiv(num,  (POSITION) 100, den);
 }
index 77e6b39..c6a9981 100644 (file)
--- a/output.c
+++ b/output.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -15,6 +15,9 @@
 #include "less.h"
 #if MSDOS_COMPILER==WIN32C
 #include "windows.h"
+#ifndef COMMON_LVB_UNDERSCORE
+#define COMMON_LVB_UNDERSCORE 0x8000
+#endif
 #endif
 
 public int errmsgs;    /* Count of messages displayed by error() */
@@ -38,6 +41,9 @@ extern int ul_fg_color, ul_bg_color;
 extern int so_fg_color, so_bg_color;
 extern int bl_fg_color, bl_bg_color;
 extern int sgr_mode;
+#if MSDOS_COMPILER==WIN32C
+extern int have_ul;
+#endif
 #endif
 
 /*
@@ -46,8 +52,8 @@ extern int sgr_mode;
        public void
 put_line()
 {
-       register int c;
-       register int i;
+       int c;
+       int i;
        int a;
 
        if (ABORT_SIGS())
@@ -96,8 +102,8 @@ static char *ob = obuf;
        public void
 flush()
 {
-       register int n;
-       register int fd;
+       int n;
+       int fd;
 
        n = (int) (ob - obuf);
        if (n == 0)
@@ -127,9 +133,9 @@ flush()
                         * the -D command-line option.
                         */
                        char *anchor, *p, *p_next;
-                       static unsigned char fg, fgi, bg, bgi;
-                       static unsigned char at;
-                       unsigned char f, b;
+                       static int fg, fgi, bg, bgi;
+                       static int at;
+                       int f, b;
 #if MSDOS_COMPILER==WIN32C
                        /* Screen colors used by 3x and 4x SGR commands. */
                        static unsigned char screen_color[] = {
@@ -259,8 +265,13 @@ flush()
                                                case 7: /* inverse on */
                                                        at |= 2;
                                                        break;
-                                               case 4: /* underline on */
-                                                       bgi = 8;
+                                               case 4: /* underline on */
+#if MSDOS_COMPILER==WIN32C
+                                                       if (have_ul)
+                                                               bgi = COMMON_LVB_UNDERSCORE >> 4;
+                                                       else
+#endif
+                                                               bgi = 8;
                                                        at |= 4;
                                                        break;
                                                case 5: /* slow blink on */
@@ -356,7 +367,11 @@ flush()
                                        if (at & 16)
                                                f = b ^ 8;
                                        f &= 0xf;
-                                       b &= 0xf;
+#if MSDOS_COMPILER==WIN32C
+                                       b &= 0xf | (COMMON_LVB_UNDERSCORE >> 4);
+#else
+                                       b &= 0xf;
+#endif
                                        WIN32setcolors(f, b);
                                        p_next = anchor = p + 1;
                                } else
@@ -436,7 +451,7 @@ putchr(c)
  */
        public void
 putstr(s)
-       register char *s;
+       constant char *s;
 {
        while (*s != '\0')
                putchr(*s++);
@@ -453,7 +468,7 @@ void funcname(num, buf) \
 { \
        int neg = (num < 0); \
        char tbuf[INT_STRLEN_BOUND(num)+2]; \
-       register char *s = tbuf + sizeof(tbuf); \
+       char *s = tbuf + sizeof(tbuf); \
        if (neg) num = -num; \
        *--s = '\0'; \
        do { \
@@ -501,11 +516,11 @@ iprint_linenum(num)
  */
        static int
 less_printf(fmt, parg)
-       register char *fmt;
+       char *fmt;
        PARG *parg;
 {
-       register char *s;
-       register int col;
+       char *s;
+       int col;
 
        col = 0;
        while (*fmt != '\0')
@@ -536,6 +551,9 @@ less_printf(fmt, parg)
                                col += iprint_linenum(parg->p_linenum);
                                parg++;
                                break;
+                       case '%':
+                               putchr('%');
+                               break;
                        }
                }
        }
@@ -600,7 +618,7 @@ error(fmt, parg)
 
        get_return();
        lower_left();
-    clear_eol();
+       clear_eol();
 
        if (col >= sc_width)
                /*
@@ -645,7 +663,7 @@ query(fmt, parg)
        char *fmt;
        PARG *parg;
 {
-       register int c;
+       int c;
        int col = 0;
 
        if (any_display && is_tty)
index 97a73e9..563bde0 100644 (file)
--- a/pattern.c
+++ b/pattern.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -12,7 +12,6 @@
  */
 
 #include "less.h"
-#include "pattern.h"
 
 extern int caseless;
 
@@ -23,7 +22,7 @@ extern int caseless;
 compile_pattern2(pattern, search_type, comp_pattern, show_error)
        char *pattern;
        int search_type;
-       void **comp_pattern;
+       PATTERN_TYPE *comp_pattern;
        int show_error;
 {
        if (search_type & SRCH_NO_REGEX)
@@ -32,8 +31,6 @@ compile_pattern2(pattern, search_type, comp_pattern, show_error)
 #if HAVE_GNU_REGEX
        struct re_pattern_buffer *comp = (struct re_pattern_buffer *)
                ecalloc(1, sizeof(struct re_pattern_buffer));
-       struct re_pattern_buffer **pcomp = 
-               (struct re_pattern_buffer **) comp_pattern;
        re_set_syntax(RE_SYNTAX_POSIX_EXTENDED);
        if (re_compile_pattern(pattern, strlen(pattern), comp))
        {
@@ -42,13 +39,15 @@ compile_pattern2(pattern, search_type, comp_pattern, show_error)
                        error("Invalid pattern", NULL_PARG);
                return (-1);
        }
-       if (*pcomp != NULL)
-               regfree(*pcomp);
-       *pcomp = comp;
+       if (*comp_pattern != NULL)
+       {
+               regfree(*comp_pattern);
+               free(*comp_pattern);
+       }
+       *comp_pattern = comp;
 #endif
 #if HAVE_POSIX_REGCOMP
        regex_t *comp = (regex_t *) ecalloc(1, sizeof(regex_t));
-       regex_t **pcomp = (regex_t **) comp_pattern;
        if (regcomp(comp, pattern, REGCOMP_FLAG))
        {
                free(comp);
@@ -56,13 +55,15 @@ compile_pattern2(pattern, search_type, comp_pattern, show_error)
                        error("Invalid pattern", NULL_PARG);
                return (-1);
        }
-       if (*pcomp != NULL)
-               regfree(*pcomp);
-       *pcomp = comp;
+       if (*comp_pattern != NULL)
+       {
+               regfree(*comp_pattern);
+               free(*comp_pattern);
+       }
+       *comp_pattern = comp;
 #endif
 #if HAVE_PCRE
        pcre *comp;
-       pcre **pcomp = (pcre **) comp_pattern;
        constant char *errstring;
        int erroffset;
        PARG parg;
@@ -75,35 +76,32 @@ compile_pattern2(pattern, search_type, comp_pattern, show_error)
                        error("%s", &parg);
                return (-1);
        }
-       *pcomp = comp;
+       *comp_pattern = comp;
 #endif
 #if HAVE_RE_COMP
        PARG parg;
-       int *pcomp = (int *) comp_pattern;
        if ((parg.p_string = re_comp(pattern)) != NULL)
        {
                if (show_error)
                        error("%s", &parg);
                return (-1);
        }
-       *pcomp = 1;
+       *comp_pattern = 1;
 #endif
 #if HAVE_REGCMP
        char *comp;
-       char **pcomp = (char **) comp_pattern;
        if ((comp = regcmp(pattern, 0)) == NULL)
        {
                if (show_error)
                        error("Invalid pattern", NULL_PARG);
                return (-1);
        }
-       if (pcomp != NULL)
-               free(*pcomp);
-       *pcomp = comp;
+       if (comp_pattern != NULL)
+               free(*comp_pattern);
+       *comp_pattern = comp;
 #endif
 #if HAVE_V8_REGCOMP
        struct regexp *comp;
-       struct regexp **pcomp = (struct regexp **) comp_pattern;
        reg_show_error = show_error;
        comp = regcomp(pattern);
        reg_show_error = 1;
@@ -115,9 +113,9 @@ compile_pattern2(pattern, search_type, comp_pattern, show_error)
                 */
                return (-1);
        }
-       if (*pcomp != NULL)
-               free(*pcomp);
-       *pcomp = comp;
+       if (*comp_pattern != NULL)
+               free(*comp_pattern);
+       *comp_pattern = comp;
 #endif
   }
        return (0);
@@ -130,7 +128,7 @@ compile_pattern2(pattern, search_type, comp_pattern, show_error)
 compile_pattern(pattern, search_type, comp_pattern)
        char *pattern;
        int search_type;
-       void **comp_pattern;
+       PATTERN_TYPE *comp_pattern;
 {
        char *cvt_pattern;
        int result;
@@ -153,41 +151,41 @@ compile_pattern(pattern, search_type, comp_pattern)
  */
        public void
 uncompile_pattern(pattern)
-       void **pattern;
+       PATTERN_TYPE *pattern;
 {
 #if HAVE_GNU_REGEX
-       struct re_pattern_buffer **pcomp = (struct re_pattern_buffer **) pattern;
-       if (*pcomp != NULL)
-               regfree(*pcomp);
-       *pcomp = NULL;
+       if (*pattern != NULL)
+       {
+               regfree(*pattern);
+               free(*pattern);
+       }
+       *pattern = NULL;
 #endif
 #if HAVE_POSIX_REGCOMP
-       regex_t **pcomp = (regex_t **) pattern;
-       if (*pcomp != NULL)
-               regfree(*pcomp);
-       *pcomp = NULL;
+       if (*pattern != NULL)
+       {
+               regfree(*pattern);
+               free(*pattern);
+       }
+       *pattern = NULL;
 #endif
 #if HAVE_PCRE
-       pcre **pcomp = (pcre **) pattern;
-       if (*pcomp != NULL)
-               pcre_free(*pcomp);
-       *pcomp = NULL;
+       if (*pattern != NULL)
+               pcre_free(*pattern);
+       *pattern = NULL;
 #endif
 #if HAVE_RE_COMP
-       int *pcomp = (int *) pattern;
-       *pcomp = 0;
+       *pattern = 0;
 #endif
 #if HAVE_REGCMP
-       char **pcomp = (char **) pattern;
-       if (*pcomp != NULL)
-               free(*pcomp);
-       *pcomp = NULL;
+       if (*pattern != NULL)
+               free(*pattern);
+       *pattern = NULL;
 #endif
 #if HAVE_V8_REGCOMP
-       struct regexp **pcomp = (struct regexp **) pattern;
-       if (*pcomp != NULL)
-               free(*pcomp);
-       *pcomp = NULL;
+       if (*pattern != NULL)
+               free(*pattern);
+       *pattern = NULL;
 #endif
 }
 
@@ -198,7 +196,7 @@ uncompile_pattern(pattern)
 valid_pattern(pattern)
        char *pattern;
 {
-       void *comp_pattern;
+       PATTERN_TYPE comp_pattern;
        int result;
 
        CLEAR_PATTERN(comp_pattern);
@@ -214,7 +212,7 @@ valid_pattern(pattern)
  */
        public int
 is_null_pattern(pattern)
-       void *pattern;
+       PATTERN_TYPE pattern;
 {
 #if HAVE_GNU_REGEX
        return (pattern == NULL);
@@ -251,9 +249,9 @@ match(pattern, pattern_len, buf, buf_len, pfound, pend)
        int buf_len;
        char **pfound, **pend;
 {
-       register char *pp, *lp;
-       register char *pattern_end = pattern + pattern_len;
-       register char *buf_end = buf + buf_len;
+       char *pp, *lp;
+       char *pattern_end = pattern + pattern_len;
+       char *buf_end = buf + buf_len;
 
        for ( ;  buf < buf_end;  buf++)
        {
@@ -286,7 +284,7 @@ match(pattern, pattern_len, buf, buf_len, pfound, pend)
  */
        public int
 match_pattern(pattern, tpattern, line, line_len, sp, ep, notbol, search_type)
-       void *pattern;
+       PATTERN_TYPE pattern;
        char *tpattern;
        char *line;
        int line_len;
@@ -296,24 +294,6 @@ match_pattern(pattern, tpattern, line, line_len, sp, ep, notbol, search_type)
        int search_type;
 {
        int matched;
-#if HAVE_GNU_REGEX
-       struct re_pattern_buffer *spattern = (struct re_pattern_buffer *) pattern;
-#endif
-#if HAVE_POSIX_REGCOMP
-       regex_t *spattern = (regex_t *) pattern;
-#endif
-#if HAVE_PCRE
-       pcre *spattern = (pcre *) pattern;
-#endif
-#if HAVE_RE_COMP
-       int spattern = (int) pattern;
-#endif
-#if HAVE_REGCMP
-       char *spattern = (char *) pattern;
-#endif
-#if HAVE_V8_REGCOMP
-       struct regexp *spattern = (struct regexp *) pattern;
-#endif
 
        *sp = *ep = NULL;
 #if NO_REGEX
@@ -326,9 +306,9 @@ match_pattern(pattern, tpattern, line, line_len, sp, ep, notbol, search_type)
 #if HAVE_GNU_REGEX
        {
                struct re_registers search_regs;
-               spattern->not_bol = notbol;
-               spattern->regs_allocated = REGS_UNALLOCATED;
-               matched = re_search(spattern, line, line_len, 0, line_len, &search_regs) >= 0;
+               pattern->not_bol = notbol;
+               pattern->regs_allocated = REGS_UNALLOCATED;
+               matched = re_search(pattern, line, line_len, 0, line_len, &search_regs) >= 0;
                if (matched)
                {
                        *sp = line + search_regs.start[0];
@@ -345,7 +325,7 @@ match_pattern(pattern, tpattern, line, line_len, sp, ep, notbol, search_type)
                rm.rm_so = 0;
                rm.rm_eo = line_len;
 #endif
-               matched = !regexec(spattern, line, 1, &rm, flags);
+               matched = !regexec(pattern, line, 1, &rm, flags);
                if (matched)
                {
 #ifndef __WATCOMC__
@@ -362,7 +342,7 @@ match_pattern(pattern, tpattern, line, line_len, sp, ep, notbol, search_type)
        {
                int flags = (notbol) ? PCRE_NOTBOL : 0;
                int ovector[3];
-               matched = pcre_exec(spattern, NULL, line, line_len,
+               matched = pcre_exec(pattern, NULL, line, line_len,
                        0, flags, ovector, 3) >= 0;
                if (matched)
                {
@@ -379,21 +359,21 @@ match_pattern(pattern, tpattern, line, line_len, sp, ep, notbol, search_type)
        *sp = *ep = NULL;
 #endif
 #if HAVE_REGCMP
-       *ep = regex(spattern, line);
+       *ep = regex(pattern, line);
        matched = (*ep != NULL);
        if (matched)
                *sp = __loc1;
 #endif
 #if HAVE_V8_REGCOMP
 #if HAVE_REGEXEC2
-       matched = regexec2(spattern, line, notbol);
+       matched = regexec2(pattern, line, notbol);
 #else
-       matched = regexec(spattern, line);
+       matched = regexec(pattern, line);
 #endif
        if (matched)
        {
-               *sp = spattern->startp[0];
-               *ep = spattern->endp[0];
+               *sp = pattern->startp[0];
+               *ep = pattern->endp[0];
        }
 #endif
        }
index 6703595..7bde5c7 100644 (file)
--- a/pattern.h
+++ b/pattern.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
 #if HAVE_GNU_REGEX
 #define __USE_GNU 1
 #include <regex.h>
-#define DEFINE_PATTERN(name)  struct re_pattern_buffer *name
+#define PATTERN_TYPE          struct re_pattern_buffer *
 #define CLEAR_PATTERN(name)   name = NULL
 #endif
 
 #if HAVE_POSIX_REGCOMP
 #include <regex.h>
 #ifdef REG_EXTENDED
-#define        REGCOMP_FLAG    REG_EXTENDED
+#define REGCOMP_FLAG    REG_EXTENDED
 #else
-#define        REGCOMP_FLAG    0
+#define REGCOMP_FLAG    0
 #endif
-#define DEFINE_PATTERN(name)  regex_t *name
+#define PATTERN_TYPE          regex_t *
 #define CLEAR_PATTERN(name)   name = NULL
 #endif
 
 #if HAVE_PCRE
 #include <pcre.h>
-#define DEFINE_PATTERN(name)  pcre *name
+#define PATTERN_TYPE          pcre *
 #define CLEAR_PATTERN(name)   name = NULL
 #endif
 
 #if HAVE_RE_COMP
-char *re_comp();
-int re_exec();
-#define DEFINE_PATTERN(name)  int name
+char *re_comp LESSPARAMS ((char*));
+int re_exec LESSPARAMS ((char*));
+#define PATTERN_TYPE          int
 #define CLEAR_PATTERN(name)   name = 0
 #endif
 
 #if HAVE_REGCMP
-char *regcmp();
-char *regex();
+char *regcmp LESSPARAMS ((char*));
+char *regex LESSPARAMS ((char**, char*));
 extern char *__loc1;
-#define DEFINE_PATTERN(name)  char *name
+#define PATTERN_TYPE          char **
 #define CLEAR_PATTERN(name)   name = NULL
 #endif
 
 #if HAVE_V8_REGCOMP
 #include "regexp.h"
 extern int reg_show_error;
-#define DEFINE_PATTERN(name)  struct regexp *name
+#define PATTERN_TYPE          struct regexp *
 #define CLEAR_PATTERN(name)   name = NULL
 #endif
 
 #if NO_REGEX
-#define DEFINE_PATTERN(name)  
+#define PATTERN_TYPE          void *
 #define CLEAR_PATTERN(name)   
 #endif
index 61493ec..e0d86e7 100644 (file)
--- a/pckeys.h
+++ b/pckeys.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
index 4f8e60f..ae3899c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -36,21 +36,22 @@ extern int sc_width, sc_height;
  *     the line after the bottom line on the screen
  */
        public POSITION
-position(where)
-       int where;
+position(sindex)
+       int sindex;
 {
-       switch (where)
+       switch (sindex)
        {
        case BOTTOM:
-               where = sc_height - 2;
+               sindex = sc_height - 2;
                break;
        case BOTTOM_PLUS_ONE:
-               where = sc_height - 1;
+               sindex = sc_height - 1;
                break;
        case MIDDLE:
-               where = (sc_height - 1) / 2;
+               sindex = (sc_height - 1) / 2;
+               break;
        }
-       return (table[where]);
+       return (table[sindex]);
 }
 
 /*
@@ -60,7 +61,7 @@ position(where)
 add_forw_pos(pos)
        POSITION pos;
 {
-       register int i;
+       int i;
 
        /*
         * Scroll the position table up.
@@ -77,7 +78,7 @@ add_forw_pos(pos)
 add_back_pos(pos)
        POSITION pos;
 {
-       register int i;
+       int i;
 
        /*
         * Scroll the position table down.
@@ -93,7 +94,7 @@ add_back_pos(pos)
        public void
 pos_clear()
 {
-       register int i;
+       int i;
 
        for (i = 0;  i < sc_height;  i++)
                table[i] = NULL_POSITION;
@@ -115,7 +116,7 @@ pos_init()
         */
        if (table != NULL)
        {
-               get_scrpos(&scrpos);
+               get_scrpos(&scrpos, TOP);
                free((char*)table);
        } else
                scrpos.pos = NULL_POSITION;
@@ -135,7 +136,7 @@ pos_init()
 onscreen(pos)
        POSITION pos;
 {
-       register int i;
+       int i;
 
        if (pos < table[0])
                return (-1);
@@ -159,7 +160,7 @@ empty_lines(s, e)
        int s;
        int e;
 {
-       register int i;
+       int i;
 
        for (i = s;  i <= e;  i++)
                if (table[i] != NULL_POSITION && table[i] != 0)
@@ -176,22 +177,34 @@ empty_lines(s, e)
  * the screen line to a number > 0.
  */
        public void
-get_scrpos(scrpos)
+get_scrpos(scrpos, where)
        struct scrpos *scrpos;
+       int where;
 {
-       register int i;
+       int i;
+       int dir;
+       int last;
+
+       switch (where)
+       {
+       case TOP: i = 0; dir = +1; last = sc_height-2; break;
+       default:  i = sc_height-2; dir = -1; last = 0; break;
+       }
 
        /*
         * Find the first line on the screen which has something on it,
         * and return the screen line number and the file position.
         */
-       for (i = 0; i < sc_height;  i++)
+       for (;; i += dir)
+       {
                if (table[i] != NULL_POSITION)
                {
                        scrpos->ln = i+1;
                        scrpos->pos = table[i];
                        return;
                }
+               if (i == last) break;
+       }
        /*
         * The screen is empty.
         */
@@ -208,7 +221,7 @@ get_scrpos(scrpos)
  * relative to the bottom of the screen.
  */
        public int
-adjsline(sline)
+sindex_from_sline(sline)
        int sline;
 {
        /*
@@ -218,12 +231,12 @@ adjsline(sline)
        if (sline < 0)
                sline += sc_height;
        /*
-        * Can't be less than 1 or greater than sc_height-1.
+        * Can't be less than 1 or greater than sc_height.
         */
        if (sline <= 0)
                sline = 1;
-       if (sline >= sc_height)
-               sline = sc_height - 1;
+       if (sline > sc_height)
+               sline = sc_height;
        /*
         * Return zero-based line number, not one-based.
         */
index a0b20c5..3067896 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
index bd2213c..3067d2b 100644 (file)
--- a/prompt.c
+++ b/prompt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -394,9 +394,9 @@ protochar(c, where, iseditproto)
  */
        static constant char *
 skipcond(p)
-       register constant char *p;
+       constant char *p;
 {
-       register int iflevel;
+       int iflevel;
 
        /*
         * We came in here after processing a ? or :,
@@ -464,7 +464,7 @@ wherechar(p, wp)
                case 'm':   *wp = MIDDLE;               break;
                case 'b':   *wp = BOTTOM;               break;
                case 'B':   *wp = BOTTOM_PLUS_ONE;      break;
-               case 'j':   *wp = adjsline(jump_sline); break;
+               case 'j':   *wp = sindex_from_sline(jump_sline); break;
                default:    *wp = TOP;  p--;            break;
                }
        }
@@ -479,8 +479,8 @@ pr_expand(proto, maxwidth)
        constant char *proto;
        int maxwidth;
 {
-       register constant char *p;
-       register int c;
+       constant char *p;
+       int c;
        int where;
 
        mp = message;
index ad3fca1..dfee5d2 100644 (file)
--- a/screen.c
+++ b/screen.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -126,16 +126,21 @@ static HANDLE con_out_save = INVALID_HANDLE_VALUE; /* previous console */
 static HANDLE con_out_ours = INVALID_HANDLE_VALUE; /* our own */
 HANDLE con_out = INVALID_HANDLE_VALUE;             /* current console */
 
+extern int utf_mode;
 extern int quitting;
 static void win32_init_term();
 static void win32_deinit_term();
 
+#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
+#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 4
+#endif
+
 #define FG_COLORS       (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY)
 #define BG_COLORS       (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY)
 #define        MAKEATTR(fg,bg)         ((WORD)((fg)|((bg)<<4)))
 #define        SETCOLORS(fg,bg)        { curr_attr = MAKEATTR(fg,bg); \
                                if (SetConsoleTextAttribute(con_out, curr_attr) == 0) \
-                               error("SETCOLORS failed"); }
+                               error("SETCOLORS failed", NULL_PARG); }
 #endif
 
 #if MSDOS_COMPILER
@@ -152,7 +157,9 @@ public int bl_bg_color;
 static int sy_fg_color;                /* Color of system text (before less) */
 static int sy_bg_color;
 public int sgr_mode;           /* Honor ANSI sequences rather than using above */
-
+#if MSDOS_COMPILER==WIN32C
+public int have_ul;            /* Is underline available? */
+#endif
 #else
 
 /*
@@ -201,9 +208,11 @@ public int above_mem, below_mem;   /* Memory retained above/below screen */
 public int can_goto_line;              /* Can move cursor to any line */
 public int clear_bg;           /* Clear fills with background color */
 public int missing_cap = 0;    /* Some capability is missing */
+public char *kent = NULL;      /* Keypad ENTER sequence */
 
 static int attrmode = AT_NORMAL;
 extern int binattr;
+extern int line_count;
 
 #if !MSDOS_COMPILER
 static char *cheaper();
@@ -233,6 +242,7 @@ extern int wscroll;
 extern int screen_trashed;
 extern int tty;
 extern int top_scroll;
+extern int quit_if_one_screen;
 extern int oldbot;
 #if HILITE_SEARCH
 extern int hilite_search;
@@ -694,7 +704,7 @@ ltgetstr(capname, pp)
        public void
 scrsize()
 {
-       register char *s;
+       char *s;
        int sys_height;
        int sys_width;
 #if !MSDOS_COMPILER
@@ -1119,7 +1129,7 @@ get_term()
 #else /* !MSDOS_COMPILER */
 
        char *sp;
-       register char *t1, *t2;
+       char *t1, *t2;
        char *term;
        char termbuf[TERMBUF_SIZE];
 
@@ -1208,7 +1218,8 @@ get_term()
        sc_e_keypad = ltgetstr("ke", &sp);
        if (sc_e_keypad == NULL)
                sc_e_keypad = "";
-               
+       kent = ltgetstr("@8", &sp);
+
        sc_init = ltgetstr("ti", &sp);
        if (sc_init == NULL)
                sc_init = "";
@@ -1496,6 +1507,8 @@ win32_init_term()
 
        if (con_out_ours == INVALID_HANDLE_VALUE)
        {
+               DWORD output_mode;
+
                /*
                 * Create our own screen buffer, so that we
                 * may restore the original when done.
@@ -1506,6 +1519,12 @@ win32_init_term()
                        (LPSECURITY_ATTRIBUTES) NULL,
                        CONSOLE_TEXTMODE_BUFFER,
                        (LPVOID) NULL);
+               /*
+                * Enable underline, if available.
+                */
+               GetConsoleMode(con_out_ours, &output_mode);
+               have_ul = SetConsoleMode(con_out_ours,
+                           output_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
        }
 
        size.X = scr.srWindow.Right - scr.srWindow.Left + 1;
@@ -1538,7 +1557,9 @@ win32_deinit_term()
 init()
 {
 #if !MSDOS_COMPILER
-       if (!no_init)
+       if (quit_if_one_screen && line_count >= sc_height)
+               quit_if_one_screen = FALSE;
+       if (!no_init && !quit_if_one_screen)
                tputs(sc_init, sc_height, putchr);
        if (!no_keypad)
                tputs(sc_s_keypad, sc_height, putchr);
@@ -1578,7 +1599,7 @@ deinit()
 #if !MSDOS_COMPILER
        if (!no_keypad)
                tputs(sc_e_keypad, sc_height, putchr);
-       if (!no_init)
+       if (!no_init && !quit_if_one_screen)
                tputs(sc_deinit, sc_height, putchr);
 #else
        /* Restore system colors. */
@@ -1824,6 +1845,8 @@ win32_scroll_up(n)
        public void
 lower_left()
 {
+       if (!init_done)
+               return;
 #if !MSDOS_COMPILER
        tputs(sc_lower_left, 1, putchr);
 #else
@@ -1898,14 +1921,14 @@ check_winch()
  * Goto a specific line on the screen.
  */
        public void
-goto_line(slinenum)
-       int slinenum;
+goto_line(sindex)
+       int sindex;
 {
 #if !MSDOS_COMPILER
-       tputs(tgoto(sc_move, 0, slinenum), 1, putchr);
+       tputs(tgoto(sc_move, 0, sindex), 1, putchr);
 #else
        flush();
-       _settextposition(slinenum+1, 1);
+       _settextposition(sindex+1, 1);
 #endif
 }
 
@@ -1946,7 +1969,7 @@ create_flash()
        }
 #else
 #if MSDOS_COMPILER==BORLANDC
-       register int n;
+       int n;
 
        whitescreen = (unsigned short *) 
                malloc(sc_width * sc_height * sizeof(short));
@@ -1956,7 +1979,7 @@ create_flash()
                whitescreen[n] = 0x7020;
 #else
 #if MSDOS_COMPILER==WIN32C
-       register int n;
+       int n;
 
        whitescreen = (WORD *)
                malloc(sc_height * sc_width * sizeof(WORD));
@@ -2504,7 +2527,18 @@ WIN32textout(text, len)
 {
 #if MSDOS_COMPILER==WIN32C
        DWORD written;
-       WriteConsole(con_out, text, len, &written, NULL);
+       if (utf_mode == 2)
+       {
+               /*
+                * We've got UTF-8 text in a non-UTF-8 console.  Convert it to
+                * wide and use WriteConsoleW.
+                */
+               WCHAR wtext[1024];
+               len = MultiByteToWideChar(CP_UTF8, 0, text, len, wtext,
+                                         sizeof(wtext)/sizeof(*wtext));
+               WriteConsoleW(con_out, wtext, len, &written, NULL);
+       } else
+               WriteConsole(con_out, text, len, &written, NULL);
 #else
        char c = text[len];
        text[len] = '\0';
index c928eba..001c55a 100644 (file)
--- a/scrsize.c
+++ b/scrsize.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
index 750b74a..7219188 100644 (file)
--- a/search.c
+++ b/search.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -13,7 +13,6 @@
  */
 
 #include "less.h"
-#include "pattern.h"
 #include "position.h"
 #include "charset.h"
 
@@ -29,7 +28,7 @@ extern int jump_sline;
 extern int bs_mode;
 extern int ctldisp;
 extern int status_col;
-extern void * constant ml_search;
+extern void *ml_search;
 extern POSITION start_attnpos;
 extern POSITION end_attnpos;
 extern int utf_mode;
@@ -103,7 +102,7 @@ static struct hilite_tree filter_anchor = HILITE_INITIALIZER();
  * search pattern and filter pattern.
  */
 struct pattern_info {
-       DEFINE_PATTERN(compiled);
+       PATTERN_TYPE compiled;
        char* text;
        int search_type;
 };
@@ -259,7 +258,7 @@ prev_pattern(info)
 repaint_hilite(on)
        int on;
 {
-       int slinenum;
+       int sindex;
        POSITION pos;
        int save_hide_hilite;
 
@@ -281,13 +280,13 @@ repaint_hilite(on)
                return;
        }
 
-       for (slinenum = TOP;  slinenum < TOP + sc_height-1;  slinenum++)
+       for (sindex = TOP;  sindex < TOP + sc_height-1;  sindex++)
        {
-               pos = position(slinenum);
+               pos = position(sindex);
                if (pos == NULL_POSITION)
                        continue;
                (void) forw_line(pos);
-               goto_line(slinenum);
+               goto_line(sindex);
                put_line();
        }
        lower_left();
@@ -300,7 +299,7 @@ repaint_hilite(on)
        public void
 clear_attn()
 {
-       int slinenum;
+       int sindex;
        POSITION old_start_attnpos;
        POSITION old_end_attnpos;
        POSITION pos;
@@ -321,17 +320,17 @@ clear_attn()
        if (squished)
                repaint();
 
-       for (slinenum = TOP;  slinenum < TOP + sc_height-1;  slinenum++)
+       for (sindex = TOP;  sindex < TOP + sc_height-1;  sindex++)
        {
-               pos = position(slinenum);
+               pos = position(sindex);
                if (pos == NULL_POSITION)
                        continue;
-               epos = position(slinenum+1);
-               if (pos < old_end_attnpos &&
+               epos = position(sindex+1);
+               if (pos <= old_end_attnpos &&
                     (epos == NULL_POSITION || epos > old_start_attnpos))
                {
                        (void) forw_line(pos);
-                       goto_line(slinenum);
+                       goto_line(sindex);
                        put_line();
                        moved = 1;
                }
@@ -349,9 +348,14 @@ undo_search()
 {
        if (!prev_pattern(&search_info))
        {
-               error("No previous regular expression", NULL_PARG);
-               return;
+               if (hilite_anchor.first == NULL)
+               {
+                       error("No previous regular expression", NULL_PARG);
+                       return;
+               }
+               clr_hilite(); /* Next time, hilite_anchor.first will be NULL. */
        }
+       clear_pattern(&search_info);
 #if HILITE_SEARCH
        hide_hilite = !hide_hilite;
        repaint_hilite(1);
@@ -621,11 +625,18 @@ is_hilited(pos, epos, nohide, p_matches)
        if (!match)
                return (0);
 
-       if (p_matches != NULL)
+       if (p_matches == NULL)
                /*
-                * Report matches, even if we're hiding highlights.
+                * Kinda kludgy way to recognize that caller is checking for
+                * hilite in status column. In this case we want to return
+                * hilite status even if hiliting is disabled or hidden.
                 */
-               *p_matches = 1;
+               return (1);
+
+       /*
+        * Report matches, even if we're hiding highlights.
+        */
+       *p_matches = 1;
 
        if (hilite_search == 0)
                /*
@@ -1024,7 +1035,7 @@ hilite_screen()
 {
        struct scrpos scrpos;
 
-       get_scrpos(&scrpos);
+       get_scrpos(&scrpos, TOP);
        if (scrpos.pos == NULL_POSITION)
                return;
        prep_hilite(scrpos.pos, position(BOTTOM_PLUS_ONE), -1);
@@ -1059,7 +1070,7 @@ search_pos(search_type)
        int search_type;
 {
        POSITION pos;
-       int linenum;
+       int sindex;
 
        if (empty_screen())
        {
@@ -1082,7 +1093,7 @@ search_pos(search_type)
                                pos = ch_length();
                        }
                }
-               linenum = 0;
+               sindex = 0;
        } else 
        {
                int add_one = 0;
@@ -1093,18 +1104,18 @@ search_pos(search_type)
                         * Search does not include current screen.
                         */
                        if (search_type & SRCH_FORW)
-                               linenum = sc_height-1; /* BOTTOM_PLUS_ONE */
+                               sindex = sc_height-1; /* BOTTOM_PLUS_ONE */
                        else
-                               linenum = 0; /* TOP */
+                               sindex = 0; /* TOP */
                } else if (how_search == OPT_ONPLUS && !(search_type & SRCH_AFTER_TARGET))
                {
                        /*
                         * Search includes all of displayed screen.
                         */
                        if (search_type & SRCH_FORW)
-                               linenum = 0; /* TOP */
+                               sindex = 0; /* TOP */
                        else
-                               linenum = sc_height-1; /* BOTTOM_PLUS_ONE */
+                               sindex = sc_height-1; /* BOTTOM_PLUS_ONE */
                } else 
                {
                        /*
@@ -1112,11 +1123,11 @@ search_pos(search_type)
                         * It starts at the jump target (if searching backwards),
                         * or at the jump target plus one (if forwards).
                         */
-                       linenum = adjsline(jump_sline);
+                       sindex = sindex_from_sline(jump_sline);
                        if (search_type & SRCH_FORW) 
                                add_one = 1;
                }
-               pos = position(linenum);
+               pos = position(sindex);
                if (add_one)
                        pos = forw_raw_line(pos, (char **)NULL, (int *)NULL);
        }
@@ -1128,17 +1139,17 @@ search_pos(search_type)
        {
                while (pos == NULL_POSITION)
                {
-                       if (++linenum >= sc_height)
+                       if (++sindex >= sc_height)
                                break;
-                       pos = position(linenum);
+                       pos = position(sindex);
                }
        } else 
        {
                while (pos == NULL_POSITION)
                {
-                       if (--linenum < 0)
+                       if (--sindex < 0)
                                break;
-                       pos = position(linenum);
+                       pos = position(sindex);
                }
        }
        return (pos);
@@ -1271,6 +1282,8 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
                                hl.hl_startpos = linepos;
                                hl.hl_endpos = pos;
                                add_hilite(&filter_anchor, &hl);
+                               free(cline);
+                               free(chpos);
                                continue;
                        }
                }
@@ -1418,7 +1431,7 @@ search(search_type, pattern, n)
                        return -1;
                }
 #if HILITE_SEARCH
-               if (hilite_search == OPT_ON)
+               if (hilite_search == OPT_ON || status_col)
                {
                        /*
                         * Erase the highlights currently on screen.
@@ -1445,7 +1458,7 @@ search(search_type, pattern, n)
                if (set_pattern(&search_info, pattern, search_type) < 0)
                        return (-1);
 #if HILITE_SEARCH
-               if (hilite_search)
+               if (hilite_search || status_col)
                {
                        /*
                         * Erase the highlights currently on screen.
@@ -1455,7 +1468,7 @@ search(search_type, pattern, n)
                        hide_hilite = 0;
                        clr_hilite();
                }
-               if (hilite_search == OPT_ONPLUS)
+               if (hilite_search == OPT_ONPLUS || status_col)
                {
                        /*
                         * Highlight any matches currently on screen,
@@ -1477,7 +1490,8 @@ search(search_type, pattern, n)
                 */
                if (search_type & SRCH_PAST_EOF)
                        return (n);
-               /* repaint(); -- why was this here? */
+               if (hilite_search == OPT_ON || status_col)
+                       repaint_hilite(1);
                error("Nothing to search", NULL_PARG);
                return (-1);
        }
@@ -1490,7 +1504,7 @@ search(search_type, pattern, n)
                 * Search was unsuccessful.
                 */
 #if HILITE_SEARCH
-               if (hilite_search == OPT_ON && n > 0)
+               if ((hilite_search == OPT_ON || status_col) && n > 0)
                        /*
                         * Redisplay old hilites.
                         */
@@ -1508,7 +1522,7 @@ search(search_type, pattern, n)
        }
 
 #if HILITE_SEARCH
-       if (hilite_search == OPT_ON)
+       if (hilite_search == OPT_ON || status_col)
                /*
                 * Display new hilites in the matching line.
                 */
index 24f78f1..f53b2f9 100644 (file)
--- a/signal.c
+++ b/signal.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -78,22 +78,16 @@ stop(type)
 }
 #endif
 
+#undef SIG_LESSWINDOW
 #ifdef SIGWINCH
-/*
- * "Window" change handler
- */
-       /* ARGSUSED*/
-       public RETSIGTYPE
-winch(type)
-       int type;
-{
-       LSIGNAL(SIGWINCH, winch);
-       sigs |= S_WINCH;
-       if (reading)
-               intread();
-}
+#define SIG_LESSWINDOW SIGWINCH
 #else
 #ifdef SIGWIND
+#define SIG_LESSWINDOW SIGWIND
+#endif
+#endif
+
+#ifdef SIG_LESSWINDOW
 /*
  * "Window" change handler
  */
@@ -102,13 +96,12 @@ winch(type)
 winch(type)
        int type;
 {
-       LSIGNAL(SIGWIND, winch);
+       LSIGNAL(SIG_LESSWINDOW, winch);
        sigs |= S_WINCH;
        if (reading)
                intread();
 }
 #endif
-#endif
 
 #if MSDOS_COMPILER==WIN32C
 /*
@@ -133,6 +126,13 @@ wbreak_handler(dwCtrlType)
 }
 #endif
 
+       static RETSIGTYPE
+terminate(type)
+       int type;
+{
+       quit(15);
+}
+
 /*
  * Set up the signal handlers.
  */
@@ -161,6 +161,9 @@ init_signals(on)
 #ifdef SIGQUIT
                (void) LSIGNAL(SIGQUIT, SIG_IGN);
 #endif
+#ifdef SIGTERM
+               (void) LSIGNAL(SIGTERM, terminate);
+#endif
        } else
        {
                /*
@@ -182,6 +185,9 @@ init_signals(on)
 #ifdef SIGQUIT
                (void) LSIGNAL(SIGQUIT, SIG_DFL);
 #endif
+#ifdef SIGTERM
+               (void) LSIGNAL(SIGTERM, SIG_DFL);
+#endif
        }
 }
 
@@ -192,7 +198,7 @@ init_signals(on)
        public void
 psignals()
 {
-       register int tsignals;
+       int tsignals;
 
        if ((tsignals = sigs) == 0)
                return;
diff --git a/tags.c b/tags.c
index 0566be7..ebb3048 100644 (file)
--- a/tags.c
+++ b/tags.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -22,6 +22,7 @@ static int curseq;
 
 extern int linenums;
 extern int sigs;
+extern int ctldisp;
 
 enum tag_result {
        TAG_FOUND,
@@ -63,8 +64,6 @@ struct taglist {
        struct tag *tl_first;
        struct tag *tl_last;
 };
-#define TAG_END  ((struct tag *) &taglist)
-static struct taglist taglist = { TAG_END, TAG_END };
 struct tag {
        struct tag *next, *prev; /* List links */
        char *tag_file;         /* Source file containing the tag */
@@ -72,6 +71,8 @@ struct tag {
        char *tag_pattern;      /* Pattern used to find the tag */
        char tag_endline;       /* True if the pattern includes '$' */
 };
+#define TAG_END  ((struct tag *) &taglist)
+static struct taglist taglist = { TAG_END, TAG_END };
 static struct tag *curtag;
 
 #define TAG_INS(tp) \
@@ -90,7 +91,7 @@ static struct tag *curtag;
        public void
 cleantags()
 {
-       register struct tag *tp;
+       struct tag *tp;
 
        /*
         * Delete any existing tag list.
@@ -100,6 +101,8 @@ cleantags()
        while ((tp = taglist.tl_first) != TAG_END)
        {
                TAG_RM(tp);
+               free(tp->tag_file);
+               free(tp->tag_pattern);
                free(tp);
        }
        curtag = NULL;
@@ -117,7 +120,7 @@ maketagent(name, file, linenum, pattern, endline)
        char *pattern;
        int endline;
 {
-       register struct tag *tp;
+       struct tag *tp;
 
        tp = (struct tag *) ecalloc(sizeof(struct tag), 1);
        tp->tag_file = (char *) ecalloc(strlen(file) + 1, sizeof(char));
@@ -170,7 +173,7 @@ gettagtype()
  */
        public void
 findtag(tag)
-       register char *tag;
+       char *tag;
 {
        int type = gettagtype();
        enum tag_result result;
@@ -266,11 +269,11 @@ curr_tag()
  */
        static enum tag_result
 findctag(tag)
-       register char *tag;
+       char *tag;
 {
        char *p;
-       register FILE *f;
-       register int taglen;
+       FILE *f;
+       int taglen;
        LINENUM taglinenum;
        char *tagfile;
        char *tagpattern;
@@ -384,6 +387,26 @@ edit_tagfile()
        return (edit(curtag->tag_file));
 }
 
+       static int
+curtag_match(char const *line, POSITION linepos)
+{
+       /*
+        * Test the line to see if we have a match.
+        * Use strncmp because the pattern may be
+        * truncated (in the tags file) if it is too long.
+        * If tagendline is set, make sure we match all
+        * the way to end of line (no extra chars after the match).
+        */
+       int len = (int) strlen(curtag->tag_pattern);
+       if (strncmp(curtag->tag_pattern, line, len) == 0 &&
+           (!curtag->tag_endline || line[len] == '\0' || line[len] == '\r'))
+       {
+               curtag->tag_linenum = find_linenum(linepos);
+               return 1;
+       }
+       return 0;
+}
+
 /*
  * Search for a tag.
  * This is a stripped-down version of search().
@@ -398,13 +421,14 @@ ctagsearch()
 {
        POSITION pos, linepos;
        LINENUM linenum;
-       int len;
+       int line_len;
        char *line;
+       int found;
 
        pos = ch_zero();
        linenum = find_linenum(pos);
 
-       for (;;)
+       for (found = 0; !found;)
        {
                /*
                 * Get lines until we find a matching one or 
@@ -418,7 +442,7 @@ ctagsearch()
                 * starting position of that line in linepos.
                 */
                linepos = pos;
-               pos = forw_raw_line(pos, &line, (int *)NULL);
+               pos = forw_raw_line(pos, &line, &line_len);
                if (linenum != 0)
                        linenum++;
 
@@ -439,19 +463,21 @@ ctagsearch()
                if (linenums)
                        add_lnum(linenum, pos);
 
-               /*
-                * Test the line to see if we have a match.
-                * Use strncmp because the pattern may be
-                * truncated (in the tags file) if it is too long.
-                * If tagendline is set, make sure we match all
-                * the way to end of line (no extra chars after the match).
-                */
-               len = (int) strlen(curtag->tag_pattern);
-               if (strncmp(curtag->tag_pattern, line, len) == 0 &&
-                   (!curtag->tag_endline || line[len] == '\0' || line[len] == '\r'))
+               if (ctldisp != OPT_ONPLUS)
                {
-                       curtag->tag_linenum = find_linenum(linepos);
-                       break;
+                       if (curtag_match(line, linepos))
+                               found = 1;
+               } else
+               {
+                       int cvt_ops = CVT_ANSI;
+                       int cvt_len = cvt_length(line_len, cvt_ops);
+                       int *chpos = cvt_alloc_chpos(cvt_len);
+                       char *cline = (char *) ecalloc(1, cvt_len);
+                       cvt_text(cline, line, chpos, &line_len, cvt_ops);
+                       if (curtag_match(cline, linepos))
+                               found = 1;
+                       free(chpos);
+                       free(cline);
                }
        }
 
diff --git a/ttyin.c b/ttyin.c
index 58892e1..87cffc2 100644 (file)
--- a/ttyin.c
+++ b/ttyin.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -120,7 +120,11 @@ getchr()
                if (c == '\003')
                        return (READ_INTR);
 #else
-               result = iread(tty, &c, sizeof(char));
+               {
+                       unsigned char uc;
+                       result = iread(tty, &uc, sizeof(char));
+                       c = (char) uc;
+               }
                if (result == READ_INTR)
                        return (READ_INTR);
                if (result < 0)
index 17c4590..888fe75 100644 (file)
--- a/ubin.uni
+++ b/ubin.uni
@@ -1,32 +1,16 @@
-/* Generated by "./mkutable -f2 Cc Cf Cs Co Zl Zp -- unicode/UnicodeData.txt" on Tue Sep 20 10:51:43 PDT 2016 */
-       { 0x0000, 0x001f }, /* Cc */
+/* Generated by "./mkutable -f2 Cc Cs Co Zl Zp -- unicode/UnicodeData.txt" on Tue Jul 25 09:04:35 PDT 2017 */
+       { 0x0000, 0x0007 }, /* Cc */
+       { 0x000b, 0x000b }, /* Cc */
+       { 0x000e, 0x001f }, /* Cc */
        { 0x007f, 0x009f }, /* Cc */
-       { 0x00ad, 0x00ad }, /* Cf */
-       { 0x0600, 0x0605 }, /* Cf */
-       { 0x061c, 0x061c }, /* Cf */
-       { 0x06dd, 0x06dd }, /* Cf */
-       { 0x070f, 0x070f }, /* Cf */
-       { 0x08e2, 0x08e2 }, /* Cf */
-       { 0x180e, 0x180e }, /* Cf */
-       { 0x200b, 0x200f }, /* Cf */
        { 0x2028, 0x2028 }, /* Zl */
        { 0x2029, 0x2029 }, /* Zp */
-       { 0x202a, 0x202e }, /* Cf */
-       { 0x2060, 0x2064 }, /* Cf */
-       { 0x2066, 0x206f }, /* Cf */
        { 0xd800, 0xd800 }, /* Cs */
        { 0xdb7f, 0xdb80 }, /* Cs */
        { 0xdbff, 0xdc00 }, /* Cs */
        { 0xdfff, 0xdfff }, /* Cs */
        { 0xe000, 0xe000 }, /* Co */
        { 0xf8ff, 0xf8ff }, /* Co */
-       { 0xfeff, 0xfeff }, /* Cf */
-       { 0xfff9, 0xfffb }, /* Cf */
-       { 0x110bd, 0x110bd }, /* Cf */
-       { 0x1bca0, 0x1bca3 }, /* Cf */
-       { 0x1d173, 0x1d17a }, /* Cf */
-       { 0xe0001, 0xe0001 }, /* Cf */
-       { 0xe0020, 0xe007f }, /* Cf */
        { 0xf0000, 0xf0000 }, /* Co */
        { 0xffffd, 0xffffd }, /* Co */
        { 0x100000, 0x100000 }, /* Co */
index dde1af0..1432b37 100644 (file)
--- a/version.c
+++ b/version.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1984-2016  Mark Nudelman
+ * Copyright (C) 1984-2017  Mark Nudelman
  *
  * You may distribute under the terms of either the GNU General Public
  * License or the Less License, as specified in the README file.
@@ -800,11 +800,59 @@ v484  9/20/16   Update to Unicode 9.0.0 database.
 v485  10/21/16  Fix "nothing to search" bug when top/bottom line is empty;
                 Display line numbers in bold. (thanks to Jason Hood);
                 Fix incorrect display when entering double-width chars in 
-               search string.
+                search string.
 v486  10/22/16  New commands ESC-{ and ESC-} to shift to start/end of 
                 displayed lines; new option -Da in Windows version to 
-               enable SGR mode (thanks to Jason Hood).
+                enable SGR mode (thanks to Jason Hood).
 v487  10/23/16  configure --help formatting.
+-----------------------------------------------------------------
+v488  2/23/17   Fix memory leaks in search (thanks to John Brooks).
+v489  3/30/17   Make -F not do init/deinit if file fits on one screen
+                (thanks to Jindrich Novy).
+v490  4/5/17    Switch to ANSI prototypes in funcs.h; remove "register".
+v491  4/7/17    Fix signed char bug.
+v492  4/21/17   Handle SIGTERM.
+v493  6/22/17   Fix bug initializing charset in MSDOS build.
+v494  6/26/17   Update Unicode tables; make Cf chars composing not binary.
+v495  7/3/17    Improve binary file detection (thanks to Bela Lubkin);
+                do -R filter when matching tags (thanks to Matthew Malcomson).
+v496  7/5/17    Add LESSRSCROLL marker.
+v497  7/5/17    Sync.
+v498  7/7/17    Fix early truncation of text if last char is double-width.
+v499  7/10/17   Misc fixes.
+v500  7/11/17   Fix bug where certain env variables couldn't be set in lesskey.
+v501  7/12/17   Make sure rscroll char is standout by default.
+v502  7/13/17   Control rscroll char via command line option not env variable.
+v503  7/13/17   Switch to git.
+v504  7/13/17   Call opt_rscroll at startup; change mkhelp.c to mkhelp.pl.
+v505  7/17/17   Add M and ESC-M commands; 
+                fix buffer handling with stdin and LESSOPEN.
+v506  7/17/17   On Windows, convert UTF-8 to multibyte if console is not UTF-8;
+                handle extended chars on input (thanks to Jason Hood).
+v507  7/18/17   Fix some bugs handling filenames containing shell metachars.
+v508  7/19/17   Fix bugs when using LESSOPEN to read stdin.
+v509  7/19/17   Fix another stdin bug.
+v510  7/20/17   Fix bug in determining when to reopen a file.
+v511  7/25/17   Fix bugs in recent MSDOS changes (thanks to Jason Hood).
+v512  7/26/17   Fix MSDOS build.
+v513  7/26/17   Fix switch to normal attr at end of line with -R and rscroll.
+v514  7/27/17   Fix bug in fcomplete when pattern does not match a file.
+v515  7/28/17   Allow 'u' in -D option on Windows.
+v516  7/29/17   Fix bug using LESSOPEN with filename containing metachars.
+v517  7/30/17   Status column shows matches even if hiliting is disabled via -G.
+v518  8/1/17    Use underline in sgr mode in MSDOS (thanks to Jason Hood).
+v519  8/10/17   Fix rscroll bug when last char of line starts coloration.
+v520  9/3/17    Fix compiler warning.
+v521  10/20/17  Fix binary file warning in UTF-8 files with SGI sequences.
+v522  10/20/17  Handle keypad ENTER key properly.
+v523  10/23/17  Cleanup.
+v524  10/24/17  Fix getcc bug.
+v525  10/24/17  Change M command to mark last displayed line.
+v526  10/25/17  Fix search hilite bug introduced in v517.
+v527  10/30/17  Fix search hilite bug on last page with -a.
+v528  11/3/17   Make second ESC-u clear status column.
+v529  11/12/17  Display Unicode formatting chars in hex if -U is set.
+v530  12/2/17   Minor doc change and add missing VOID_PARAM.
 */
 
-char version[] = "487";
+char version[] = "530";
index 17c3859..801a352 100644 (file)
--- a/wide.uni
+++ b/wide.uni
@@ -1,4 +1,4 @@
-/* Generated by "./mkutable -f1 W F -- unicode/EastAsianWidth.txt" on Tue Sep 20 10:51:43 PDT 2016 */
+/* Generated by "./mkutable -f1 W F -- unicode/EastAsianWidth.txt" on Tue Jul 25 09:04:35 PDT 2017 */
        { 0x1100, 0x115f }, /* W */
        { 0x231a, 0x231b }, /* W */
        { 0x2329, 0x232a }, /* W */
@@ -42,7 +42,7 @@
        { 0x3001, 0x303e }, /* W */
        { 0x3041, 0x3096 }, /* W */
        { 0x3099, 0x30ff }, /* W */
-       { 0x3105, 0x312d }, /* W */
+       { 0x3105, 0x312e }, /* W */
        { 0x3131, 0x318e }, /* W */
        { 0x3190, 0x31ba }, /* W */
        { 0x31c0, 0x31e3 }, /* W */
        { 0xfe68, 0xfe6b }, /* W */
        { 0xff01, 0xff60 }, /* F */
        { 0xffe0, 0xffe6 }, /* F */
-       { 0x16fe0, 0x16fe0 }, /* W */
+       { 0x16fe0, 0x16fe1 }, /* W */
        { 0x17000, 0x187ec }, /* W */
        { 0x18800, 0x18af2 }, /* W */
-       { 0x1b000, 0x1b001 }, /* W */
+       { 0x1b000, 0x1b11e }, /* W */
+       { 0x1b170, 0x1b2fb }, /* W */
        { 0x1f004, 0x1f004 }, /* W */
        { 0x1f0cf, 0x1f0cf }, /* W */
        { 0x1f18e, 0x1f18e }, /* W */
@@ -73,6 +74,7 @@
        { 0x1f210, 0x1f23b }, /* W */
        { 0x1f240, 0x1f248 }, /* W */
        { 0x1f250, 0x1f251 }, /* W */
+       { 0x1f260, 0x1f265 }, /* W */
        { 0x1f300, 0x1f320 }, /* W */
        { 0x1f32d, 0x1f335 }, /* W */
        { 0x1f337, 0x1f37c }, /* W */
        { 0x1f6cc, 0x1f6cc }, /* W */
        { 0x1f6d0, 0x1f6d2 }, /* W */
        { 0x1f6eb, 0x1f6ec }, /* W */
-       { 0x1f6f4, 0x1f6f6 }, /* W */
-       { 0x1f910, 0x1f91e }, /* W */
-       { 0x1f920, 0x1f927 }, /* W */
-       { 0x1f930, 0x1f930 }, /* W */
-       { 0x1f933, 0x1f93e }, /* W */
-       { 0x1f940, 0x1f94b }, /* W */
-       { 0x1f950, 0x1f95e }, /* W */
-       { 0x1f980, 0x1f991 }, /* W */
+       { 0x1f6f4, 0x1f6f8 }, /* W */
+       { 0x1f910, 0x1f93e }, /* W */
+       { 0x1f940, 0x1f94c }, /* W */
+       { 0x1f950, 0x1f96b }, /* W */
+       { 0x1f980, 0x1f997 }, /* W */
        { 0x1f9c0, 0x1f9c0 }, /* W */
+       { 0x1f9d0, 0x1f9e6 }, /* W */
        { 0x20000, 0x2fffd }, /* W */
        { 0x30000, 0x3fffd }, /* W */