From 720c436c669bf5f7405777dcd50575bf6651e0f8 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 4 Jun 2007 01:43:11 +0000 Subject: [PATCH] Resolve conflicts. --- contrib/less/command.c | 51 +++++++++++---- contrib/less/forwback.c | 37 +++++++---- contrib/less/less.h | 7 +- contrib/less/line.c | 30 +++++++-- contrib/less/main.c | 39 +++++++----- contrib/less/prompt.c | 11 +++- contrib/less/screen.c | 55 ++++++++++++++-- contrib/less/search.c | 138 +++++++++++++++++++++++++++++----------- contrib/less/signal.c | 13 ++-- 9 files changed, 281 insertions(+), 100 deletions(-) diff --git a/contrib/less/command.c b/contrib/less/command.c index 18ea4d42174b..bac243130515 100644 --- a/contrib/less/command.c +++ b/contrib/less/command.c @@ -1,6 +1,6 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1984-2005 Mark Nudelman + * Copyright (C) 1984-2007 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. @@ -24,7 +24,6 @@ extern int erase_char, erase2_char, kill_char; extern int sigs; -extern int quit_at_eof; extern int quit_if_one_screen; extern int squished; extern int hit_eof; @@ -39,7 +38,7 @@ extern int ignore_eoi; extern int secure; extern int hshift; extern int show_attn; -extern int more_mode; +extern int less_is_more; extern char *every_first_cmd; extern char *curr_altfilename; extern char version[]; @@ -56,6 +55,8 @@ extern char *editproto; #endif extern int screen_trashed; /* The screen has been overwritten */ extern int shift_count; +extern int oldbot; +extern int forw_prompt; static char ungot[UNGOT_SIZE]; static char *ungotp = NULL; @@ -65,6 +66,7 @@ static char *shellcmd = NULL; /* For holding last shell command for "!!" */ static int mca; /* The multicharacter command (action) */ static int search_type; /* The previous type of search */ static LINENUM number; /* The number typed by the user */ +static long fraction; /* The fractional part of the number */ static char optchar; static int optflag; static int optgetname; @@ -77,7 +79,7 @@ static char pipec; static void multi_search(); /* - * Move the cursor to lower left before executing a command. + * Move the cursor to start of prompt line before executing a command. * This looks nicer if the command takes a long time before * updating the screen. */ @@ -85,7 +87,7 @@ static void multi_search(); cmd_exec() { clear_attn(); - lower_left(); + line_left(); flush(); } @@ -100,6 +102,7 @@ start_mca(action, prompt, mlist, cmdflags) int cmdflags; { mca = action; + clear_bot(); clear_cmd(); cmd_putstr(prompt); set_mlist(mlist, cmdflags); @@ -122,6 +125,7 @@ mca_search() else mca = A_B_SEARCH; + clear_bot(); clear_cmd(); if (search_type & SRCH_NO_MATCH) @@ -157,6 +161,7 @@ mca_opt_toggle() dash = (flag == OPT_NO_TOGGLE) ? "_" : "-"; mca = A_OPT_TOGGLE; + clear_bot(); clear_cmd(); cmd_putstr(dash); if (optgetname) @@ -293,14 +298,14 @@ mca_char(c) * Entering digits of a number. * Terminated by a non-digit. */ - if ((c < '0' || c > '9') && + if (!((c >= '0' && c <= '9') || c == '.') && editchar(c, EC_PEEK|EC_NOHISTORY|EC_NOCOMPLETE|EC_NORIGHTLEFT) == A_INVALID) { /* * Not part of the number. * Treat as a normal command character. */ - number = cmd_int(); + number = cmd_int(&fraction); mca = 0; cmd_accept(); return (NO_MCA); @@ -482,13 +487,13 @@ mca_char(c) switch (c) { case '*': - if (more_mode) + if (less_is_more) break; case CONTROL('E'): /* ignore END of file */ flag = SRCH_PAST_EOF; break; case '@': - if (more_mode) + if (less_is_more) break; case CONTROL('F'): /* FIRST file */ flag = SRCH_FIRST_FILE; @@ -612,7 +617,7 @@ prompt() * {{ Relying on "first prompt" to detect a single-screen file * fails if +G is used, for example. }} */ - if ((quit_at_eof == OPT_ONPLUS || quit_if_one_screen) && + if ((get_quit_at_eof() == OPT_ONPLUS || quit_if_one_screen) && hit_eof && !(ch_getflags() & CH_HELPFILE) && next_ifile(curr_ifile) == NULL_IFILE) quit(QUIT_OK); @@ -622,7 +627,7 @@ prompt() * If the -e flag is set and we've hit EOF on the last file, * and the file is squished (shorter than the screen), quit. */ - if (quit_at_eof && squished && + if (get_quit_at_eof() && squished && next_ifile(curr_ifile) == NULL_IFILE) quit(QUIT_OK); #endif @@ -637,7 +642,20 @@ prompt() /* * Select the proper prompt and display it. */ + /* + * If the previous action was a forward movement, + * don't clear the bottom line of the display; + * just print the prompt since the forward movement guarantees + * that we're in the right position to display the prompt. + * Clearing the line could cause a problem: for example, if the last + * line displayed ended at the right screen edge without a newline, + * then clearing would clear the last displayed line rather than + * the prompt line. + */ + if (!forw_prompt) + clear_bot(); clear_cmd(); + forw_prompt = 0; p = pr_string(); if (p == NULL || *p == '\0') putchr(':'); @@ -647,6 +665,7 @@ prompt() putstr(p); at_exit(); } + clear_eol(); } /* @@ -1167,11 +1186,17 @@ commands() * Go to a specified percentage into the file. */ if (number < 0) + { number = 0; + fraction = 0; + } if (number > 100) + { number = 100; + fraction = 0; + } cmd_exec(); - jump_percent((int) number); + jump_percent((int) number, fraction); break; case A_GOEND: @@ -1392,7 +1417,7 @@ commands() number = 1; if (edit_next((int) number)) { - if (quit_at_eof && hit_eof && + if (get_quit_at_eof() && hit_eof && !(ch_getflags() & CH_HELPFILE)) quit(QUIT_OK); parg.p_string = (number > 1) ? "(N-th) " : ""; diff --git a/contrib/less/forwback.c b/contrib/less/forwback.c index a514c9f9fb7b..309eef6e42e2 100644 --- a/contrib/less/forwback.c +++ b/contrib/less/forwback.c @@ -1,6 +1,6 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1984-2005 Mark Nudelman + * Copyright (C) 1984-2007 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,19 +22,20 @@ public int hit_eof; /* Keeps track of how many times we hit end of file */ public int screen_trashed; public int squished; public int no_back_scroll = 0; +public int forw_prompt; extern int sigs; extern int top_scroll; extern int quiet; extern int sc_width, sc_height; -extern int quit_at_eof; -extern int more_mode; +extern int less_is_more; extern int plusoption; extern int forw_scroll; extern int back_scroll; extern int ignore_eoi; extern int clear_bg; extern int final_attr; +extern int oldbot; #if TAGS extern char *tagoption; #endif @@ -79,7 +80,7 @@ eof_check() * of the screen; this can happen when we display a short file * for the first time. */ - static void + public void squish_check() { if (!squished) @@ -137,10 +138,8 @@ forw(n, pos, force, only_last, nblank) pos_clear(); add_forw_pos(pos); force = 1; - if (more_mode == 0) - { - if (top_scroll == OPT_ONPLUS || (first_time && top_scroll != OPT_ON)) - clear(); + if (less_is_more == 0) { + clear(); home(); } } else @@ -160,8 +159,7 @@ forw(n, pos, force, only_last, nblank) force = 1; if (top_scroll) { - if (top_scroll == OPT_ONPLUS) - clear(); + clear(); home(); } else if (!first_time) { @@ -226,7 +224,7 @@ forw(n, pos, force, only_last, nblank) * start the display after the beginning of the file, * and it is not appropriate to squish in that case. */ - if ((first_time || more_mode) && + if ((first_time || less_is_more) && pos == NULL_POSITION && !top_scroll && #if TAGS tagoption == NULL && @@ -236,9 +234,16 @@ forw(n, pos, force, only_last, nblank) squished = 1; continue; } - if (top_scroll == OPT_ON) - clear_eol(); put_line(); +#if 0 + /* {{ + * Can't call clear_eol here. The cursor might be at end of line + * on an ignaw terminal, so clear_eol would clear the last char + * of the current line instead of all of the next line. + * If we really need to do this on clear_bg terminals, we need + * to find a better way. + * }} + */ if (clear_bg && apply_at_specials(final_attr) != AT_NORMAL) { /* @@ -250,6 +255,8 @@ forw(n, pos, force, only_last, nblank) */ clear_eol(); } +#endif + forw_prompt = 1; } if (ignore_eoi) @@ -315,6 +322,8 @@ back(n, pos, force, only_last) eof_bell(); else if (do_repaint) repaint(); + else if (!oldbot) + lower_left(); (void) currline(BOTTOM); } @@ -330,7 +339,7 @@ forward(n, force, only_last) { POSITION pos; - if (quit_at_eof && hit_eof && !(ch_getflags() & CH_HELPFILE)) + if (get_quit_at_eof() && hit_eof && !(ch_getflags() & CH_HELPFILE)) { /* * If the -e flag is set and we're trying to go diff --git a/contrib/less/less.h b/contrib/less/less.h index 3700b4f0d080..ada9e270ac91 100644 --- a/contrib/less/less.h +++ b/contrib/less/less.h @@ -1,6 +1,6 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1984-2005 Mark Nudelman + * Copyright (C) 1984-2007 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 @@ * contact the author, see the README file. */ +#define NEWBOT 1 /* * Standard include file for "less". @@ -296,6 +297,10 @@ struct textlist #define READ_INTR (-2) +/* A fraction is represented by an int n; the fraction is n/NUM_FRAC_DENOM */ +#define NUM_FRAC_DENOM 1000000 +#define NUM_LOG_FRAC_DENOM 6 + /* How quiet should we be? */ #define NOT_QUIET 0 /* Ring bell at eof and for errors */ #define LITTLE_QUIET 1 /* Ring bell only for errors */ diff --git a/contrib/less/line.c b/contrib/less/line.c index 42a2ea331ef5..c1a31fb714da 100644 --- a/contrib/less/line.c +++ b/contrib/less/line.c @@ -1,6 +1,6 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1984-2005 Mark Nudelman + * Copyright (C) 1984-2007 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,6 +60,7 @@ extern int bl_s_width, bl_e_width; extern int so_s_width, so_e_width; extern int sc_width, sc_height; extern int utf_mode; +extern int oldbot; extern POSITION start_attnpos; extern POSITION end_attnpos; @@ -995,6 +996,8 @@ pflushmbc() pdone(endline) int endline; { + int nl; + (void) pflushmbc(); if (pendc && (pendc != '\r' || !endline)) @@ -1025,8 +1028,21 @@ pdone(endline) /* * Add a newline if necessary, * and append a '\0' to the end of the line. + * We output a newline if we're not at the right edge of the screen, + * or if the terminal doesn't auto wrap, + * or if this is really the end of the line AND the terminal ignores + * a newline at the right edge. + * (In the last case we don't want to output a newline if the terminal + * doesn't ignore it since that would produce an extra blank line. + * But we do want to output a newline if the terminal ignores it in case + * the next line is blank. In that case the single newline output for + * that blank line would be ignored!) */ - if (column < sc_width || !auto_wrap || ignaw || ctldisp == OPT_ON) + if (!oldbot) + nl = (column < sc_width || !auto_wrap || (endline && ignaw) || ctldisp == OPT_ON); + else + nl = (column < sc_width || !auto_wrap || ignaw || ctldisp == OPT_ON); + if (nl) { linebuf[curr] = '\n'; attr[curr] = AT_NORMAL; @@ -1094,9 +1110,10 @@ null_line() * {{ This is supposed to be more efficient than forw_line(). }} */ public POSITION -forw_raw_line(curr_pos, linep) +forw_raw_line(curr_pos, linep, line_lenp) POSITION curr_pos; char **linep; + int *line_lenp; { register int n; register int c; @@ -1132,6 +1149,8 @@ forw_raw_line(curr_pos, linep) linebuf[n] = '\0'; if (linep != NULL) *linep = linebuf; + if (line_lenp != NULL) + *line_lenp = n; return (new_pos); } @@ -1140,9 +1159,10 @@ forw_raw_line(curr_pos, linep) * {{ This is supposed to be more efficient than back_line(). }} */ public POSITION -back_raw_line(curr_pos, linep) +back_raw_line(curr_pos, linep, line_lenp) POSITION curr_pos; char **linep; + int *line_lenp; { register int n; register int c; @@ -1203,5 +1223,7 @@ back_raw_line(curr_pos, linep) } if (linep != NULL) *linep = &linebuf[n]; + if (line_lenp != NULL) + *line_lenp = size_linebuf - 1 - n; return (new_pos); } diff --git a/contrib/less/main.c b/contrib/less/main.c index c7dbdb864c32..33e8600c11e3 100644 --- a/contrib/less/main.c +++ b/contrib/less/main.c @@ -1,6 +1,6 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1984-2004 Mark Nudelman + * Copyright (C) 1984-2007 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. @@ -33,7 +33,7 @@ public char * progname; public int quitting; public int secure; public int dohelp; -public int more_mode = 0; +public int less_is_more; #if LOGFILE public int logfile = -1; @@ -58,6 +58,8 @@ static char consoleTitle[256]; extern int missing_cap; extern int know_dumb; +extern int quit_if_one_screen; +extern int pr_type; /* @@ -111,27 +113,29 @@ main(argc, argv) * Process command line arguments and LESS environment arguments. * Command line arguments override environment arguments. */ - if (strcmp(__progname, "more") == 0) - more_mode = 1; - is_tty = isatty(1); get_term(); init_cmds(); - init_prompt(); init_charset(); init_line(); init_cmdhist(); init_option(); - - if (more_mode) { - scan_option("-E"); - scan_option("-m"); - scan_option("-G"); - scan_option("-f"); - s = lgetenv("MORE"); - } else { - s = lgetenv("LESS"); + + /* + * If the name of the executable program is "more", + * act like LESS_IS_MORE is set. + */ + for (s = progname + strlen(progname); s > progname; s--) + { + if (s[-1] == PATHNAME_SEP[0]) + break; } + if (strcmp(s, "more") == 0) + less_is_more = 1; + + init_prompt(); + + s = lgetenv(less_is_more ? "MORE" : "LESS"); if (s != NULL) scan_option(save(s)); @@ -156,6 +160,9 @@ main(argc, argv) quit(QUIT_OK); } + if (less_is_more && get_quit_at_eof()) + quit_if_one_screen = TRUE; + #if EDITOR editor = lgetenv("VISUAL"); if (editor == NULL || *editor == '\0') @@ -230,7 +237,7 @@ main(argc, argv) quit(QUIT_OK); } - if (missing_cap && !know_dumb && !more_mode) + if (missing_cap && !know_dumb) error("WARNING: terminal is not fully functional", NULL_PARG); init_mark(); open_getchr(); diff --git a/contrib/less/prompt.c b/contrib/less/prompt.c index 7e22f99cf2db..4f9689567e58 100644 --- a/contrib/less/prompt.c +++ b/contrib/less/prompt.c @@ -1,6 +1,6 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1984-2004 Mark Nudelman + * Copyright (C) 1984-2007 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. @@ -31,6 +31,7 @@ extern int linenums; extern int hshift; extern int sc_height; extern int jump_sline; +extern int less_is_more; extern IFILE curr_ifile; #if EDITOR extern char *editor; @@ -53,6 +54,8 @@ static constant char h_proto[] = "HELP -- ?eEND -- Press g to see it again:Press RETURN for more., or q when done"; static constant char w_proto[] = "Waiting for data"; +static constant char more_proto[] = + "--More--(?eEND ?x- Next\\: %x.:?pB%pB\\%:byte %bB?s/%s...%t)"; public char *prproto[3]; public char constant *eqproto = e_proto; @@ -69,7 +72,7 @@ static char *mp; init_prompt() { prproto[0] = save(s_proto); - prproto[1] = save(m_proto); + prproto[1] = save(less_is_more ? more_proto : m_proto); prproto[2] = save(M_proto); eqproto = save(e_proto); hproto = save(h_proto); @@ -562,9 +565,11 @@ eq_message() pr_string() { char *prompt; + int type; + type = (!less_is_more) ? pr_type : pr_type ? 0 : 1; prompt = pr_expand((ch_getflags() & CH_HELPFILE) ? - hproto : prproto[pr_type], + hproto : prproto[type], sc_width-so_s_width-so_e_width-2); new_file = 0; return (prompt); diff --git a/contrib/less/screen.c b/contrib/less/screen.c index 03960c721cbd..399ffc3e37f0 100644 --- a/contrib/less/screen.c +++ b/contrib/less/screen.c @@ -1,6 +1,6 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1984-2005 Mark Nudelman + * Copyright (C) 1984-2007 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. @@ -164,6 +164,7 @@ static char *sc_home, /* Cursor home */ *sc_addline, /* Add line, scroll down following lines */ *sc_lower_left, /* Cursor to last line, first column */ + *sc_return, /* Cursor to beginning of current line */ *sc_move, /* General cursor positioning */ *sc_clear, /* Clear screen */ *sc_eol_clear, /* Clear to end of line */ @@ -228,13 +229,14 @@ extern int no_back_scroll; extern int swindow; extern int no_init; extern int quit_at_eof; -extern int more_mode; +extern int less_is_more; extern int no_keypad; extern int sigs; extern int wscroll; extern int screen_trashed; extern int tty; extern int top_scroll; +extern int oldbot; #if HILITE_SEARCH extern int hilite_search; #endif @@ -1130,7 +1132,7 @@ get_term() if ((term = lgetenv("TERM")) == NULL) term = DEFAULT_TERM; hardcopy = 0; - if (tgetent(termbuf, term) <= 0) + if (tgetent(termbuf, term) != TGETENT_OK) hardcopy = 1; if (ltgetflag("hc")) hardcopy = 1; @@ -1196,7 +1198,7 @@ get_term() * that switch to/from an alternate screen, and we're in quit_at_eof * (eg, more(1)). */ - if (!quit_at_eof && !more_mode) { + if (!quit_at_eof && !less_is_more) { sc_init = ltgetstr("ti", &sp); sc_deinit = ltgetstr("te", &sp); } @@ -1293,6 +1295,13 @@ get_term() } sc_lower_left = cheaper(t1, t2, "\r"); + /* + * Get carriage return string. + */ + sc_return = ltgetstr("cr", &sp); + if (sc_return == NULL) + sc_return = "\r"; + /* * Choose between using "al" or "sr" ("add line" or "scroll reverse") * to add a line at the top of the screen. @@ -1811,6 +1820,33 @@ lower_left() #endif } +/* + * Move cursor to left position of current line. + */ + public void +line_left() +{ +#if !MSDOS_COMPILER + tputs(sc_return, 1, putchr); +#else + int row; + flush(); +#if MSDOS_COMPILER==WIN32C + { + CONSOLE_SCREEN_BUFFER_INFO scr; + GetConsoleScreenBufferInfo(con_out, &scr); + row = scr.dwCursorPosition.Y - scr.srWindow.Top + 1; + } +#else + { + struct rccoord tpos = _gettextposition(); + row = tpos.row; + } +#endif + _settextposition(row, 1); +#endif +} + /* * Check if the console size has changed and reset internals * (in lieu of SIGWINCH for WIN32). @@ -2119,7 +2155,11 @@ clear_bot() * the mode while we do the clear. Some terminals fill the * cleared area with the current attribute. */ - lower_left(); + if (oldbot) + lower_left(); + else + line_left(); + if (attrmode == AT_NORMAL) clear_eol_bot(); else @@ -2196,7 +2236,10 @@ at_exit() at_switch(attr) int attr; { - if (apply_at_specials(attr) != attrmode) + int new_attrmode = apply_at_specials(attr); + int ignore_modes = AT_ANSI; + + if ((new_attrmode & ~ignore_modes) != (attrmode & ~ignore_modes)) { at_exit(); at_enter(attr); diff --git a/contrib/less/search.c b/contrib/less/search.c index 63e58751570e..ccc07bd7e29c 100644 --- a/contrib/less/search.c +++ b/contrib/less/search.c @@ -1,6 +1,6 @@ /* $FreeBSD$ */ /* - * Copyright (C) 1984-2005 Mark Nudelman + * Copyright (C) 1984-2007 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. @@ -23,7 +23,7 @@ #if HAVE_POSIX_REGCOMP #include #ifdef REG_EXTENDED -#define REGCOMP_FLAG (more_mode ? 0 : REG_EXTENDED) +#define REGCOMP_FLAG (less_is_more ? 0 : REG_EXTENDED) #else #define REGCOMP_FLAG 0 #endif @@ -53,9 +53,10 @@ extern int linenums; extern int sc_height; extern int jump_sline; extern int bs_mode; -extern int more_mode; +extern int less_is_more; extern int ctldisp; extern int status_col; +extern void * constant ml_search; extern POSITION start_attnpos; extern POSITION end_attnpos; #if HILITE_SEARCH @@ -65,6 +66,7 @@ extern int size_linebuf; extern int squished; extern int can_goto_line; static int hide_hilite; +static int oldbot; static POSITION prep_startpos; static POSITION prep_endpos; @@ -112,15 +114,22 @@ static char *last_pattern = NULL; #define CVT_ANSI 010 /* Remove ANSI escape sequences */ static void -cvt_text(odst, osrc, ops) +cvt_text(odst, osrc, lenp, ops) char *odst; char *osrc; + int *lenp; int ops; { register char *dst; register char *src; + register char *src_end; - for (src = osrc, dst = odst; *src != '\0'; src++) + if (lenp != NULL) + src_end = osrc + *lenp; + else + src_end = osrc + strlen(osrc); + + for (src = osrc, dst = odst; src < src_end; src++) { if ((ops & CVT_TO_LC) && IS_UPPER(*src)) /* Convert uppercase to lowercase. */ @@ -131,7 +140,7 @@ cvt_text(odst, osrc, ops) else if ((ops & CVT_ANSI) && *src == ESC) { /* Skip to end of ANSI escape sequence. */ - while (src[1] != '\0') + while (src + 1 != src_end) if (!is_ansi_middle(*++src)) break; } else @@ -141,6 +150,8 @@ cvt_text(odst, osrc, ops) if ((ops & CVT_CRLF) && dst > odst && dst[-1] == '\r') dst--; *dst = '\0'; + if (lenp != NULL) + *lenp = dst - odst; } /* @@ -267,6 +278,8 @@ repaint_hilite(on) put_line(); } } + if (!oldbot) + lower_left(); hide_hilite = save_hide_hilite; } @@ -450,8 +463,9 @@ uncompile_pattern() * Set sp and ep to the start and end of the matched string. */ static int -match_pattern(line, sp, ep, notbol) +match_pattern(line, line_len, sp, ep, notbol) char *line; + int line_len; char **sp; char **ep; int notbol; @@ -459,7 +473,7 @@ match_pattern(line, sp, ep, notbol) int matched; if (last_search_type & SRCH_NO_REGEX) - return (match(last_pattern, line, sp, ep)); + return (match(last_pattern, strlen(last_pattern), line, line_len, sp, ep)); #if HAVE_POSIX_REGCOMP { @@ -481,7 +495,7 @@ match_pattern(line, sp, ep, notbol) { int flags = (notbol) ? PCRE_NOTBOL : 0; int ovector[3]; - matched = pcre_exec(regpattern, NULL, line, strlen(line), + matched = pcre_exec(regpattern, NULL, line, line_len, 0, flags, ovector, 3) >= 0; if (!matched) return (0); @@ -515,7 +529,7 @@ match_pattern(line, sp, ep, notbol) *ep = regpattern->endp[0]; #endif #if NO_REGEX - matched = match(last_pattern, line, sp, ep); + matched = match(last_pattern, strlen(last_pattern), line, line_len, sp, ep); #endif return (matched); } @@ -652,11 +666,14 @@ add_hilite(anchor, hl) } static void -adj_hilite_ansi(cvt_ops, line, npos) +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 (**line == ESC) { @@ -666,7 +683,7 @@ adj_hilite_ansi(cvt_ops, line, npos) */ (*line)++; (*npos)++; - while (**line != '\0') + while (*line < line_end) { (*npos)++; if (!is_ansi_middle(*(*line)++)) @@ -685,6 +702,8 @@ adj_hilite(anchor, linepos, cvt_ops) int cvt_ops; { char *line; + int line_len; + char *line_end; struct hilite *hl; int checkstart; POSITION opos; @@ -697,7 +716,8 @@ adj_hilite(anchor, linepos, cvt_ops) * This may not be true if there are backspaces in the line. * Get the raw line again. Look at each character. */ - (void) forw_raw_line(linepos, &line); + (void) forw_raw_line(linepos, &line, &line_len); + line_end = line + line_len; opos = npos = linepos; hl = anchor->hl_first; checkstart = TRUE; @@ -722,9 +742,9 @@ adj_hilite(anchor, linepos, cvt_ops) hl = hl->hl_next; continue; /* {{ necessary }} */ } - if (*line == '\0') + if (line == line_end) break; - adj_hilite_ansi(cvt_ops, &line, &npos); + adj_hilite_ansi(cvt_ops, &line, line_end - line, &npos); opos++; npos++; line++; @@ -734,8 +754,8 @@ adj_hilite(anchor, linepos, cvt_ops) { npos++; line++; - adj_hilite_ansi(cvt_ops, &line, &npos); - if (*line == '\0') + adj_hilite_ansi(cvt_ops, &line, line_end - line, &npos); + if (line == line_end) { --npos; --line; @@ -759,14 +779,16 @@ adj_hilite(anchor, linepos, cvt_ops) * sp,ep delimit the first match already found. */ static void -hilite_line(linepos, line, sp, ep, cvt_ops) +hilite_line(linepos, line, line_len, sp, ep, cvt_ops) POSITION linepos; char *line; + int line_len; char *sp; char *ep; int cvt_ops; { char *searchp; + char *line_end = line + line_len; struct hilite *hl; struct hilite hilites; @@ -780,7 +802,7 @@ hilite_line(linepos, line, sp, ep, cvt_ops) * substrings of the line, may mark more than is correct * if the pattern starts with "^". This bug is fixed * for those regex functions that accept a notbol parameter - * (currently POSIX and V8-with-regexec2). }} + * (currently POSIX, PCRE and V8-with-regexec2). }} */ searchp = line; /* @@ -807,11 +829,11 @@ hilite_line(linepos, line, sp, ep, cvt_ops) */ if (ep > searchp) searchp = ep; - else if (*searchp != '\0') + else if (searchp != line_end) searchp++; else /* end of line */ break; - } while (match_pattern(searchp, &sp, &ep, 1)); + } while (match_pattern(searchp, line_end - searchp, &sp, &ep, 1)); /* * If there were backspaces in the original line, they @@ -942,7 +964,7 @@ search_pos(search_type) pos = position(linenum); if (search_type & SRCH_FORW) { - pos = forw_raw_line(pos, (char **)NULL); + pos = forw_raw_line(pos, (char **)NULL, (int *)NULL); while (pos == NULL_POSITION) { if (++linenum >= sc_height) @@ -976,6 +998,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos) POSITION *pendpos; { char *line; + int line_len; LINENUM linenum; char *sp, *ep; int line_match; @@ -1018,7 +1041,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos) * starting position of that line in linepos. */ linepos = pos; - pos = forw_raw_line(pos, &line); + pos = forw_raw_line(pos, &line, &line_len); if (linenum != 0) linenum++; } else @@ -1027,7 +1050,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos) * Read the previous line and save the * starting position of that line in linepos. */ - pos = back_raw_line(pos, &line); + pos = back_raw_line(pos, &line, &line_len); linepos = pos; if (linenum != 0) linenum--; @@ -1060,14 +1083,14 @@ 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, cvt_ops); + cvt_text(line, 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, &sp, &ep, 0); + line_match = match_pattern(line, line_len, &sp, &ep, 0); line_match = (!(search_type & SRCH_NO_MATCH) && line_match) || ((search_type & SRCH_NO_MATCH) && !line_match); if (!line_match) @@ -1084,7 +1107,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos) * hilite list and keep searching. */ if (line_match) - hilite_line(linepos, line, sp, ep, cvt_ops); + hilite_line(linepos, line, line_len, sp, ep, cvt_ops); #endif } else if (--matches <= 0) { @@ -1101,7 +1124,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos) */ clr_hilite(); if (line_match) - hilite_line(linepos, line, sp, ep, cvt_ops); + hilite_line(linepos, line, line_len, sp, ep, cvt_ops); } #endif if (plinepos != NULL) @@ -1111,6 +1134,44 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos) } } + /* + * search for a pattern in history. If found, compile that pattern. + */ + static int +hist_pattern(search_type) + int search_type; +{ +#if CMD_HISTORY + char *pattern; + + set_mlist(ml_search, 0); + pattern = cmd_lastpattern(); + 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); + + is_ucase_pattern = is_ucase(pattern); + if (is_ucase_pattern && caseless != OPT_ONPLUS) + is_caseless = 0; + else + is_caseless = caseless; + +#if HILITE_SEARCH + if (hilite_search == OPT_ONPLUS && !hide_hilite) + hilite_screen(); +#endif + + return (1); +#else /* CMD_HISTORY */ + return (0); +#endif /* CMD_HISTORY */ +} + /* * Search for the n-th occurrence of a specified pattern, * either forward or backward. @@ -1134,7 +1195,7 @@ search(search_type, pattern, n) /* * A null pattern means use the previously compiled pattern. */ - if (!prev_pattern()) + if (!prev_pattern() && !hist_pattern(search_type)) { error("No previous regular expression", NULL_PARG); return (-1); @@ -1172,7 +1233,7 @@ search(search_type, pattern, n) */ ucase = is_ucase(pattern); if (caseless == OPT_ONPLUS) - cvt_text(pattern, pattern, CVT_TO_LC); + cvt_text(pattern, pattern, (int *)NULL, CVT_TO_LC); if (compile_pattern(pattern, search_type) < 0) return (-1); /* @@ -1300,7 +1361,7 @@ prep_hilite(spos, epos, maxlines) { max_epos = spos; for (i = 0; i < maxlines; i++) - max_epos = forw_raw_line(max_epos, (char **)NULL); + max_epos = forw_raw_line(max_epos, (char **)NULL, (int *)NULL); } /* @@ -1396,18 +1457,23 @@ prep_hilite(spos, epos, maxlines) * It supports no metacharacters like *, etc. */ static int -match(pattern, buf, pfound, pend) - char *pattern, *buf; +match(pattern, pattern_len, buf, buf_len, pfound, pend) + char *pattern; + int pattern_len; + char *buf; + int buf_len; char **pfound, **pend; { register char *pp, *lp; + register char *pattern_end = pattern + pattern_len; + register char *buf_end = buf + buf_len; - for ( ; *buf != '\0'; buf++) + for ( ; buf < buf_end; buf++) { for (pp = pattern, lp = buf; *pp == *lp; pp++, lp++) - if (*pp == '\0' || *lp == '\0') + if (pp == pattern_end || lp == buf_end) break; - if (*pp == '\0') + if (pp == pattern_end) { if (pfound != NULL) *pfound = buf; diff --git a/contrib/less/signal.c b/contrib/less/signal.c index 8b0691f01624..26dcadddc568 100644 --- a/contrib/less/signal.c +++ b/contrib/less/signal.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2004 Mark Nudelman + * Copyright (C) 1984-2007 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. @@ -35,7 +35,8 @@ extern int linenums; extern int wscroll; extern int reading; extern int quit_on_intr; -extern int more_mode; +extern int less_is_more; +extern long jump_sline_fraction; /* * Interrupt signal handler. @@ -59,7 +60,7 @@ u_interrupt(type) if (kbhit()) getkey(); #endif - if (more_mode) + if (less_is_more) quit(0); if (reading) intread(); @@ -92,8 +93,6 @@ winch(type) { LSIGNAL(SIGWINCH, winch); sigs |= S_WINCH; - if (reading) - intread(); } #else #ifdef SIGWIND @@ -157,13 +156,12 @@ init_signals(on) #endif #ifdef SIGWINCH (void) LSIGNAL(SIGWINCH, winch); -#else +#endif #ifdef SIGWIND (void) LSIGNAL(SIGWIND, winch); #endif #ifdef SIGQUIT (void) LSIGNAL(SIGQUIT, SIG_IGN); -#endif #endif } else { @@ -246,6 +244,7 @@ psignals() if (sc_width != old_width || sc_height != old_height) { wscroll = (sc_height + 1) / 2; + calc_jump_sline(); screen_trashed = 1; } }