search.c (161478) | search.c (170259) |
---|---|
1/* $FreeBSD: head/contrib/less/search.c 161478 2006-08-20 15:50:51Z delphij $ */ | 1/* $FreeBSD: head/contrib/less/search.c 170259 2007-06-04 01:43:11Z delphij $ */ |
2/* | 2/* |
3 * Copyright (C) 1984-2005 Mark Nudelman | 3 * Copyright (C) 1984-2007 Mark Nudelman |
4 * 5 * You may distribute under the terms of either the GNU General Public 6 * License or the Less License, as specified in the README file. 7 * 8 * For more information about less, or for information on how to 9 * contact the author, see the README file. 10 */ 11 --- 6 unchanged lines hidden (view full) --- 18#include "position.h" 19 20#define MINPOS(a,b) (((a) < (b)) ? (a) : (b)) 21#define MAXPOS(a,b) (((a) > (b)) ? (a) : (b)) 22 23#if HAVE_POSIX_REGCOMP 24#include <regex.h> 25#ifdef REG_EXTENDED | 4 * 5 * You may distribute under the terms of either the GNU General Public 6 * License or the Less License, as specified in the README file. 7 * 8 * For more information about less, or for information on how to 9 * contact the author, see the README file. 10 */ 11 --- 6 unchanged lines hidden (view full) --- 18#include "position.h" 19 20#define MINPOS(a,b) (((a) < (b)) ? (a) : (b)) 21#define MAXPOS(a,b) (((a) > (b)) ? (a) : (b)) 22 23#if HAVE_POSIX_REGCOMP 24#include <regex.h> 25#ifdef REG_EXTENDED |
26#define REGCOMP_FLAG (more_mode ? 0 : REG_EXTENDED) | 26#define REGCOMP_FLAG (less_is_more ? 0 : REG_EXTENDED) |
27#else 28#define REGCOMP_FLAG 0 29#endif 30#endif 31#if HAVE_PCRE 32#include <pcre.h> 33#endif 34#if HAVE_RE_COMP --- 13 unchanged lines hidden (view full) --- 48 49extern int sigs; 50extern int how_search; 51extern int caseless; 52extern int linenums; 53extern int sc_height; 54extern int jump_sline; 55extern int bs_mode; | 27#else 28#define REGCOMP_FLAG 0 29#endif 30#endif 31#if HAVE_PCRE 32#include <pcre.h> 33#endif 34#if HAVE_RE_COMP --- 13 unchanged lines hidden (view full) --- 48 49extern int sigs; 50extern int how_search; 51extern int caseless; 52extern int linenums; 53extern int sc_height; 54extern int jump_sline; 55extern int bs_mode; |
56extern int more_mode; | 56extern int less_is_more; |
57extern int ctldisp; 58extern int status_col; | 57extern int ctldisp; 58extern int status_col; |
59extern void * constant ml_search; |
|
59extern POSITION start_attnpos; 60extern POSITION end_attnpos; 61#if HILITE_SEARCH 62extern int hilite_search; 63extern int screen_trashed; 64extern int size_linebuf; 65extern int squished; 66extern int can_goto_line; 67static int hide_hilite; | 60extern POSITION start_attnpos; 61extern POSITION end_attnpos; 62#if HILITE_SEARCH 63extern int hilite_search; 64extern int screen_trashed; 65extern int size_linebuf; 66extern int squished; 67extern int can_goto_line; 68static int hide_hilite; |
69static int oldbot; |
|
68static POSITION prep_startpos; 69static POSITION prep_endpos; 70 71struct hilite 72{ 73 struct hilite *hl_next; 74 POSITION hl_startpos; 75 POSITION hl_endpos; --- 31 unchanged lines hidden (view full) --- 107 * Convert text. Perform one or more of these transformations: 108 */ 109#define CVT_TO_LC 01 /* Convert upper-case to lower-case */ 110#define CVT_BS 02 /* Do backspace processing */ 111#define CVT_CRLF 04 /* Remove CR after LF */ 112#define CVT_ANSI 010 /* Remove ANSI escape sequences */ 113 114 static void | 70static POSITION prep_startpos; 71static POSITION prep_endpos; 72 73struct hilite 74{ 75 struct hilite *hl_next; 76 POSITION hl_startpos; 77 POSITION hl_endpos; --- 31 unchanged lines hidden (view full) --- 109 * Convert text. Perform one or more of these transformations: 110 */ 111#define CVT_TO_LC 01 /* Convert upper-case to lower-case */ 112#define CVT_BS 02 /* Do backspace processing */ 113#define CVT_CRLF 04 /* Remove CR after LF */ 114#define CVT_ANSI 010 /* Remove ANSI escape sequences */ 115 116 static void |
115cvt_text(odst, osrc, ops) | 117cvt_text(odst, osrc, lenp, ops) |
116 char *odst; 117 char *osrc; | 118 char *odst; 119 char *osrc; |
120 int *lenp; |
|
118 int ops; 119{ 120 register char *dst; 121 register char *src; | 121 int ops; 122{ 123 register char *dst; 124 register char *src; |
125 register char *src_end; |
|
122 | 126 |
123 for (src = osrc, dst = odst; *src != '\0'; src++) | 127 if (lenp != NULL) 128 src_end = osrc + *lenp; 129 else 130 src_end = osrc + strlen(osrc); 131 132 for (src = osrc, dst = odst; src < src_end; src++) |
124 { 125 if ((ops & CVT_TO_LC) && IS_UPPER(*src)) 126 /* Convert uppercase to lowercase. */ 127 *dst++ = TO_LOWER(*src); 128 else if ((ops & CVT_BS) && *src == '\b' && dst > odst) 129 /* Delete BS and preceding char. */ 130 dst--; 131 else if ((ops & CVT_ANSI) && *src == ESC) 132 { 133 /* Skip to end of ANSI escape sequence. */ | 133 { 134 if ((ops & CVT_TO_LC) && IS_UPPER(*src)) 135 /* Convert uppercase to lowercase. */ 136 *dst++ = TO_LOWER(*src); 137 else if ((ops & CVT_BS) && *src == '\b' && dst > odst) 138 /* Delete BS and preceding char. */ 139 dst--; 140 else if ((ops & CVT_ANSI) && *src == ESC) 141 { 142 /* Skip to end of ANSI escape sequence. */ |
134 while (src[1] != '\0') | 143 while (src + 1 != src_end) |
135 if (!is_ansi_middle(*++src)) 136 break; 137 } else 138 /* Just copy. */ 139 *dst++ = *src; 140 } 141 if ((ops & CVT_CRLF) && dst > odst && dst[-1] == '\r') 142 dst--; 143 *dst = '\0'; | 144 if (!is_ansi_middle(*++src)) 145 break; 146 } else 147 /* Just copy. */ 148 *dst++ = *src; 149 } 150 if ((ops & CVT_CRLF) && dst > odst && dst[-1] == '\r') 151 dst--; 152 *dst = '\0'; |
153 if (lenp != NULL) 154 *lenp = dst - odst; |
|
144} 145 146/* 147 * Determine which conversions to perform. 148 */ 149 static int 150get_cvt_ops() 151{ --- 110 unchanged lines hidden (view full) --- 262 if (is_hilited(pos, epos, 1, NULL)) 263#endif 264 { 265 (void) forw_line(pos); 266 goto_line(slinenum); 267 put_line(); 268 } 269 } | 155} 156 157/* 158 * Determine which conversions to perform. 159 */ 160 static int 161get_cvt_ops() 162{ --- 110 unchanged lines hidden (view full) --- 273 if (is_hilited(pos, epos, 1, NULL)) 274#endif 275 { 276 (void) forw_line(pos); 277 goto_line(slinenum); 278 put_line(); 279 } 280 } |
281 if (!oldbot) 282 lower_left(); |
|
270 hide_hilite = save_hide_hilite; 271} 272 273/* 274 * Clear the attn hilite. 275 */ 276 public void 277clear_attn() --- 167 unchanged lines hidden (view full) --- 445 last_pattern = NULL; 446} 447 448/* 449 * Perform a pattern match with the previously compiled pattern. 450 * Set sp and ep to the start and end of the matched string. 451 */ 452 static int | 283 hide_hilite = save_hide_hilite; 284} 285 286/* 287 * Clear the attn hilite. 288 */ 289 public void 290clear_attn() --- 167 unchanged lines hidden (view full) --- 458 last_pattern = NULL; 459} 460 461/* 462 * Perform a pattern match with the previously compiled pattern. 463 * Set sp and ep to the start and end of the matched string. 464 */ 465 static int |
453match_pattern(line, sp, ep, notbol) | 466match_pattern(line, line_len, sp, ep, notbol) |
454 char *line; | 467 char *line; |
468 int line_len; |
|
455 char **sp; 456 char **ep; 457 int notbol; 458{ 459 int matched; 460 461 if (last_search_type & SRCH_NO_REGEX) | 469 char **sp; 470 char **ep; 471 int notbol; 472{ 473 int matched; 474 475 if (last_search_type & SRCH_NO_REGEX) |
462 return (match(last_pattern, line, sp, ep)); | 476 return (match(last_pattern, strlen(last_pattern), line, line_len, sp, ep)); |
463 464#if HAVE_POSIX_REGCOMP 465 { 466 regmatch_t rm; 467 int flags = (notbol) ? REG_NOTBOL : 0; 468 matched = !regexec(regpattern, line, 1, &rm, flags); 469 if (!matched) 470 return (0); --- 5 unchanged lines hidden (view full) --- 476 *ep = rm.rm_ep; 477#endif 478 } 479#endif 480#if HAVE_PCRE 481 { 482 int flags = (notbol) ? PCRE_NOTBOL : 0; 483 int ovector[3]; | 477 478#if HAVE_POSIX_REGCOMP 479 { 480 regmatch_t rm; 481 int flags = (notbol) ? REG_NOTBOL : 0; 482 matched = !regexec(regpattern, line, 1, &rm, flags); 483 if (!matched) 484 return (0); --- 5 unchanged lines hidden (view full) --- 490 *ep = rm.rm_ep; 491#endif 492 } 493#endif 494#if HAVE_PCRE 495 { 496 int flags = (notbol) ? PCRE_NOTBOL : 0; 497 int ovector[3]; |
484 matched = pcre_exec(regpattern, NULL, line, strlen(line), | 498 matched = pcre_exec(regpattern, NULL, line, line_len, |
485 0, flags, ovector, 3) >= 0; 486 if (!matched) 487 return (0); 488 *sp = line + ovector[0]; 489 *ep = line + ovector[1]; 490 } 491#endif 492#if HAVE_RE_COMP --- 17 unchanged lines hidden (view full) --- 510 matched = regexec(regpattern, line); 511#endif 512 if (!matched) 513 return (0); 514 *sp = regpattern->startp[0]; 515 *ep = regpattern->endp[0]; 516#endif 517#if NO_REGEX | 499 0, flags, ovector, 3) >= 0; 500 if (!matched) 501 return (0); 502 *sp = line + ovector[0]; 503 *ep = line + ovector[1]; 504 } 505#endif 506#if HAVE_RE_COMP --- 17 unchanged lines hidden (view full) --- 524 matched = regexec(regpattern, line); 525#endif 526 if (!matched) 527 return (0); 528 *sp = regpattern->startp[0]; 529 *ep = regpattern->endp[0]; 530#endif 531#if NO_REGEX |
518 matched = match(last_pattern, line, sp, ep); | 532 matched = match(last_pattern, strlen(last_pattern), line, line_len, sp, ep); |
519#endif 520 return (matched); 521} 522 523#if HILITE_SEARCH 524/* 525 * Clear the hilite list. 526 */ --- 120 unchanged lines hidden (view full) --- 647 free(hl); 648 return; 649 } 650 hl->hl_next = ihl->hl_next; 651 ihl->hl_next = hl; 652} 653 654 static void | 533#endif 534 return (matched); 535} 536 537#if HILITE_SEARCH 538/* 539 * Clear the hilite list. 540 */ --- 120 unchanged lines hidden (view full) --- 661 free(hl); 662 return; 663 } 664 hl->hl_next = ihl->hl_next; 665 ihl->hl_next = hl; 666} 667 668 static void |
655adj_hilite_ansi(cvt_ops, line, npos) | 669adj_hilite_ansi(cvt_ops, line, line_len, npos) |
656 int cvt_ops; 657 char **line; | 670 int cvt_ops; 671 char **line; |
672 int line_len; |
|
658 POSITION *npos; 659{ | 673 POSITION *npos; 674{ |
675 char *line_end = *line + line_len; 676 |
|
660 if (cvt_ops & CVT_ANSI) 661 while (**line == ESC) 662 { 663 /* 664 * Found an ESC. The file position moves 665 * forward past the entire ANSI escape sequence. 666 */ 667 (*line)++; 668 (*npos)++; | 677 if (cvt_ops & CVT_ANSI) 678 while (**line == ESC) 679 { 680 /* 681 * Found an ESC. The file position moves 682 * forward past the entire ANSI escape sequence. 683 */ 684 (*line)++; 685 (*npos)++; |
669 while (**line != '\0') | 686 while (*line < line_end) |
670 { 671 (*npos)++; 672 if (!is_ansi_middle(*(*line)++)) 673 break; 674 } 675 } 676} 677 678/* 679 * Adjust hl_startpos & hl_endpos to account for backspace processing. 680 */ 681 static void 682adj_hilite(anchor, linepos, cvt_ops) 683 struct hilite *anchor; 684 POSITION linepos; 685 int cvt_ops; 686{ 687 char *line; | 687 { 688 (*npos)++; 689 if (!is_ansi_middle(*(*line)++)) 690 break; 691 } 692 } 693} 694 695/* 696 * Adjust hl_startpos & hl_endpos to account for backspace processing. 697 */ 698 static void 699adj_hilite(anchor, linepos, cvt_ops) 700 struct hilite *anchor; 701 POSITION linepos; 702 int cvt_ops; 703{ 704 char *line; |
705 int line_len; 706 char *line_end; |
|
688 struct hilite *hl; 689 int checkstart; 690 POSITION opos; 691 POSITION npos; 692 693 /* 694 * The line was already scanned and hilites were added (in hilite_line). 695 * But it was assumed that each char position in the line 696 * correponds to one char position in the file. 697 * This may not be true if there are backspaces in the line. 698 * Get the raw line again. Look at each character. 699 */ | 707 struct hilite *hl; 708 int checkstart; 709 POSITION opos; 710 POSITION npos; 711 712 /* 713 * The line was already scanned and hilites were added (in hilite_line). 714 * But it was assumed that each char position in the line 715 * correponds to one char position in the file. 716 * This may not be true if there are backspaces in the line. 717 * Get the raw line again. Look at each character. 718 */ |
700 (void) forw_raw_line(linepos, &line); | 719 (void) forw_raw_line(linepos, &line, &line_len); 720 line_end = line + line_len; |
701 opos = npos = linepos; 702 hl = anchor->hl_first; 703 checkstart = TRUE; 704 while (hl != NULL) 705 { 706 /* 707 * See if we need to adjust the current hl_startpos or 708 * hl_endpos. After adjusting startpos[i], move to endpos[i]. --- 8 unchanged lines hidden (view full) --- 717 continue; /* {{ not really necessary }} */ 718 } else if (!checkstart && hl->hl_endpos == opos) 719 { 720 hl->hl_endpos = npos; 721 checkstart = TRUE; 722 hl = hl->hl_next; 723 continue; /* {{ necessary }} */ 724 } | 721 opos = npos = linepos; 722 hl = anchor->hl_first; 723 checkstart = TRUE; 724 while (hl != NULL) 725 { 726 /* 727 * See if we need to adjust the current hl_startpos or 728 * hl_endpos. After adjusting startpos[i], move to endpos[i]. --- 8 unchanged lines hidden (view full) --- 737 continue; /* {{ not really necessary }} */ 738 } else if (!checkstart && hl->hl_endpos == opos) 739 { 740 hl->hl_endpos = npos; 741 checkstart = TRUE; 742 hl = hl->hl_next; 743 continue; /* {{ necessary }} */ 744 } |
725 if (*line == '\0') | 745 if (line == line_end) |
726 break; | 746 break; |
727 adj_hilite_ansi(cvt_ops, &line, &npos); | 747 adj_hilite_ansi(cvt_ops, &line, line_end - line, &npos); |
728 opos++; 729 npos++; 730 line++; 731 if (cvt_ops & CVT_BS) 732 { 733 while (*line == '\b') 734 { 735 npos++; 736 line++; | 748 opos++; 749 npos++; 750 line++; 751 if (cvt_ops & CVT_BS) 752 { 753 while (*line == '\b') 754 { 755 npos++; 756 line++; |
737 adj_hilite_ansi(cvt_ops, &line, &npos); 738 if (*line == '\0') | 757 adj_hilite_ansi(cvt_ops, &line, line_end - line, &npos); 758 if (line == line_end) |
739 { 740 --npos; 741 --line; 742 break; 743 } 744 /* 745 * Found a backspace. The file position moves 746 * forward by 2 relative to the processed line --- 7 unchanged lines hidden (view full) --- 754} 755 756/* 757 * Make a hilite for each string in a physical line which matches 758 * the current pattern. 759 * sp,ep delimit the first match already found. 760 */ 761 static void | 759 { 760 --npos; 761 --line; 762 break; 763 } 764 /* 765 * Found a backspace. The file position moves 766 * forward by 2 relative to the processed line --- 7 unchanged lines hidden (view full) --- 774} 775 776/* 777 * Make a hilite for each string in a physical line which matches 778 * the current pattern. 779 * sp,ep delimit the first match already found. 780 */ 781 static void |
762hilite_line(linepos, line, sp, ep, cvt_ops) | 782hilite_line(linepos, line, line_len, sp, ep, cvt_ops) |
763 POSITION linepos; 764 char *line; | 783 POSITION linepos; 784 char *line; |
785 int line_len; |
|
765 char *sp; 766 char *ep; 767 int cvt_ops; 768{ 769 char *searchp; | 786 char *sp; 787 char *ep; 788 int cvt_ops; 789{ 790 char *searchp; |
791 char *line_end = line + line_len; |
|
770 struct hilite *hl; 771 struct hilite hilites; 772 773 if (sp == NULL || ep == NULL) 774 return; 775 /* 776 * sp and ep delimit the first match in the line. 777 * Mark the corresponding file positions, then 778 * look for further matches and mark them. 779 * {{ This technique, of calling match_pattern on subsequent 780 * substrings of the line, may mark more than is correct 781 * if the pattern starts with "^". This bug is fixed 782 * for those regex functions that accept a notbol parameter | 792 struct hilite *hl; 793 struct hilite hilites; 794 795 if (sp == NULL || ep == NULL) 796 return; 797 /* 798 * sp and ep delimit the first match in the line. 799 * Mark the corresponding file positions, then 800 * look for further matches and mark them. 801 * {{ This technique, of calling match_pattern on subsequent 802 * substrings of the line, may mark more than is correct 803 * if the pattern starts with "^". This bug is fixed 804 * for those regex functions that accept a notbol parameter |
783 * (currently POSIX and V8-with-regexec2). }} | 805 * (currently POSIX, PCRE and V8-with-regexec2). }} |
784 */ 785 searchp = line; 786 /* 787 * Put the hilites into a temporary list until they're adjusted. 788 */ 789 hilites.hl_first = NULL; 790 do { 791 if (ep > sp) --- 10 unchanged lines hidden (view full) --- 802 } 803 /* 804 * If we matched more than zero characters, 805 * move to the first char after the string we matched. 806 * If we matched zero, just move to the next char. 807 */ 808 if (ep > searchp) 809 searchp = ep; | 806 */ 807 searchp = line; 808 /* 809 * Put the hilites into a temporary list until they're adjusted. 810 */ 811 hilites.hl_first = NULL; 812 do { 813 if (ep > sp) --- 10 unchanged lines hidden (view full) --- 824 } 825 /* 826 * If we matched more than zero characters, 827 * move to the first char after the string we matched. 828 * If we matched zero, just move to the next char. 829 */ 830 if (ep > searchp) 831 searchp = ep; |
810 else if (*searchp != '\0') | 832 else if (searchp != line_end) |
811 searchp++; 812 else /* end of line */ 813 break; | 833 searchp++; 834 else /* end of line */ 835 break; |
814 } while (match_pattern(searchp, &sp, &ep, 1)); | 836 } while (match_pattern(searchp, line_end - searchp, &sp, &ep, 1)); |
815 816 /* 817 * If there were backspaces in the original line, they 818 * were removed, and hl_startpos/hl_endpos are not correct. 819 * {{ This is very ugly. }} 820 */ 821 adj_hilite(&hilites, linepos, cvt_ops); 822 --- 114 unchanged lines hidden (view full) --- 937 * Search includes current screen. 938 * It starts at the jump target (if searching backwards), 939 * or at the jump target plus one (if forwards). 940 */ 941 linenum = adjsline(jump_sline); 942 pos = position(linenum); 943 if (search_type & SRCH_FORW) 944 { | 837 838 /* 839 * If there were backspaces in the original line, they 840 * were removed, and hl_startpos/hl_endpos are not correct. 841 * {{ This is very ugly. }} 842 */ 843 adj_hilite(&hilites, linepos, cvt_ops); 844 --- 114 unchanged lines hidden (view full) --- 959 * Search includes current screen. 960 * It starts at the jump target (if searching backwards), 961 * or at the jump target plus one (if forwards). 962 */ 963 linenum = adjsline(jump_sline); 964 pos = position(linenum); 965 if (search_type & SRCH_FORW) 966 { |
945 pos = forw_raw_line(pos, (char **)NULL); | 967 pos = forw_raw_line(pos, (char **)NULL, (int *)NULL); |
946 while (pos == NULL_POSITION) 947 { 948 if (++linenum >= sc_height) 949 break; 950 pos = position(linenum); 951 } 952 } else 953 { --- 17 unchanged lines hidden (view full) --- 971 POSITION endpos; 972 int search_type; 973 int matches; 974 int maxlines; 975 POSITION *plinepos; 976 POSITION *pendpos; 977{ 978 char *line; | 968 while (pos == NULL_POSITION) 969 { 970 if (++linenum >= sc_height) 971 break; 972 pos = position(linenum); 973 } 974 } else 975 { --- 17 unchanged lines hidden (view full) --- 993 POSITION endpos; 994 int search_type; 995 int matches; 996 int maxlines; 997 POSITION *plinepos; 998 POSITION *pendpos; 999{ 1000 char *line; |
1001 int line_len; |
|
979 LINENUM linenum; 980 char *sp, *ep; 981 int line_match; 982 int cvt_ops; 983 POSITION linepos, oldpos; 984 985 linenum = find_linenum(pos); 986 oldpos = pos; --- 26 unchanged lines hidden (view full) --- 1013 1014 if (search_type & SRCH_FORW) 1015 { 1016 /* 1017 * Read the next line, and save the 1018 * starting position of that line in linepos. 1019 */ 1020 linepos = pos; | 1002 LINENUM linenum; 1003 char *sp, *ep; 1004 int line_match; 1005 int cvt_ops; 1006 POSITION linepos, oldpos; 1007 1008 linenum = find_linenum(pos); 1009 oldpos = pos; --- 26 unchanged lines hidden (view full) --- 1036 1037 if (search_type & SRCH_FORW) 1038 { 1039 /* 1040 * Read the next line, and save the 1041 * starting position of that line in linepos. 1042 */ 1043 linepos = pos; |
1021 pos = forw_raw_line(pos, &line); | 1044 pos = forw_raw_line(pos, &line, &line_len); |
1022 if (linenum != 0) 1023 linenum++; 1024 } else 1025 { 1026 /* 1027 * Read the previous line and save the 1028 * starting position of that line in linepos. 1029 */ | 1045 if (linenum != 0) 1046 linenum++; 1047 } else 1048 { 1049 /* 1050 * Read the previous line and save the 1051 * starting position of that line in linepos. 1052 */ |
1030 pos = back_raw_line(pos, &line); | 1053 pos = back_raw_line(pos, &line, &line_len); |
1031 linepos = pos; 1032 if (linenum != 0) 1033 linenum--; 1034 } 1035 1036 if (pos == NULL_POSITION) 1037 { 1038 /* --- 16 unchanged lines hidden (view full) --- 1055 add_lnum(linenum, pos); 1056 oldpos = pos; 1057 1058 /* 1059 * If it's a caseless search, convert the line to lowercase. 1060 * If we're doing backspace processing, delete backspaces. 1061 */ 1062 cvt_ops = get_cvt_ops(); | 1054 linepos = pos; 1055 if (linenum != 0) 1056 linenum--; 1057 } 1058 1059 if (pos == NULL_POSITION) 1060 { 1061 /* --- 16 unchanged lines hidden (view full) --- 1078 add_lnum(linenum, pos); 1079 oldpos = pos; 1080 1081 /* 1082 * If it's a caseless search, convert the line to lowercase. 1083 * If we're doing backspace processing, delete backspaces. 1084 */ 1085 cvt_ops = get_cvt_ops(); |
1063 cvt_text(line, line, cvt_ops); | 1086 cvt_text(line, line, &line_len, cvt_ops); |
1064 1065 /* 1066 * Test the next line to see if we have a match. 1067 * We are successful if we either want a match and got one, 1068 * or if we want a non-match and got one. 1069 */ | 1087 1088 /* 1089 * Test the next line to see if we have a match. 1090 * We are successful if we either want a match and got one, 1091 * or if we want a non-match and got one. 1092 */ |
1070 line_match = match_pattern(line, &sp, &ep, 0); | 1093 line_match = match_pattern(line, line_len, &sp, &ep, 0); |
1071 line_match = (!(search_type & SRCH_NO_MATCH) && line_match) || 1072 ((search_type & SRCH_NO_MATCH) && !line_match); 1073 if (!line_match) 1074 continue; 1075 /* 1076 * Got a match. 1077 */ 1078 if (search_type & SRCH_FIND_ALL) 1079 { 1080#if HILITE_SEARCH 1081 /* 1082 * We are supposed to find all matches in the range. 1083 * Just add the matches in this line to the 1084 * hilite list and keep searching. 1085 */ 1086 if (line_match) | 1094 line_match = (!(search_type & SRCH_NO_MATCH) && line_match) || 1095 ((search_type & SRCH_NO_MATCH) && !line_match); 1096 if (!line_match) 1097 continue; 1098 /* 1099 * Got a match. 1100 */ 1101 if (search_type & SRCH_FIND_ALL) 1102 { 1103#if HILITE_SEARCH 1104 /* 1105 * We are supposed to find all matches in the range. 1106 * Just add the matches in this line to the 1107 * hilite list and keep searching. 1108 */ 1109 if (line_match) |
1087 hilite_line(linepos, line, sp, ep, cvt_ops); | 1110 hilite_line(linepos, line, line_len, sp, ep, cvt_ops); |
1088#endif 1089 } else if (--matches <= 0) 1090 { 1091 /* 1092 * Found the one match we're looking for. 1093 * Return it. 1094 */ 1095#if HILITE_SEARCH 1096 if (hilite_search == OPT_ON) 1097 { 1098 /* 1099 * Clear the hilite list and add only 1100 * the matches in this one line. 1101 */ 1102 clr_hilite(); 1103 if (line_match) | 1111#endif 1112 } else if (--matches <= 0) 1113 { 1114 /* 1115 * Found the one match we're looking for. 1116 * Return it. 1117 */ 1118#if HILITE_SEARCH 1119 if (hilite_search == OPT_ON) 1120 { 1121 /* 1122 * Clear the hilite list and add only 1123 * the matches in this one line. 1124 */ 1125 clr_hilite(); 1126 if (line_match) |
1104 hilite_line(linepos, line, sp, ep, cvt_ops); | 1127 hilite_line(linepos, line, line_len, sp, ep, cvt_ops); |
1105 } 1106#endif 1107 if (plinepos != NULL) 1108 *plinepos = linepos; 1109 return (0); 1110 } 1111 } 1112} 1113 | 1128 } 1129#endif 1130 if (plinepos != NULL) 1131 *plinepos = linepos; 1132 return (0); 1133 } 1134 } 1135} 1136 |
1137 /* 1138 * search for a pattern in history. If found, compile that pattern. 1139 */ 1140 static int 1141hist_pattern(search_type) 1142 int search_type; 1143{ 1144#if CMD_HISTORY 1145 char *pattern; 1146 1147 set_mlist(ml_search, 0); 1148 pattern = cmd_lastpattern(); 1149 if (pattern == NULL) 1150 return (0); 1151 1152 if (caseless == OPT_ONPLUS) 1153 cvt_text(pattern, pattern, (int *)NULL, CVT_TO_LC); 1154 1155 if (compile_pattern(pattern, search_type) < 0) 1156 return (0); 1157 1158 is_ucase_pattern = is_ucase(pattern); 1159 if (is_ucase_pattern && caseless != OPT_ONPLUS) 1160 is_caseless = 0; 1161 else 1162 is_caseless = caseless; 1163 1164#if HILITE_SEARCH 1165 if (hilite_search == OPT_ONPLUS && !hide_hilite) 1166 hilite_screen(); 1167#endif 1168 1169 return (1); 1170#else /* CMD_HISTORY */ 1171 return (0); 1172#endif /* CMD_HISTORY */ 1173} 1174 |
|
1114/* 1115 * Search for the n-th occurrence of a specified pattern, 1116 * either forward or backward. 1117 * Return the number of matches not yet found in this file 1118 * (that is, n minus the number of matches found). 1119 * Return -1 if the search should be aborted. 1120 * Caller may continue the search in another file 1121 * if less than n matches are found in this file. --- 7 unchanged lines hidden (view full) --- 1129 POSITION pos; 1130 int ucase; 1131 1132 if (pattern == NULL || *pattern == '\0') 1133 { 1134 /* 1135 * A null pattern means use the previously compiled pattern. 1136 */ | 1175/* 1176 * Search for the n-th occurrence of a specified pattern, 1177 * either forward or backward. 1178 * Return the number of matches not yet found in this file 1179 * (that is, n minus the number of matches found). 1180 * Return -1 if the search should be aborted. 1181 * Caller may continue the search in another file 1182 * if less than n matches are found in this file. --- 7 unchanged lines hidden (view full) --- 1190 POSITION pos; 1191 int ucase; 1192 1193 if (pattern == NULL || *pattern == '\0') 1194 { 1195 /* 1196 * A null pattern means use the previously compiled pattern. 1197 */ |
1137 if (!prev_pattern()) | 1198 if (!prev_pattern() && !hist_pattern(search_type)) |
1138 { 1139 error("No previous regular expression", NULL_PARG); 1140 return (-1); 1141 } 1142 if ((search_type & SRCH_NO_REGEX) != 1143 (last_search_type & SRCH_NO_REGEX)) 1144 { 1145 error("Please re-enter search pattern", NULL_PARG); --- 21 unchanged lines hidden (view full) --- 1167#endif 1168 } else 1169 { 1170 /* 1171 * Compile the pattern. 1172 */ 1173 ucase = is_ucase(pattern); 1174 if (caseless == OPT_ONPLUS) | 1199 { 1200 error("No previous regular expression", NULL_PARG); 1201 return (-1); 1202 } 1203 if ((search_type & SRCH_NO_REGEX) != 1204 (last_search_type & SRCH_NO_REGEX)) 1205 { 1206 error("Please re-enter search pattern", NULL_PARG); --- 21 unchanged lines hidden (view full) --- 1228#endif 1229 } else 1230 { 1231 /* 1232 * Compile the pattern. 1233 */ 1234 ucase = is_ucase(pattern); 1235 if (caseless == OPT_ONPLUS) |
1175 cvt_text(pattern, pattern, CVT_TO_LC); | 1236 cvt_text(pattern, pattern, (int *)NULL, CVT_TO_LC); |
1176 if (compile_pattern(pattern, search_type) < 0) 1177 return (-1); 1178 /* 1179 * Ignore case if -I is set OR 1180 * -i is set AND the pattern is all lowercase. 1181 */ 1182 is_ucase_pattern = ucase; 1183 if (is_ucase_pattern && caseless != OPT_ONPLUS) --- 111 unchanged lines hidden (view full) --- 1295 * file position we should stop at. 1296 */ 1297 if (maxlines < 0) 1298 max_epos = NULL_POSITION; 1299 else 1300 { 1301 max_epos = spos; 1302 for (i = 0; i < maxlines; i++) | 1237 if (compile_pattern(pattern, search_type) < 0) 1238 return (-1); 1239 /* 1240 * Ignore case if -I is set OR 1241 * -i is set AND the pattern is all lowercase. 1242 */ 1243 is_ucase_pattern = ucase; 1244 if (is_ucase_pattern && caseless != OPT_ONPLUS) --- 111 unchanged lines hidden (view full) --- 1356 * file position we should stop at. 1357 */ 1358 if (maxlines < 0) 1359 max_epos = NULL_POSITION; 1360 else 1361 { 1362 max_epos = spos; 1363 for (i = 0; i < maxlines; i++) |
1303 max_epos = forw_raw_line(max_epos, (char **)NULL); | 1364 max_epos = forw_raw_line(max_epos, (char **)NULL, (int *)NULL); |
1304 } 1305 1306 /* 1307 * Find two ranges: 1308 * The range that we need to search (spos,epos); and the range that 1309 * the "prep" region will then cover (nprep_startpos,nprep_endpos). 1310 */ 1311 --- 79 unchanged lines hidden (view full) --- 1391} 1392#endif 1393 1394/* 1395 * Simple pattern matching function. 1396 * It supports no metacharacters like *, etc. 1397 */ 1398 static int | 1365 } 1366 1367 /* 1368 * Find two ranges: 1369 * The range that we need to search (spos,epos); and the range that 1370 * the "prep" region will then cover (nprep_startpos,nprep_endpos). 1371 */ 1372 --- 79 unchanged lines hidden (view full) --- 1452} 1453#endif 1454 1455/* 1456 * Simple pattern matching function. 1457 * It supports no metacharacters like *, etc. 1458 */ 1459 static int |
1399match(pattern, buf, pfound, pend) 1400 char *pattern, *buf; | 1460match(pattern, pattern_len, buf, buf_len, pfound, pend) 1461 char *pattern; 1462 int pattern_len; 1463 char *buf; 1464 int buf_len; |
1401 char **pfound, **pend; 1402{ 1403 register char *pp, *lp; | 1465 char **pfound, **pend; 1466{ 1467 register char *pp, *lp; |
1468 register char *pattern_end = pattern + pattern_len; 1469 register char *buf_end = buf + buf_len; |
|
1404 | 1470 |
1405 for ( ; *buf != '\0'; buf++) | 1471 for ( ; buf < buf_end; buf++) |
1406 { 1407 for (pp = pattern, lp = buf; *pp == *lp; pp++, lp++) | 1472 { 1473 for (pp = pattern, lp = buf; *pp == *lp; pp++, lp++) |
1408 if (*pp == '\0' || *lp == '\0') | 1474 if (pp == pattern_end || lp == buf_end) |
1409 break; | 1475 break; |
1410 if (*pp == '\0') | 1476 if (pp == pattern_end) |
1411 { 1412 if (pfound != NULL) 1413 *pfound = buf; 1414 if (pend != NULL) 1415 *pend = lp; 1416 return (1); 1417 } 1418 } --- 19 unchanged lines hidden --- | 1477 { 1478 if (pfound != NULL) 1479 *pfound = buf; 1480 if (pend != NULL) 1481 *pend = lp; 1482 return (1); 1483 } 1484 } --- 19 unchanged lines hidden --- |