3 * Copyright (C) 1984-2007 Mark Nudelman
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.
8 * For more information about less, or for information on how to
9 * contact the author, see the README file.
14 * Routines to search a file for a pattern.
21 #define MINPOS(a,b) (((a) < (b)) ? (a) : (b))
22 #define MAXPOS(a,b) (((a) > (b)) ? (a) : (b))
24 #if HAVE_POSIX_REGCOMP
27 #define REGCOMP_FLAG (less_is_more ? 0 : REG_EXTENDED)
29 #define REGCOMP_FLAG 0
51 extern int how_search;
55 extern int jump_sline;
57 extern int less_is_more;
59 extern int status_col;
60 extern void * constant ml_search;
61 extern POSITION start_attnpos;
62 extern POSITION end_attnpos;
64 extern int hilite_search;
65 extern int screen_trashed;
66 extern int size_linebuf;
68 extern int can_goto_line;
69 static int hide_hilite;
71 static POSITION prep_startpos;
72 static POSITION prep_endpos;
76 struct hilite *hl_next;
80 static struct hilite hilite_anchor = { NULL, NULL_POSITION, NULL_POSITION };
81 #define hl_first hl_next
85 * These are the static variables that represent the "remembered"
88 #if HAVE_POSIX_REGCOMP
89 static regex_t *regpattern = NULL;
92 pcre *regpattern = NULL;
98 static char *cpattern = NULL;
101 static struct regexp *regpattern = NULL;
104 static int is_caseless;
105 static int is_ucase_pattern;
106 static int last_search_type;
107 static char *last_pattern = NULL;
110 * Convert text. Perform one or more of these transformations:
112 #define CVT_TO_LC 01 /* Convert upper-case to lower-case */
113 #define CVT_BS 02 /* Do backspace processing */
114 #define CVT_CRLF 04 /* Remove CR after LF */
115 #define CVT_ANSI 010 /* Remove ANSI escape sequences */
118 cvt_text(odst, osrc, lenp, ops)
126 register char *src_end;
130 src_end = osrc + *lenp;
132 src_end = osrc + strlen(osrc);
134 for (src = osrc, dst = odst; src < src_end; )
136 ch = step_char(&src, +1, src_end);
137 if ((ops & CVT_TO_LC) && IS_UPPER(ch))
139 /* Convert uppercase to lowercase. */
140 put_wchar(&dst, TO_LOWER(ch));
141 } else if ((ops & CVT_BS) && ch == '\b' && dst > odst)
143 /* Delete BS and preceding char. */
146 } while (dst > odst &&
147 !IS_ASCII_OCTET(*dst) && !IS_UTF8_LEAD(*dst));
148 } else if ((ops & CVT_ANSI) && IS_CSI_START(ch))
150 /* Skip to end of ANSI escape sequence. */
151 while (src + 1 != src_end)
152 if (!is_ansi_middle(*++src))
158 if ((ops & CVT_CRLF) && dst > odst && dst[-1] == '\r')
166 * Determine which conversions to perform.
172 if (is_caseless || bs_mode == BS_SPECIAL)
176 if (bs_mode == BS_SPECIAL)
178 if (bs_mode != BS_CONTROL)
180 } else if (bs_mode != BS_CONTROL)
184 if (ctldisp == OPT_ONPLUS)
190 * Are there any uppercase letters in this string?
196 char *str_end = str + strlen(str);
199 while (str < str_end)
201 ch = step_char(&str, +1, str_end);
209 * Is there a previous (remembered) search pattern?
214 if (last_search_type & SRCH_NO_REGEX)
215 return (last_pattern != NULL);
216 #if HAVE_POSIX_REGCOMP
217 return (regpattern != NULL);
220 return (regpattern != NULL);
223 return (re_pattern != 0);
226 return (cpattern != NULL);
229 return (regpattern != NULL);
232 return (last_pattern != NULL);
238 * Repaint the hilites currently displayed on the screen.
239 * Repaint each line which contains highlighted text.
240 * If on==0, force all hilites off.
249 int save_hide_hilite;
254 save_hide_hilite = hide_hilite;
265 hide_hilite = save_hide_hilite;
269 for (slinenum = TOP; slinenum < TOP + sc_height-1; slinenum++)
271 pos = position(slinenum);
272 if (pos == NULL_POSITION)
274 epos = position(slinenum+1);
277 * If any character in the line is highlighted,
280 * {{ This doesn't work -- if line is drawn with highlights
281 * which should be erased (e.g. toggle -i with status column),
282 * we must redraw the line even if it has no highlights.
283 * For now, just repaint every line. }}
285 if (is_hilited(pos, epos, 1, NULL))
288 (void) forw_line(pos);
295 hide_hilite = save_hide_hilite;
299 * Clear the attn hilite.
305 POSITION old_start_attnpos;
306 POSITION old_end_attnpos;
311 if (start_attnpos == NULL_POSITION)
313 old_start_attnpos = start_attnpos;
314 old_end_attnpos = end_attnpos;
315 start_attnpos = end_attnpos = NULL_POSITION;
325 for (slinenum = TOP; slinenum < TOP + sc_height-1; slinenum++)
327 pos = position(slinenum);
328 if (pos == NULL_POSITION)
330 epos = position(slinenum+1);
331 if (pos < old_end_attnpos &&
332 (epos == NULL_POSITION || epos > old_start_attnpos))
334 (void) forw_line(pos);
346 * Hide search string highlighting.
353 error("No previous regular expression", NULL_PARG);
357 hide_hilite = !hide_hilite;
363 * Compile a search pattern, for future use by match_pattern.
366 compile_pattern(pattern, search_type)
370 if ((search_type & SRCH_NO_REGEX) == 0)
372 #if HAVE_POSIX_REGCOMP
373 regex_t *s = (regex_t *) ecalloc(1, sizeof(regex_t));
374 if (regcomp(s, pattern, REGCOMP_FLAG))
377 error("Invalid pattern", NULL_PARG);
380 if (regpattern != NULL)
386 const char *errstring;
389 comp = pcre_compile(pattern, 0,
390 &errstring, &erroffset, NULL);
393 parg.p_string = (char *) errstring;
401 if ((parg.p_string = re_comp(pattern)) != NULL)
410 if ((s = regcmp(pattern, 0)) == NULL)
412 error("Invalid pattern", NULL_PARG);
415 if (cpattern != NULL)
421 if ((s = regcomp(pattern)) == NULL)
424 * regcomp has already printed an error message
429 if (regpattern != NULL)
435 if (last_pattern != NULL)
437 last_pattern = (char *) calloc(1, strlen(pattern)+1);
438 if (last_pattern != NULL)
439 strcpy(last_pattern, pattern);
441 last_search_type = search_type;
446 * Forget that we have a compiled pattern.
451 #if HAVE_POSIX_REGCOMP
452 if (regpattern != NULL)
457 if (regpattern != NULL)
458 pcre_free(regpattern);
465 if (cpattern != NULL)
470 if (regpattern != NULL)
478 * Perform a pattern match with the previously compiled pattern.
479 * Set sp and ep to the start and end of the matched string.
482 match_pattern(line, line_len, sp, ep, notbol)
491 if (last_search_type & SRCH_NO_REGEX)
492 return (match(last_pattern, strlen(last_pattern), line, line_len, sp, ep));
494 #if HAVE_POSIX_REGCOMP
497 int flags = (notbol) ? REG_NOTBOL : 0;
498 matched = !regexec(regpattern, line, 1, &rm, flags);
502 *sp = line + rm.rm_so;
503 *ep = line + rm.rm_eo;
512 int flags = (notbol) ? PCRE_NOTBOL : 0;
514 matched = pcre_exec(regpattern, NULL, line, line_len,
515 0, flags, ovector, 3) >= 0;
518 *sp = line + ovector[0];
519 *ep = line + ovector[1];
523 matched = (re_exec(line) == 1);
525 * re_exec doesn't seem to provide a way to get the matched string.
530 *ep = regex(cpattern, line);
531 matched = (*ep != NULL);
538 matched = regexec2(regpattern, line, notbol);
540 matched = regexec(regpattern, line);
544 *sp = regpattern->startp[0];
545 *ep = regpattern->endp[0];
548 matched = match(last_pattern, strlen(last_pattern), line, line_len, sp, ep);
555 * Clear the hilite list.
561 struct hilite *nexthl;
563 for (hl = hilite_anchor.hl_first; hl != NULL; hl = nexthl)
565 nexthl = hl->hl_next;
568 hilite_anchor.hl_first = NULL;
569 prep_startpos = prep_endpos = NULL_POSITION;
573 * Should any characters in a specified range be highlighted?
576 is_hilited_range(pos, epos)
583 * Look at each highlight and see if any part of it falls in the range.
585 for (hl = hilite_anchor.hl_first; hl != NULL; hl = hl->hl_next)
587 if (hl->hl_endpos > pos &&
588 (epos == NULL_POSITION || epos > hl->hl_startpos))
595 * Should any characters in a specified range be highlighted?
596 * If nohide is nonzero, don't consider hide_hilite.
599 is_hilited(pos, epos, nohide, p_matches)
607 if (p_matches != NULL)
611 start_attnpos != NULL_POSITION &&
613 (epos == NULL_POSITION || epos > start_attnpos))
615 * The attn line overlaps this range.
619 match = is_hilited_range(pos, epos);
623 if (p_matches != NULL)
625 * Report matches, even if we're hiding highlights.
629 if (hilite_search == 0)
631 * Not doing highlighting.
635 if (!nohide && hide_hilite)
637 * Highlighting is hidden.
645 * Add a new hilite to a hilite list.
648 add_hilite(anchor, hl)
649 struct hilite *anchor;
655 * Hilites are sorted in the list; find where new one belongs.
656 * Insert new one after ihl.
658 for (ihl = anchor; ihl->hl_next != NULL; ihl = ihl->hl_next)
660 if (ihl->hl_next->hl_startpos > hl->hl_startpos)
665 * Truncate hilite so it doesn't overlap any existing ones
666 * above and below it.
669 hl->hl_startpos = MAXPOS(hl->hl_startpos, ihl->hl_endpos);
670 if (ihl->hl_next != NULL)
671 hl->hl_endpos = MINPOS(hl->hl_endpos, ihl->hl_next->hl_startpos);
672 if (hl->hl_startpos >= hl->hl_endpos)
675 * Hilite was truncated out of existence.
680 hl->hl_next = ihl->hl_next;
685 adj_hilite_ansi(cvt_ops, line, line_len, npos)
691 char *line_end = *line + line_len;
693 if (cvt_ops & CVT_ANSI)
694 while (IS_CSI_START(**line))
697 * Found an ESC. The file position moves
698 * forward past the entire ANSI escape sequence.
702 while (*line < line_end)
705 if (!is_ansi_middle(*(*line)++))
712 * Adjust hl_startpos & hl_endpos to account for backspace processing.
715 adj_hilite(anchor, linepos, cvt_ops)
716 struct hilite *anchor;
729 * The line was already scanned and hilites were added (in hilite_line).
730 * But it was assumed that each char position in the line
731 * correponds to one char position in the file.
732 * This may not be true if there are backspaces in the line.
733 * Get the raw line again. Look at each character.
735 (void) forw_raw_line(linepos, &line, &line_len);
736 line_end = line + line_len;
737 opos = npos = linepos;
738 hl = anchor->hl_first;
743 * See if we need to adjust the current hl_startpos or
744 * hl_endpos. After adjusting startpos[i], move to endpos[i].
745 * After adjusting endpos[i], move to startpos[i+1].
746 * The hilite list must be sorted thus:
747 * startpos[0] < endpos[0] <= startpos[1] < endpos[1] <= etc.
749 if (checkstart && hl->hl_startpos == opos)
751 hl->hl_startpos = npos;
753 continue; /* {{ not really necessary }} */
754 } else if (!checkstart && hl->hl_endpos == opos)
756 hl->hl_endpos = npos;
759 continue; /* {{ necessary }} */
761 if (line == line_end)
763 adj_hilite_ansi(cvt_ops, &line, line_end - line, &npos);
767 if (cvt_ops & CVT_BS)
769 while (*line == '\b')
773 adj_hilite_ansi(cvt_ops, &line, line_end - line, &npos);
774 if (line == line_end)
781 * Found a backspace. The file position moves
782 * forward by 2 relative to the processed line
783 * which was searched in hilite_line.
793 * Make a hilite for each string in a physical line which matches
794 * the current pattern.
795 * sp,ep delimit the first match already found.
798 hilite_line(linepos, line, line_len, sp, ep, cvt_ops)
807 char *line_end = line + line_len;
809 struct hilite hilites;
811 if (sp == NULL || ep == NULL)
814 * sp and ep delimit the first match in the line.
815 * Mark the corresponding file positions, then
816 * look for further matches and mark them.
817 * {{ This technique, of calling match_pattern on subsequent
818 * substrings of the line, may mark more than is correct
819 * if the pattern starts with "^". This bug is fixed
820 * for those regex functions that accept a notbol parameter
821 * (currently POSIX, PCRE and V8-with-regexec2). }}
825 * Put the hilites into a temporary list until they're adjusted.
827 hilites.hl_first = NULL;
832 * Assume that each char position in the "line"
833 * buffer corresponds to one char position in the file.
834 * This is not quite true; we need to adjust later.
836 hl = (struct hilite *) ecalloc(1, sizeof(struct hilite));
837 hl->hl_startpos = linepos + (sp-line);
838 hl->hl_endpos = linepos + (ep-line);
839 add_hilite(&hilites, hl);
842 * If we matched more than zero characters,
843 * move to the first char after the string we matched.
844 * If we matched zero, just move to the next char.
848 else if (searchp != line_end)
850 else /* end of line */
852 } while (match_pattern(searchp, line_end - searchp, &sp, &ep, 1));
855 * If there were backspaces in the original line, they
856 * were removed, and hl_startpos/hl_endpos are not correct.
857 * {{ This is very ugly. }}
859 adj_hilite(&hilites, linepos, cvt_ops);
862 * Now put the hilites into the real list.
864 while ((hl = hilites.hl_next) != NULL)
866 hilites.hl_next = hl->hl_next;
867 add_hilite(&hilite_anchor, hl);
873 * Change the caseless-ness of searches.
874 * Updates the internal search state to reflect a change in the -i flag.
879 if (!is_ucase_pattern)
881 * Pattern did not have uppercase.
882 * Just set the search caselessness to the global caselessness.
884 is_caseless = caseless;
887 * Pattern did have uppercase.
888 * Discard the pattern; we can't change search caselessness now.
895 * Find matching text which is currently on screen and highlight it.
900 struct scrpos scrpos;
903 if (scrpos.pos == NULL_POSITION)
905 prep_hilite(scrpos.pos, position(BOTTOM_PLUS_ONE), -1);
910 * Change highlighting parameters.
916 * Erase any highlights currently on screen.
921 if (hilite_search == OPT_ONPLUS)
923 * Display highlights.
930 * Figure out where to start a search.
933 search_pos(search_type)
942 * Start at the beginning (or end) of the file.
943 * The empty_screen() case is mainly for
944 * command line initiated searches;
945 * for example, "+/xyz" on the command line.
946 * Also for multi-file (SRCH_PAST_EOF) searches.
948 if (search_type & SRCH_FORW)
954 if (pos == NULL_POSITION)
956 (void) ch_end_seek();
965 * Search does not include current screen.
967 if (search_type & SRCH_FORW)
968 linenum = BOTTOM_PLUS_ONE;
971 pos = position(linenum);
975 * Search includes current screen.
976 * It starts at the jump target (if searching backwards),
977 * or at the jump target plus one (if forwards).
979 linenum = adjsline(jump_sline);
980 pos = position(linenum);
981 if (search_type & SRCH_FORW)
983 pos = forw_raw_line(pos, (char **)NULL, (int *)NULL);
984 while (pos == NULL_POSITION)
986 if (++linenum >= sc_height)
988 pos = position(linenum);
992 while (pos == NULL_POSITION)
996 pos = position(linenum);
1004 * Search a subset of the file, specified by start/end position.
1007 search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
1022 POSITION linepos, oldpos;
1024 linenum = find_linenum(pos);
1029 * Get lines until we find a matching one or until
1030 * we hit end-of-file (or beginning-of-file if we're
1031 * going backwards), or until we hit the end position.
1036 * A signal aborts the search.
1041 if ((endpos != NULL_POSITION && pos >= endpos) || maxlines == 0)
1044 * Reached end position without a match.
1046 if (pendpos != NULL)
1053 if (search_type & SRCH_FORW)
1056 * Read the next line, and save the
1057 * starting position of that line in linepos.
1060 pos = forw_raw_line(pos, &line, &line_len);
1066 * Read the previous line and save the
1067 * starting position of that line in linepos.
1069 pos = back_raw_line(pos, &line, &line_len);
1075 if (pos == NULL_POSITION)
1078 * Reached EOF/BOF without a match.
1080 if (pendpos != NULL)
1086 * If we're using line numbers, we might as well
1087 * remember the information we have now (the position
1088 * and line number of the current line).
1089 * Don't do it for every line because it slows down
1090 * the search. Remember the line number only if
1091 * we're "far" from the last place we remembered it.
1093 if (linenums && abs((int)(pos - oldpos)) > 1024)
1094 add_lnum(linenum, pos);
1098 * If it's a caseless search, convert the line to lowercase.
1099 * If we're doing backspace processing, delete backspaces.
1101 cvt_ops = get_cvt_ops();
1102 cvt_text(line, line, &line_len, cvt_ops);
1105 * Test the next line to see if we have a match.
1106 * We are successful if we either want a match and got one,
1107 * or if we want a non-match and got one.
1109 line_match = match_pattern(line, line_len, &sp, &ep, 0);
1110 line_match = (!(search_type & SRCH_NO_MATCH) && line_match) ||
1111 ((search_type & SRCH_NO_MATCH) && !line_match);
1117 if (search_type & SRCH_FIND_ALL)
1121 * We are supposed to find all matches in the range.
1122 * Just add the matches in this line to the
1123 * hilite list and keep searching.
1126 hilite_line(linepos, line, line_len, sp, ep, cvt_ops);
1128 } else if (--matches <= 0)
1131 * Found the one match we're looking for.
1135 if (hilite_search == OPT_ON)
1138 * Clear the hilite list and add only
1139 * the matches in this one line.
1143 hilite_line(linepos, line, line_len, sp, ep, cvt_ops);
1146 if (plinepos != NULL)
1147 *plinepos = linepos;
1154 * search for a pattern in history. If found, compile that pattern.
1157 hist_pattern(search_type)
1163 set_mlist(ml_search, 0);
1164 pattern = cmd_lastpattern();
1165 if (pattern == NULL)
1168 if (caseless == OPT_ONPLUS)
1169 cvt_text(pattern, pattern, (int *)NULL, CVT_TO_LC);
1171 if (compile_pattern(pattern, search_type) < 0)
1174 is_ucase_pattern = is_ucase(pattern);
1175 if (is_ucase_pattern && caseless != OPT_ONPLUS)
1178 is_caseless = caseless;
1181 if (hilite_search == OPT_ONPLUS && !hide_hilite)
1186 #else /* CMD_HISTORY */
1188 #endif /* CMD_HISTORY */
1192 * Search for the n-th occurrence of a specified pattern,
1193 * either forward or backward.
1194 * Return the number of matches not yet found in this file
1195 * (that is, n minus the number of matches found).
1196 * Return -1 if the search should be aborted.
1197 * Caller may continue the search in another file
1198 * if less than n matches are found in this file.
1201 search(search_type, pattern, n)
1209 if (pattern == NULL || *pattern == '\0')
1212 * A null pattern means use the previously compiled pattern.
1214 if (!prev_pattern() && !hist_pattern(search_type))
1216 error("No previous regular expression", NULL_PARG);
1219 if ((search_type & SRCH_NO_REGEX) !=
1220 (last_search_type & SRCH_NO_REGEX))
1222 error("Please re-enter search pattern", NULL_PARG);
1226 if (hilite_search == OPT_ON)
1229 * Erase the highlights currently on screen.
1230 * If the search fails, we'll redisplay them later.
1234 if (hilite_search == OPT_ONPLUS && hide_hilite)
1237 * Highlight any matches currently on screen,
1238 * before we actually start the search.
1248 * Compile the pattern.
1250 ucase = is_ucase(pattern);
1251 if (caseless == OPT_ONPLUS)
1252 cvt_text(pattern, pattern, (int *)NULL, CVT_TO_LC);
1253 if (compile_pattern(pattern, search_type) < 0)
1256 * Ignore case if -I is set OR
1257 * -i is set AND the pattern is all lowercase.
1259 is_ucase_pattern = ucase;
1260 if (is_ucase_pattern && caseless != OPT_ONPLUS)
1263 is_caseless = caseless;
1268 * Erase the highlights currently on screen.
1269 * Also permanently delete them from the hilite list.
1275 if (hilite_search == OPT_ONPLUS)
1278 * Highlight any matches currently on screen,
1279 * before we actually start the search.
1287 * Figure out where to start the search.
1289 pos = search_pos(search_type);
1290 if (pos == NULL_POSITION)
1293 * Can't find anyplace to start searching from.
1295 if (search_type & SRCH_PAST_EOF)
1297 /* repaint(); -- why was this here? */
1298 error("Nothing to search", NULL_PARG);
1302 n = search_range(pos, NULL_POSITION, search_type, n, -1,
1303 &pos, (POSITION*)NULL);
1307 * Search was unsuccessful.
1310 if (hilite_search == OPT_ON && n > 0)
1312 * Redisplay old hilites.
1319 if (!(search_type & SRCH_NO_MOVE))
1322 * Go to the matching line.
1324 jump_loc(pos, jump_sline);
1328 if (hilite_search == OPT_ON)
1330 * Display new hilites in the matching line.
1340 * Prepare hilites in a given range of the file.
1342 * The pair (prep_startpos,prep_endpos) delimits a contiguous region
1343 * of the file that has been "prepared"; that is, scanned for matches for
1344 * the current search pattern, and hilites have been created for such matches.
1345 * If prep_startpos == NULL_POSITION, the prep region is empty.
1346 * If prep_endpos == NULL_POSITION, the prep region extends to EOF.
1347 * prep_hilite asks that the range (spos,epos) be covered by the prep region.
1350 prep_hilite(spos, epos, maxlines)
1355 POSITION nprep_startpos = prep_startpos;
1356 POSITION nprep_endpos = prep_endpos;
1362 * Search beyond where we're asked to search, so the prep region covers
1363 * more than we need. Do one big search instead of a bunch of small ones.
1365 #define SEARCH_MORE (3*size_linebuf)
1367 if (!prev_pattern())
1371 * If we're limited to a max number of lines, figure out the
1372 * file position we should stop at.
1375 max_epos = NULL_POSITION;
1379 for (i = 0; i < maxlines; i++)
1380 max_epos = forw_raw_line(max_epos, (char **)NULL, (int *)NULL);
1385 * The range that we need to search (spos,epos); and the range that
1386 * the "prep" region will then cover (nprep_startpos,nprep_endpos).
1389 if (prep_startpos == NULL_POSITION ||
1390 (epos != NULL_POSITION && epos < prep_startpos) ||
1394 * New range is not contiguous with old prep region.
1395 * Discard the old prep region and start a new one.
1398 if (epos != NULL_POSITION)
1399 epos += SEARCH_MORE;
1400 nprep_startpos = spos;
1404 * New range partially or completely overlaps old prep region.
1406 if (epos == NULL_POSITION)
1409 * New range goes to end of file.
1412 } else if (epos > prep_endpos)
1415 * New range ends after old prep region.
1416 * Extend prep region to end at end of new range.
1418 epos += SEARCH_MORE;
1419 } else /* (epos <= prep_endpos) */
1422 * New range ends within old prep region.
1423 * Truncate search to end at start of old prep region.
1425 epos = prep_startpos;
1428 if (spos < prep_startpos)
1431 * New range starts before old prep region.
1432 * Extend old prep region backwards to start at
1433 * start of new range.
1435 if (spos < SEARCH_MORE)
1438 spos -= SEARCH_MORE;
1439 nprep_startpos = spos;
1440 } else /* (spos >= prep_startpos) */
1443 * New range starts within or after old prep region.
1444 * Trim search to start at end of old prep region.
1450 if (epos != NULL_POSITION && max_epos != NULL_POSITION &&
1453 * Don't go past the max position we're allowed.
1457 if (epos == NULL_POSITION || epos > spos)
1459 result = search_range(spos, epos, SRCH_FORW|SRCH_FIND_ALL, 0,
1460 maxlines, (POSITION*)NULL, &new_epos);
1463 if (prep_endpos == NULL_POSITION || new_epos > prep_endpos)
1464 nprep_endpos = new_epos;
1466 prep_startpos = nprep_startpos;
1467 prep_endpos = nprep_endpos;
1472 * Simple pattern matching function.
1473 * It supports no metacharacters like *, etc.
1476 match(pattern, pattern_len, buf, buf_len, pfound, pend)
1481 char **pfound, **pend;
1483 register char *pp, *lp;
1484 register char *pattern_end = pattern + pattern_len;
1485 register char *buf_end = buf + buf_len;
1487 for ( ; buf < buf_end; buf++)
1489 for (pp = pattern, lp = buf; *pp == *lp; pp++, lp++)
1490 if (pp == pattern_end || lp == buf_end)
1492 if (pp == pattern_end)
1506 * This function is called by the V8 regcomp to report
1507 * errors in regular expressions.