Merge from vendor branch LESS:
authorPeter Avalos <pavalos@dragonflybsd.org>
Fri, 16 Nov 2007 22:31:48 +0000 (22:31 +0000)
committerPeter Avalos <pavalos@dragonflybsd.org>
Fri, 16 Nov 2007 22:31:48 +0000 (22:31 +0000)
Import less-415:

Fix case-insensitive searching with non-ASCII text.

Use symbolic SEEK constants.

Fix search highlight bug with non-ASCII text.

Fix display bug with no-wrap terminals.

New --follow-name option makes F command follow the name of a file
rather than the file descriptor if an open file is renamed.

19 files changed:
contrib/less-4/LICENSE
contrib/less-4/NEWS
contrib/less-4/ch.c
contrib/less-4/command.c
contrib/less-4/decode.c
contrib/less-4/edit.c
contrib/less-4/filename.c
contrib/less-4/funcs.h
contrib/less-4/less.h
contrib/less-4/less.nro
contrib/less-4/lessecho.nro
contrib/less-4/lesskey.nro
contrib/less-4/line.c
contrib/less-4/optfunc.c
contrib/less-4/opttbl.c
contrib/less-4/screen.c
contrib/less-4/search.c
contrib/less-4/tags.c
contrib/less-4/version.c

index 7e4887b..8112859 100755 (executable)
@@ -2,7 +2,7 @@
                           ------------
 
 Less
-Copyright (C) 1984-2005  Mark Nudelman
+Copyright (C) 1984-2007  Mark Nudelman
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
index 0154225..3d6b098 100644 (file)
 ======================================================================
 
 
+       Major changes between "less" versions 409 and 415
+
+* New --follow-name option makes F command follow the name of a file
+  rather than the file descriptor if an open file is renamed.
+
+* Make searching with -i/-I work correctly with non-ASCII text.
+
+* Fix DJGPP build.
+
+======================================================================
+
        Major changes between "less" versions 406 and 409
 
 * Support CSI escape sequences, like SGR escape sequences.
 
 
 
+
index 2ac14d7..eb607d5 100755 (executable)
 #include <windows.h>
 #endif
 
+#if HAVE_STAT_INO
+#include <sys/stat.h>
+extern dev_t curr_dev;
+extern ino_t curr_ino;
+#endif
+
 typedef POSITION BLOCKNUM;
 
 public int ignore_eoi;
@@ -98,6 +104,8 @@ static int maxbufs = -1;
 extern int autobuf;
 extern int sigs;
 extern int secure;
+extern int screen_trashed;
+extern int follow_mode;
 extern constant char helpdata[];
 extern constant int size_helpdata;
 extern IFILE curr_ifile;
@@ -195,7 +203,7 @@ fch_get()
                 */
                if (!(ch_flags & CH_CANSEEK))
                        return ('?');
-               if (lseek(ch_file, (off_t)pos, 0) == BAD_LSEEK)
+               if (lseek(ch_file, (off_t)pos, SEEK_SET) == BAD_LSEEK)
                {
                        error("seek error", NULL_PARG);
                        clear_eol();
@@ -276,6 +284,25 @@ fch_get()
 #endif
 #endif
                        slept = TRUE;
+
+#if HAVE_STAT_INO
+                       if (follow_mode == FOLLOW_NAME)
+                       {
+                               /* See whether the file's i-number has changed.
+                                * If so, force the file to be closed and
+                                * reopened. */
+                               struct stat st;
+                               int r = stat(get_filename(curr_ifile), &st);
+                               if (r == 0 && (st.st_ino != curr_ino ||
+                                       st.st_dev != curr_dev))
+                               {
+                                       /* screen_trashed=2 causes
+                                        * make_display to reopen the file. */
+                                       screen_trashed = 2;
+                                       return (EOI);
+                               }
+                       }
+#endif
                }
                if (sigs)
                        return (EOI);
@@ -648,7 +675,7 @@ ch_flush()
        }
 #endif
 
-       if (lseek(ch_file, (off_t)0, 0) == BAD_LSEEK)
+       if (lseek(ch_file, (off_t)0, SEEK_SET) == BAD_LSEEK)
        {
                /*
                 * Warning only; even if the seek fails for some reason,
@@ -711,7 +738,7 @@ ch_delbufs()
        while (ch_bufhead != END_OF_CHAIN)
        {
                bp = ch_bufhead;
-               bp->next->prev = bp->prev;;
+               bp->next->prev = bp->prev;
                bp->prev->next = bp->next;
                free(bp);
        }
@@ -737,7 +764,7 @@ seekable(f)
                return (0);
        }
 #endif
-       return (lseek(f, (off_t)1, 0) != BAD_LSEEK);
+       return (lseek(f, (off_t)1, SEEK_SET) != BAD_LSEEK);
 }
 
 /*
index ff48909..ef6dfa4 100755 (executable)
@@ -551,6 +551,21 @@ mca_char(c)
        return (MCA_MORE);
 }
 
+/*
+ * Discard any buffered file data.
+ */
+       static void
+clear_buffers()
+{
+       if (!(ch_getflags() & CH_CANSEEK))
+               return;
+       ch_flush();
+       clr_linenum();
+#if HILITE_SEARCH
+       clr_hilite();
+#endif
+}
+
 /*
  * Make sure the screen is displayed.
  */
@@ -574,11 +589,20 @@ make_display()
                        jump_loc(initial_scrpos.pos, initial_scrpos.ln);
        } else if (screen_trashed)
        {
-               int save_top_scroll;
-               save_top_scroll = top_scroll;
+               int save_top_scroll = top_scroll;
+               int save_ignore_eoi = ignore_eoi;
                top_scroll = 1;
+               ignore_eoi = 0;
+               if (screen_trashed == 2)
+               {
+                       /* Special case used by ignore_eoi: re-open the input file
+                        * and jump to the end of the file. */
+                       reopen_curr_ifile();
+                       jump_forw();
+               }
                repaint();
                top_scroll = save_top_scroll;
+               ignore_eoi = save_ignore_eoi;
        }
 }
 
@@ -1109,7 +1133,10 @@ commands()
                        ignore_eoi = 1;
                        hit_eof = 0;
                        while (!sigs)
+                       {
+                               make_display();
                                forward(1, 0, 0);
+                       }
                        ignore_eoi = 0;
                        /*
                         * This gets us back in "F mode" after processing 
@@ -1148,14 +1175,7 @@ commands()
                         * Flush buffers, then repaint screen.
                         * Don't flush the buffers on a pipe!
                         */
-                       if (ch_getflags() & CH_CANSEEK)
-                       {
-                               ch_flush();
-                               clr_linenum();
-#if HILITE_SEARCH
-                               clr_hilite();
-#endif
-                       }
+                       clear_buffers();
                        /* FALLTHRU */
                case A_REPAINT:
                        /*
@@ -1257,7 +1277,8 @@ commands()
 /*
  * Define abbreviation for a commonly used sequence below.
  */
-#define        DO_SEARCH()     if (number <= 0) number = 1;    \
+#define        DO_SEARCH() \
+                       if (number <= 0) number = 1;    \
                        mca_search();                   \
                        cmd_exec();                     \
                        multi_search((char *)NULL, (int) number);
index 3007473..ac1668f 100755 (executable)
@@ -682,7 +682,7 @@ lesskey(filename, sysvar)
                close(f);
                return (-1);
        }
-       if (lseek(f, (off_t)0, 0) == BAD_LSEEK)
+       if (lseek(f, (off_t)0, SEEK_SET) == BAD_LSEEK)
        {
                free(buf);
                close(f);
index 908f29e..e2e30f2 100755 (executable)
@@ -10,6 +10,9 @@
 
 
 #include "less.h"
+#if HAVE_STAT
+#include <sys/stat.h>
+#endif
 
 public int fd0 = 0;
 
@@ -36,6 +39,11 @@ extern int force_logfile;
 extern char *namelogfile;
 #endif
 
+#if HAVE_STAT_INO
+public dev_t curr_dev;
+public ino_t curr_ino;
+#endif
+
 char *curr_altfilename = NULL;
 static void *curr_altpipe;
 
@@ -178,6 +186,9 @@ close_file()
                curr_altfilename = NULL;
        }
        curr_ifile = NULL_IFILE;
+#if HAVE_STAT_INO
+       curr_ino = curr_dev = 0;
+#endif
 }
 
 /*
@@ -360,7 +371,6 @@ edit_ifile(ifile)
                        }
                }
        }
-       free(qopen_filename);
 
        /*
         * Get the new ifile.
@@ -384,11 +394,24 @@ edit_ifile(ifile)
 #if LOGFILE
                if (namelogfile != NULL && is_tty)
                        use_logfile(namelogfile);
+#endif
+#if HAVE_STAT_INO
+               /* Remember the i-number and device of the opened file. */
+               {
+                       struct stat statbuf;
+                       int r = stat(qopen_filename, &statbuf);
+                       if (r == 0)
+                       {
+                               curr_ino = statbuf.st_ino;
+                               curr_dev = statbuf.st_dev;
+                       }
+               }
 #endif
                if (every_first_cmd != NULL)
                        ungetsc(every_first_cmd);
        }
 
+       free(qopen_filename);
        no_display = !any_display;
        flush();
        any_display = TRUE;
@@ -657,6 +680,14 @@ reedit_ifile(save_ifile)
        quit(QUIT_ERROR);
 }
 
+       public void
+reopen_curr_ifile()
+{
+       IFILE save_ifile = save_curr_ifile();
+       close_file();
+       reedit_ifile(save_ifile);
+}
+
 /*
  * Edit standard input.
  */
@@ -747,7 +778,7 @@ loop:
                 * Append: open the file and seek to the end.
                 */
                logfile = open(filename, OPEN_APPEND);
-               if (lseek(logfile, (off_t)0, 2) == BAD_LSEEK)
+               if (lseek(logfile, (off_t)0, SEEK_END) == BAD_LSEEK)
                {
                        close(logfile);
                        logfile = -1;
index ea3120f..aa45b76 100755 (executable)
@@ -476,7 +476,7 @@ bin_file(f)
 
        if (!seekable(f))
                return (0);
-       if (lseek(f, (off_t)0, 0) == BAD_LSEEK)
+       if (lseek(f, (off_t)0, SEEK_SET) == BAD_LSEEK)
                return (0);
        n = read(f, data, sizeof(data));
        for (i = 0;  i < n;  i++)
@@ -505,7 +505,7 @@ seek_filesize(f)
 {
        off_t spos;
 
-       spos = lseek(f, (off_t)0, 2);
+       spos = lseek(f, (off_t)0, SEEK_END);
        if (spos == BAD_LSEEK)
                return (NULL_POSITION);
        return ((POSITION) spos);
index a4a0c7c..649598e 100644 (file)
        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 ();
index 8f0d2d8..078ccbb 100755 (executable)
@@ -71,6 +71,9 @@
 #if HAVE_CTYPE_H
 #include <ctype.h>
 #endif
+#if HAVE_WCTYPE_H
+#include <wctype.h>
+#endif
 #if HAVE_LIMITS_H
 #include <limits.h>
 #endif
@@ -125,16 +128,23 @@ void free();
 #undef IS_SPACE
 #undef IS_DIGIT
 
-#if !HAVE_UPPER_LOWER
-#define        IS_UPPER(c)     ASCII_IS_UPPER(c)
-#define        IS_LOWER(c)     ASCII_IS_LOWER(c)
-#define        TO_UPPER(c)     ASCII_TO_UPPER(c)
-#define        TO_LOWER(c)     ASCII_TO_LOWER(c)
+#if HAVE_WCTYPE
+#define        IS_UPPER(c)     iswupper(c)
+#define        IS_LOWER(c)     iswlower(c)
+#define        TO_UPPER(c)     towupper(c)
+#define        TO_LOWER(c)     towlower(c)
 #else
+#if HAVE_UPPER_LOWER
 #define        IS_UPPER(c)     isupper((unsigned char) (c))
 #define        IS_LOWER(c)     islower((unsigned char) (c))
 #define        TO_UPPER(c)     toupper((unsigned char) (c))
 #define        TO_LOWER(c)     tolower((unsigned char) (c))
+#else
+#define        IS_UPPER(c)     ASCII_IS_UPPER(c)
+#define        IS_LOWER(c)     ASCII_IS_LOWER(c)
+#define        TO_UPPER(c)     ASCII_TO_UPPER(c)
+#define        TO_LOWER(c)     ASCII_TO_LOWER(c)
+#endif
 #endif
 
 #ifdef isspace
@@ -187,6 +197,13 @@ void free();
 
 #define        BAD_LSEEK       ((off_t)-1)
 
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+#ifndef SEEK_END
+#define SEEK_END 2
+#endif
+
 #ifndef CHAR_BIT
 #define CHAR_BIT 8
 #endif
@@ -457,6 +474,9 @@ struct textlist
 #define        QUIT_ERROR      1
 #define        QUIT_SAVED_STATUS (-1)
 
+#define FOLLOW_DESC     0
+#define FOLLOW_NAME     1
+
 /* filestate flags */
 #define        CH_CANSEEK      001
 #define        CH_KEEPOPEN     002
index 483e194..d226181 100644 (file)
@@ -1,4 +1,4 @@
-.TH LESS 1 "Version 409: 12 Oct 2007"
+.TH LESS 1 "Version 415: 15 Nov 2007"
 .SH NAME
 less \- opposite of more
 .SH SYNOPSIS
@@ -799,11 +799,6 @@ Disables sending the termcap initialization and deinitialization strings
 to the terminal.
 This is sometimes desirable if the deinitialization string does
 something unnecessary, like clearing the screen.
-.IP "\-\-no-keypad"
-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.
 .IP "\-y\fIn\fP or \-\-max-forw-scroll=\fIn\fP"
 Specifies a maximum number of lines to scroll forward.
 If it is necessary to scroll forward more than \fIn\fP lines,
@@ -847,6 +842,24 @@ Specifies the default number of positions to scroll horizontally
 in the RIGHTARROW and LEFTARROW commands.
 If the number specified is zero, it sets the default number of
 positions to one half of the screen width.
+.IP "\-\-no-keypad"
+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.
+.IP "\-\-follow-name"
+Normally, if the input file is renamed while an F command is executing, 
+.I less
+will continue to display the contents of the original file despite
+its name change.
+If \-\-follow-name is specified, during an F command
+.I less
+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 renamed) file),
+.I less
+will display the contents of that new file.
 .IP \-\-
 A command line argument of "\-\-" marks the end of option arguments.
 Any arguments following this are interpreted as filenames.
index d9dd628..d31b83d 100644 (file)
@@ -1,4 +1,4 @@
-.TH LESSECHO 1 "Version 409: 12 Oct 2007"
+.TH LESSECHO 1 "Version 415: 15 Nov 2007"
 .SH NAME
 lessecho \- expand metacharacters
 .SH SYNOPSIS
index afc3586..a757bab 100644 (file)
@@ -1,4 +1,4 @@
-.TH LESSKEY 1 "Version 409: 12 Oct 2007"
+.TH LESSKEY 1 "Version 415: 15 Nov 2007"
 .SH NAME
 lesskey \- specify key bindings for less
 .SH SYNOPSIS
index d61b872..08ca3be 100755 (executable)
@@ -1046,6 +1046,23 @@ pdone(endline)
                linebuf[curr] = '\n';
                attr[curr] = AT_NORMAL;
                curr++;
+       } 
+       else if (ignaw && !auto_wrap && column >= sc_width)
+       {
+               /*
+                * Big horrible kludge.
+                * No-wrap terminals are too hard to deal with when they get in
+                * the state where a full screen width of characters have been 
+                * output but the cursor is sitting on the right edge instead
+                * of at the start of the next line.  
+                * So after we output a full line, we output an extra 
+                * space and backspace to force the cursor to the 
+                * beginning of the next line, like a sane terminal.
+                */
+               linebuf[curr] = ' '; 
+               attr[curr++] = AT_NORMAL;
+               linebuf[curr] = '\b'; 
+               attr[curr++] = AT_NORMAL;
        }
        linebuf[curr] = '\0';
        attr[curr] = AT_NORMAL;
index 4ca5142..f296b79 100755 (executable)
@@ -442,7 +442,7 @@ opt__V(type, s)
                any_display = 1;
                putstr("less ");
                putstr(version);
-               putstr("\nCopyright (C) 1984-2005 Mark Nudelman\n\n");
+               putstr("\nCopyright (C) 1984-2007 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");
index 2514463..755a93d 100755 (executable)
@@ -50,7 +50,8 @@ public int shift_count;               /* Number of positions to shift horizontally */
 public int status_col;         /* Display a status column */
 public int use_lessopen;       /* Use the LESSOPEN filter */
 public int quit_on_intr;       /* Quit on interrupt */
-public int oldbot;             /* Old bottom of screen behavior */
+public int follow_mode;                /* F cmd Follows file desc or file name? */
+public int oldbot;             /* Old bottom of screen behavior {{REMOVE}} */
 #if HILITE_SEARCH
 public int hilite_search;      /* Highlight matched search patterns? */
 #endif
@@ -113,6 +114,7 @@ static struct optname query_optname  = { "help",                 NULL };
 static struct optname pound_optname  = { "shift",                NULL };
 static struct optname keypad_optname = { "no-keypad",            NULL };
 static struct optname oldbot_optname = { "old-bot",              NULL };
+static struct optname follow_optname = { "follow-name",          NULL };
 
 
 /*
@@ -440,6 +442,14 @@ static struct loption option[] =
                        NULL
                }
        },
+       { '.', &follow_optname,
+               BOOL, FOLLOW_DESC, &follow_mode, NULL,
+               {
+                       "F command Follows file descriptor",
+                       "F command Follows file name",
+                       NULL
+               }
+       },
        { '\0', NULL, NOVAR, 0, NULL, NULL, { NULL, NULL, NULL } }
 };
 
index 51ab799..8e3a060 100755 (executable)
@@ -1844,11 +1844,15 @@ line_left()
                GetConsoleScreenBufferInfo(con_out, &scr);
                row = scr.dwCursorPosition.Y - scr.srWindow.Top + 1;
        }
+#else
+#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
+               row = wherey();
 #else
        {
                struct rccoord tpos = _gettextposition();
                row = tpos.row;
        }
+#endif
 #endif
        _settextposition(row, 1);
 #endif
index 6104964..b983334 100755 (executable)
@@ -64,6 +64,7 @@ extern int screen_trashed;
 extern int size_linebuf;
 extern int squished;
 extern int can_goto_line;
+extern int utf_mode;
 static int hide_hilite;
 static int oldbot;
 static POSITION prep_startpos;
@@ -104,14 +105,31 @@ static int is_ucase_pattern;
 static int last_search_type;
 static char *last_pattern = NULL;
 
-/*
- * Convert text.  Perform one or more of these transformations:
- */
 #define        CVT_TO_LC       01      /* Convert upper-case to lower-case */
 #define        CVT_BS          02      /* Do backspace processing */
 #define        CVT_CRLF        04      /* Remove CR after LF */
 #define        CVT_ANSI        010     /* Remove ANSI escape sequences */
 
+/*
+ * Get the length of a buffer needed to convert a string.
+ */
+       static int
+cvt_length(len, ops)
+       int len;
+       int ops;
+{
+       if (utf_mode && (ops & CVT_TO_LC))
+               /*
+                * Converting case can cause a UTF-8 string to increase in length.
+                * Multiplying by 3 is the worst case.
+                */
+               len *= 3;
+       return len+1;
+}
+
+/*
+ * Convert text.  Perform one or more of these transformations:
+ */
        static void
 cvt_text(odst, osrc, lenp, ops)
        char *odst;
@@ -138,7 +156,7 @@ cvt_text(odst, osrc, lenp, ops)
                        put_wchar(&dst, TO_LOWER(ch));
                } else if ((ops & CVT_BS) && ch == '\b' && dst > odst)
                {
-                       /* Delete BS and preceding char. */
+                       /* Delete backspace and preceding char. */
                        do {
                                dst--;
                        } while (dst > odst &&
@@ -361,7 +379,7 @@ undo_search()
  * Compile a search pattern, for future use by match_pattern.
  */
        static int
-compile_pattern(pattern, search_type)
+compile_pattern2(pattern, search_type)
        char *pattern;
        int search_type;
 {
@@ -440,6 +458,30 @@ compile_pattern(pattern, search_type)
        return (0);
 }
 
+/*
+ * Like compile_pattern, but convert the pattern to lowercase if necessary.
+ */
+       static int
+compile_pattern(pattern, search_type)
+       char *pattern;
+       int search_type;
+{
+       char *cvt_pattern;
+       int result;
+
+       if (caseless != OPT_ONPLUS)
+               cvt_pattern = pattern;
+       else
+       {
+               cvt_pattern = (char*) ecalloc(1, cvt_length(strlen(pattern), CVT_TO_LC));
+               cvt_text(cvt_pattern, pattern, (int *)NULL, CVT_TO_LC);
+       }
+       result = compile_pattern2(cvt_pattern, search_type);
+       if (cvt_pattern != pattern)
+               free(cvt_pattern);
+       return (result);
+}
+
 /*
  * Forget that we have a compiled pattern.
  */
@@ -679,35 +721,8 @@ add_hilite(anchor, hl)
        ihl->hl_next = hl;
 }
 
-       static void
-adj_hilite_ansi(cvt_ops, line, line_len, npos)
-       int cvt_ops;
-       char **line;
-       int line_len;
-       POSITION *npos;
-{
-       char *line_end = *line + line_len;
-
-       if (cvt_ops & CVT_ANSI)
-               while (IS_CSI_START(**line))
-               {
-                       /*
-                        * Found an ESC.  The file position moves
-                        * forward past the entire ANSI escape sequence.
-                        */
-                       (*line)++;
-                       (*npos)++;
-                       while (*line < line_end)
-                       {
-                               (*npos)++;
-                               if (!is_ansi_middle(*(*line)++))
-                                       break;
-                       }
-               }
-}
-
 /*
- * Adjust hl_startpos & hl_endpos to account for backspace processing.
+ * Adjust hl_startpos & hl_endpos to account for processing by cvt_text.
  */
        static void
 adj_hilite(anchor, linepos, cvt_ops)
@@ -716,18 +731,21 @@ adj_hilite(anchor, linepos, cvt_ops)
        int cvt_ops;
 {
        char *line;
+       char *oline;
        int line_len;
        char *line_end;
        struct hilite *hl;
        int checkstart;
        POSITION opos;
        POSITION npos;
+       LWCHAR ch;
+       int ncwidth;
 
        /*
         * The line was already scanned and hilites were added (in hilite_line).
         * But it was assumed that each char position in the line 
         * correponds to one char position in the file.
-        * This may not be true if there are backspaces in the line.
+        * This may not be true if cvt_text modified the line.
         * Get the raw line again.  Look at each character.
         */
        (void) forw_raw_line(linepos, &line, &line_len);
@@ -758,31 +776,43 @@ adj_hilite(anchor, linepos, cvt_ops)
                }
                if (line == line_end)
                        break;
-               adj_hilite_ansi(cvt_ops, &line, line_end - line, &npos);
-               opos++;
-               npos++;
-               line++;
-               if (cvt_ops & CVT_BS)
+
+               /* Get the next char from the line. */
+               oline = line;
+               ch = step_char(&line, +1, line_end);
+               ncwidth = line - oline;
+               npos += ncwidth;
+
+               /* Figure out how this char was processed by cvt_text. */
+               if ((cvt_ops & CVT_BS) && ch == '\b')
+               {
+                       /* Skip the backspace and the following char. */
+                       oline = line;
+                       ch = step_char(&line, +1, line_end);
+                       ncwidth = line - oline;
+                       npos += ncwidth;
+               } else if ((cvt_ops & CVT_TO_LC) && IS_UPPER(ch))
+               {
+                       /* Converted uppercase to lower.
+                        * Note that this may have changed the number of bytes 
+                        * that the character occupies. */
+                       char dbuf[6];
+                       char *dst = dbuf;
+                       put_wchar(&dst, TO_LOWER(ch));
+                       opos += dst - dbuf;
+               } else if ((cvt_ops & CVT_ANSI) && IS_CSI_START(ch))
                {
-                       while (*line == '\b')
+                       /* Skip to end of ANSI escape sequence. */
+                       while (line < line_end)
                        {
                                npos++;
-                               line++;
-                               adj_hilite_ansi(cvt_ops, &line, line_end - line, &npos);
-                               if (line == line_end)
-                               {
-                                       --npos;
-                                       --line;
+                               if (!is_ansi_middle(*++line))
                                        break;
-                               }
-                               /*
-                                * Found a backspace.  The file position moves
-                                * forward by 2 relative to the processed line
-                                * which was searched in hilite_line.
-                                */
-                               npos++;
-                               line++;
                        }
+               } else 
+               {
+                       /* Ordinary unprocessed character. */
+                       opos += ncwidth;
                }
        }
 }
@@ -1012,6 +1042,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
        POSITION *pendpos;
 {
        char *line;
+       char *cline;
        int line_len;
        LINENUM linenum;
        char *sp, *ep;
@@ -1097,18 +1128,22 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
                 * If we're doing backspace processing, delete backspaces.
                 */
                cvt_ops = get_cvt_ops();
-               cvt_text(line, line, &line_len, cvt_ops);
+               cline = calloc(1, cvt_length(line_len, cvt_ops));
+               cvt_text(cline, line, &line_len, cvt_ops);
 
                /*
                 * Test the next line to see if we have a match.
                 * We are successful if we either want a match and got one,
                 * or if we want a non-match and got one.
                 */
-               line_match = match_pattern(line, line_len, &sp, &ep, 0);
+               line_match = match_pattern(cline, line_len, &sp, &ep, 0);
                line_match = (!(search_type & SRCH_NO_MATCH) && line_match) ||
                                ((search_type & SRCH_NO_MATCH) && !line_match);
                if (!line_match)
+               {
+                       free(cline);
                        continue;
+               }
                /*
                 * Got a match.
                 */
@@ -1121,8 +1156,9 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
                         * hilite list and keep searching.
                         */
                        if (line_match)
-                               hilite_line(linepos, line, line_len, sp, ep, cvt_ops);
+                               hilite_line(linepos, cline, line_len, sp, ep, cvt_ops);
 #endif
+                       free(cline);
                } else if (--matches <= 0)
                {
                        /*
@@ -1138,9 +1174,10 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
                                 */
                                clr_hilite();
                                if (line_match)
-                                       hilite_line(linepos, line, line_len, sp, ep, cvt_ops);
+                                       hilite_line(linepos, cline, line_len, sp, ep, cvt_ops);
                        }
 #endif
+                       free(cline);
                        if (plinepos != NULL)
                                *plinepos = linepos;
                        return (0);
@@ -1163,9 +1200,6 @@ hist_pattern(search_type)
        if (pattern == NULL)
                return (0);
 
-       if (caseless == OPT_ONPLUS)
-               cvt_text(pattern, pattern, (int *)NULL, CVT_TO_LC);
-
        if (compile_pattern(pattern, search_type) < 0)
                return (0);
 
@@ -1202,7 +1236,7 @@ search(search_type, pattern, n)
        int n;
 {
        POSITION pos;
-       int ucase;
+       int result;
 
        if (pattern == NULL || *pattern == '\0')
        {
@@ -1245,16 +1279,13 @@ search(search_type, pattern, n)
                /*
                 * Compile the pattern.
                 */
-               ucase = is_ucase(pattern);
-               if (caseless == OPT_ONPLUS)
-                       cvt_text(pattern, pattern, (int *)NULL, CVT_TO_LC);
                if (compile_pattern(pattern, search_type) < 0)
                        return (-1);
                /*
                 * Ignore case if -I is set OR
                 * -i is set AND the pattern is all lowercase.
                 */
-               is_ucase_pattern = ucase;
+               is_ucase_pattern = is_ucase(pattern);
                if (is_ucase_pattern && caseless != OPT_ONPLUS)
                        is_caseless = 0;
                else
index b22fda8..ab00faf 100755 (executable)
@@ -662,7 +662,7 @@ prevgtag()
 /*
  * Position the current file at at what is hopefully the tag that was chosen
  * using either findtag() or one of nextgtag() and prevgtag().  Returns -1
- * if it was unable to position at the tag, 0 if succesful.
+ * if it was unable to position at the tag, 0 if successful.
  */
        static POSITION
 gtagsearch()
index 1fce12e..578dc55 100755 (executable)
@@ -696,6 +696,11 @@ v406  6/17/07      Fix secure build.
 v407  8/16/07  Fix bugs; support CSI chars.
 v408  10/1/07  Fix bug in -i with non-ASCII chars.
 v409  10/12/07 Fix crash when viewing text with invalid UTF-8 sequences.
+v411  11/6/07  Fix case-insensitive searching with non-ASCII text.
+v412  11/6/07  Use symbolic SEEK constants.
+v413  11/6/07  Fix search highlight bug with non-ASCII text.
+v414  11/6/07  Fix display bug with no-wrap terminals.
+v415  11/14/07 Add --follow-name option.
 */
 
-char version[] = "409";
+char version[] = "415";