pax: avoid implicit function declaration warnings
[unleashed.git] / bin / less / pattern.c
blob6e98ff28b0e90eac85e74107c68037a4db0a94a7
1 /*
2 * Copyright (C) 1984-2012 Mark Nudelman
3 * Modified for use with illumos by Garrett D'Amore.
4 * Copyright 2014 Garrett D'Amore <garrett@damore.org>
6 * You may distribute under the terms of either the GNU General Public
7 * License or the Less License, as specified in the README file.
9 * For more information, see the README file.
13 * Routines to do pattern matching.
16 #include "less.h"
17 #include "pattern.h"
19 extern int caseless;
20 extern int less_is_more;
23 * Compile a search pattern, for future use by match_pattern.
25 static int
26 compile_pattern2(char *pattern, int search_type, regex_t **comp_pattern)
28 regex_t *comp;
30 if (search_type & SRCH_NO_REGEX)
31 return (0);
32 comp = ecalloc(1, sizeof (regex_t));
33 if (regcomp(comp, pattern, less_is_more ? 0 : REGCOMP_FLAG)) {
34 free(comp);
35 error("Invalid pattern", NULL);
36 return (-1);
38 if (*comp_pattern != NULL)
39 regfree(*comp_pattern);
40 *comp_pattern = comp;
41 return (0);
45 * Like compile_pattern2, but convert the pattern to lowercase if necessary.
47 int
48 compile_pattern(char *pattern, int search_type, regex_t **comp_pattern)
50 char *cvt_pattern;
51 int result;
53 if (caseless != OPT_ONPLUS) {
54 cvt_pattern = pattern;
55 } else {
56 cvt_pattern = ecalloc(1, cvt_length(strlen(pattern)));
57 cvt_text(cvt_pattern, pattern, NULL, NULL, CVT_TO_LC);
59 result = compile_pattern2(cvt_pattern, search_type, comp_pattern);
60 if (cvt_pattern != pattern)
61 free(cvt_pattern);
62 return (result);
66 * Forget that we have a compiled pattern.
68 void
69 uncompile_pattern(regex_t **pattern)
71 if (*pattern != NULL)
72 regfree(*pattern);
73 *pattern = NULL;
77 * Simple pattern matching function.
78 * It supports no metacharacters like *, etc.
80 static int
81 match(char *pattern, int pattern_len, char *buf, int buf_len,
82 char **pfound, char **pend)
84 char *pp, *lp;
85 char *pattern_end = pattern + pattern_len;
86 char *buf_end = buf + buf_len;
88 for (; buf < buf_end; buf++) {
89 for (pp = pattern, lp = buf; *pp == *lp; pp++, lp++)
90 if (pp == pattern_end || lp == buf_end)
91 break;
92 if (pp == pattern_end) {
93 if (pfound != NULL)
94 *pfound = buf;
95 if (pend != NULL)
96 *pend = lp;
97 return (1);
100 return (0);
104 * Perform a pattern match with the previously compiled pattern.
105 * Set sp and ep to the start and end of the matched string.
108 match_pattern(void *pattern, char *tpattern, char *line, int line_len,
109 char **sp, char **ep, int notbol, int search_type)
111 int matched;
112 regex_t *spattern = (regex_t *)pattern;
114 if (search_type & SRCH_NO_REGEX) {
115 matched = match(tpattern, strlen(tpattern), line, line_len,
116 sp, ep);
117 } else {
118 regmatch_t rm;
119 int flags = (notbol) ? REG_NOTBOL : 0;
120 #ifdef REG_STARTEND
121 flags |= REG_STARTEND;
122 rm.rm_so = 0;
123 rm.rm_eo = line_len;
124 #endif
125 *sp = NULL;
126 *ep = NULL;
127 matched = !regexec(spattern, line, 1, &rm, flags);
128 if (matched) {
129 *sp = line + rm.rm_so;
130 *ep = line + rm.rm_eo;
133 matched = (!(search_type & SRCH_NO_MATCH) && matched) ||
134 ((search_type & SRCH_NO_MATCH) && !matched);
135 return (matched);