search.c (221715) | search.c (237613) |
---|---|
1/* $FreeBSD: head/contrib/less/search.c 221715 2011-05-09 21:51:59Z delphij $ */ | 1/* $FreeBSD: head/contrib/less/search.c 237613 2012-06-26 23:17:33Z delphij $ */ |
2/* | 2/* |
3 * Copyright (C) 1984-2011 Mark Nudelman | 3 * Copyright (C) 1984-2012 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 * | 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. | 8 * For more information, see the README file. |
10 */ 11 12 13/* 14 * Routines to search a file for a pattern. 15 */ 16 17#include "less.h" --- 45 unchanged lines hidden (view full) --- 63 * These are the static variables that represent the "remembered" 64 * search pattern and filter pattern. 65 */ 66struct pattern_info { 67 DEFINE_PATTERN(compiled); 68 char* text; 69 int search_type; 70}; | 9 */ 10 11 12/* 13 * Routines to search a file for a pattern. 14 */ 15 16#include "less.h" --- 45 unchanged lines hidden (view full) --- 62 * These are the static variables that represent the "remembered" 63 * search pattern and filter pattern. 64 */ 65struct pattern_info { 66 DEFINE_PATTERN(compiled); 67 char* text; 68 int search_type; 69}; |
70 71#if NO_REGEX 72#define info_compiled(info) ((void*)0) 73#else 74#define info_compiled(info) ((info)->compiled) 75#endif |
|
71 72static struct pattern_info search_info; 73static struct pattern_info filter_info; 74 75/* 76 * Are there any uppercase letters in this string? 77 */ 78 static int --- 16 unchanged lines hidden (view full) --- 95 * Compile and save a search pattern. 96 */ 97 static int 98set_pattern(info, pattern, search_type) 99 struct pattern_info *info; 100 char *pattern; 101 int search_type; 102{ | 76 77static struct pattern_info search_info; 78static struct pattern_info filter_info; 79 80/* 81 * Are there any uppercase letters in this string? 82 */ 83 static int --- 16 unchanged lines hidden (view full) --- 100 * Compile and save a search pattern. 101 */ 102 static int 103set_pattern(info, pattern, search_type) 104 struct pattern_info *info; 105 char *pattern; 106 int search_type; 107{ |
108#if !NO_REGEX |
|
103 if (pattern == NULL) | 109 if (pattern == NULL) |
104 CLEAR_PATTERN(search_info.compiled); | 110 CLEAR_PATTERN(info->compiled); |
105 else if (compile_pattern(pattern, search_type, &info->compiled) < 0) 106 return -1; | 111 else if (compile_pattern(pattern, search_type, &info->compiled) < 0) 112 return -1; |
113#endif |
|
107 /* Pattern compiled successfully; save the text too. */ 108 if (info->text != NULL) 109 free(info->text); 110 info->text = NULL; 111 if (pattern != NULL) 112 { 113 info->text = (char *) ecalloc(1, strlen(pattern)+1); 114 strcpy(info->text, pattern); --- 17 unchanged lines hidden (view full) --- 132 */ 133 static void 134clear_pattern(info) 135 struct pattern_info *info; 136{ 137 if (info->text != NULL) 138 free(info->text); 139 info->text = NULL; | 114 /* Pattern compiled successfully; save the text too. */ 115 if (info->text != NULL) 116 free(info->text); 117 info->text = NULL; 118 if (pattern != NULL) 119 { 120 info->text = (char *) ecalloc(1, strlen(pattern)+1); 121 strcpy(info->text, pattern); --- 17 unchanged lines hidden (view full) --- 139 */ 140 static void 141clear_pattern(info) 142 struct pattern_info *info; 143{ 144 if (info->text != NULL) 145 free(info->text); 146 info->text = NULL; |
147#if !NO_REGEX |
|
140 uncompile_pattern(&info->compiled); | 148 uncompile_pattern(&info->compiled); |
149#endif |
|
141} 142 143/* 144 * Initialize saved pattern to nothing. 145 */ 146 static void 147init_pattern(info) 148 struct pattern_info *info; --- 39 unchanged lines hidden (view full) --- 188 189/* 190 * Is there a previous (remembered) search pattern? 191 */ 192 static int 193prev_pattern(info) 194 struct pattern_info *info; 195{ | 150} 151 152/* 153 * Initialize saved pattern to nothing. 154 */ 155 static void 156init_pattern(info) 157 struct pattern_info *info; --- 39 unchanged lines hidden (view full) --- 197 198/* 199 * Is there a previous (remembered) search pattern? 200 */ 201 static int 202prev_pattern(info) 203 struct pattern_info *info; 204{ |
196 if (info->search_type & SRCH_NO_REGEX) 197 return (info->text != NULL); 198 return (!is_null_pattern(info->compiled)); | 205#if !NO_REGEX 206 if ((info->search_type & SRCH_NO_REGEX) == 0) 207 return (!is_null_pattern(info->compiled)); 208#endif 209 return (info->text != NULL); |
199} 200 201#if HILITE_SEARCH 202/* 203 * Repaint the hilites currently displayed on the screen. 204 * Repaint each line which contains highlighted text. 205 * If on==0, force all hilites off. 206 */ --- 266 unchanged lines hidden (view full) --- 473 free(hl); 474 return; 475 } 476 hl->hl_next = ihl->hl_next; 477 ihl->hl_next = hl; 478} 479 480/* | 210} 211 212#if HILITE_SEARCH 213/* 214 * Repaint the hilites currently displayed on the screen. 215 * Repaint each line which contains highlighted text. 216 * If on==0, force all hilites off. 217 */ --- 266 unchanged lines hidden (view full) --- 484 free(hl); 485 return; 486 } 487 hl->hl_next = ihl->hl_next; 488 ihl->hl_next = hl; 489} 490 491/* |
492 * Hilight every character in a range of displayed characters. 493 */ 494 static void 495create_hilites(linepos, start_index, end_index, chpos) 496 POSITION linepos; 497 int start_index; 498 int end_index; 499 int *chpos; 500{ 501 struct hilite *hl; 502 int i; 503 504 /* Start the first hilite. */ 505 hl = (struct hilite *) ecalloc(1, sizeof(struct hilite)); 506 hl->hl_startpos = linepos + chpos[start_index]; 507 508 /* 509 * Step through the displayed chars. 510 * If the source position (before cvt) of the char is one more 511 * than the source pos of the previous char (the usual case), 512 * just increase the size of the current hilite by one. 513 * Otherwise (there are backspaces or something involved), 514 * finish the current hilite and start a new one. 515 */ 516 for (i = start_index+1; i <= end_index; i++) 517 { 518 if (chpos[i] != chpos[i-1] + 1 || i == end_index) 519 { 520 hl->hl_endpos = linepos + chpos[i-1] + 1; 521 add_hilite(&hilite_anchor, hl); 522 /* Start new hilite unless this is the last char. */ 523 if (i < end_index) 524 { 525 hl = (struct hilite *) ecalloc(1, sizeof(struct hilite)); 526 hl->hl_startpos = linepos + chpos[i]; 527 } 528 } 529 } 530} 531 532/* |
|
481 * Make a hilite for each string in a physical line which matches 482 * the current pattern. 483 * sp,ep delimit the first match already found. 484 */ 485 static void 486hilite_line(linepos, line, line_len, chpos, sp, ep, cvt_ops) 487 POSITION linepos; 488 char *line; 489 int line_len; 490 int *chpos; 491 char *sp; 492 char *ep; 493 int cvt_ops; 494{ 495 char *searchp; 496 char *line_end = line + line_len; | 533 * Make a hilite for each string in a physical line which matches 534 * the current pattern. 535 * sp,ep delimit the first match already found. 536 */ 537 static void 538hilite_line(linepos, line, line_len, chpos, sp, ep, cvt_ops) 539 POSITION linepos; 540 char *line; 541 int line_len; 542 int *chpos; 543 char *sp; 544 char *ep; 545 int cvt_ops; 546{ 547 char *searchp; 548 char *line_end = line + line_len; |
497 struct hilite *hl; | |
498 499 if (sp == NULL || ep == NULL) 500 return; 501 /* 502 * sp and ep delimit the first match in the line. 503 * Mark the corresponding file positions, then 504 * look for further matches and mark them. 505 * {{ This technique, of calling match_pattern on subsequent 506 * substrings of the line, may mark more than is correct 507 * if the pattern starts with "^". This bug is fixed 508 * for those regex functions that accept a notbol parameter 509 * (currently POSIX, PCRE and V8-with-regexec2). }} 510 */ 511 searchp = line; 512 do { | 549 550 if (sp == NULL || ep == NULL) 551 return; 552 /* 553 * sp and ep delimit the first match in the line. 554 * Mark the corresponding file positions, then 555 * look for further matches and mark them. 556 * {{ This technique, of calling match_pattern on subsequent 557 * substrings of the line, may mark more than is correct 558 * if the pattern starts with "^". This bug is fixed 559 * for those regex functions that accept a notbol parameter 560 * (currently POSIX, PCRE and V8-with-regexec2). }} 561 */ 562 searchp = line; 563 do { |
513 if (ep > sp) 514 { 515 hl = (struct hilite *) ecalloc(1, sizeof(struct hilite)); 516 hl->hl_startpos = linepos + chpos[sp-line]; 517 hl->hl_endpos = linepos + chpos[ep-line]; 518 add_hilite(&hilite_anchor, hl); 519 } | 564 create_hilites(linepos, sp-line, ep-line, chpos); |
520 /* 521 * If we matched more than zero characters, 522 * move to the first char after the string we matched. 523 * If we matched zero, just move to the next char. 524 */ 525 if (ep > searchp) 526 searchp = ep; 527 else if (searchp != line_end) 528 searchp++; 529 else /* end of line */ 530 break; | 565 /* 566 * If we matched more than zero characters, 567 * move to the first char after the string we matched. 568 * If we matched zero, just move to the next char. 569 */ 570 if (ep > searchp) 571 searchp = ep; 572 else if (searchp != line_end) 573 searchp++; 574 else /* end of line */ 575 break; |
531 } while (match_pattern(search_info.compiled, search_info.text, | 576 } while (match_pattern(info_compiled(&search_info), search_info.text, |
532 searchp, line_end - searchp, &sp, &ep, 1, search_info.search_type)); 533} 534#endif 535 536/* 537 * Change the caseless-ness of searches. 538 * Updates the internal search state to reflect a change in the -i flag. 539 */ --- 255 unchanged lines hidden (view full) --- 795 cvt_text(cline, line, chpos, &line_len, cvt_ops); 796 797#if HILITE_SEARCH 798 /* 799 * Check to see if the line matches the filter pattern. 800 * If so, add an entry to the filter list. 801 */ 802 if ((search_type & SRCH_FIND_ALL) && prev_pattern(&filter_info)) { | 577 searchp, line_end - searchp, &sp, &ep, 1, search_info.search_type)); 578} 579#endif 580 581/* 582 * Change the caseless-ness of searches. 583 * Updates the internal search state to reflect a change in the -i flag. 584 */ --- 255 unchanged lines hidden (view full) --- 840 cvt_text(cline, line, chpos, &line_len, cvt_ops); 841 842#if HILITE_SEARCH 843 /* 844 * Check to see if the line matches the filter pattern. 845 * If so, add an entry to the filter list. 846 */ 847 if ((search_type & SRCH_FIND_ALL) && prev_pattern(&filter_info)) { |
803 int line_filter = match_pattern(filter_info.compiled, filter_info.text, | 848 int line_filter = match_pattern(info_compiled(&filter_info), filter_info.text, |
804 cline, line_len, &sp, &ep, 0, filter_info.search_type); 805 if (line_filter) 806 { 807 struct hilite *hl = (struct hilite *) 808 ecalloc(1, sizeof(struct hilite)); 809 hl->hl_startpos = linepos; 810 hl->hl_endpos = pos; 811 add_hilite(&filter_anchor, hl); 812 } 813 } 814#endif 815 816 /* 817 * Test the next line to see if we have a match. 818 * We are successful if we either want a match and got one, 819 * or if we want a non-match and got one. 820 */ 821 if (prev_pattern(&search_info)) 822 { | 849 cline, line_len, &sp, &ep, 0, filter_info.search_type); 850 if (line_filter) 851 { 852 struct hilite *hl = (struct hilite *) 853 ecalloc(1, sizeof(struct hilite)); 854 hl->hl_startpos = linepos; 855 hl->hl_endpos = pos; 856 add_hilite(&filter_anchor, hl); 857 } 858 } 859#endif 860 861 /* 862 * Test the next line to see if we have a match. 863 * We are successful if we either want a match and got one, 864 * or if we want a non-match and got one. 865 */ 866 if (prev_pattern(&search_info)) 867 { |
823 line_match = match_pattern(search_info.compiled, search_info.text, | 868 line_match = match_pattern(info_compiled(&search_info), search_info.text, |
824 cline, line_len, &sp, &ep, 0, search_type); 825 if (line_match) 826 { 827 /* 828 * Got a match. 829 */ 830 if (search_type & SRCH_FIND_ALL) 831 { --- 382 unchanged lines hidden --- | 869 cline, line_len, &sp, &ep, 0, search_type); 870 if (line_match) 871 { 872 /* 873 * Got a match. 874 */ 875 if (search_type & SRCH_FIND_ALL) 876 { --- 382 unchanged lines hidden --- |