Annotation of src/usr.bin/less/pattern.c, Revision 1.6
1.1 shadchin 1: /*
1.3 shadchin 2: * Copyright (C) 1984-2012 Mark Nudelman
1.1 shadchin 3: *
4: * You may distribute under the terms of either the GNU General Public
5: * License or the Less License, as specified in the README file.
6: *
1.3 shadchin 7: * For more information, see the README file.
1.1 shadchin 8: */
1.6 ! nicm 9: /*
! 10: * Modified for use with illumos.
! 11: * Copyright 2014 Garrett D'Amore <garrett@damore.org>
! 12: */
1.1 shadchin 13:
14: /*
15: * Routines to do pattern matching.
16: */
17:
18: #include "less.h"
19: #include "pattern.h"
20:
21: extern int caseless;
1.2 millert 22: extern int less_is_more;
1.1 shadchin 23:
24: /*
25: * Compile a search pattern, for future use by match_pattern.
26: */
1.6 ! nicm 27: static int
! 28: compile_pattern2(char *pattern, int search_type, regex_t **comp_pattern)
1.1 shadchin 29: {
1.6 ! nicm 30: regex_t *comp;
! 31:
1.3 shadchin 32: if (search_type & SRCH_NO_REGEX)
33: return (0);
1.6 ! nicm 34: comp = ecalloc(1, sizeof (regex_t));
! 35: if (regcomp(comp, pattern, less_is_more ? 0 : REGCOMP_FLAG)) {
1.3 shadchin 36: free(comp);
37: error("Invalid pattern", NULL_PARG);
38: return (-1);
39: }
1.6 ! nicm 40: if (*comp_pattern != NULL)
! 41: regfree(*comp_pattern);
! 42: *comp_pattern = comp;
1.1 shadchin 43: return (0);
44: }
45:
46: /*
47: * Like compile_pattern2, but convert the pattern to lowercase if necessary.
48: */
1.6 ! nicm 49: int
! 50: compile_pattern(char *pattern, int search_type, regex_t **comp_pattern)
1.1 shadchin 51: {
52: char *cvt_pattern;
53: int result;
54:
1.6 ! nicm 55: if (caseless != OPT_ONPLUS) {
1.1 shadchin 56: cvt_pattern = pattern;
1.6 ! nicm 57: } else {
! 58: cvt_pattern = ecalloc(1, cvt_length(strlen(pattern)));
! 59: cvt_text(cvt_pattern, pattern, NULL, NULL, CVT_TO_LC);
1.1 shadchin 60: }
61: result = compile_pattern2(cvt_pattern, search_type, comp_pattern);
62: if (cvt_pattern != pattern)
63: free(cvt_pattern);
64: return (result);
65: }
66:
67: /*
68: * Forget that we have a compiled pattern.
69: */
1.6 ! nicm 70: void
! 71: uncompile_pattern(regex_t **pattern)
1.1 shadchin 72: {
1.6 ! nicm 73: if (*pattern != NULL)
! 74: regfree(*pattern);
! 75: *pattern = NULL;
1.1 shadchin 76: }
77:
78: /*
79: * Is a compiled pattern null?
80: */
1.6 ! nicm 81: int
! 82: is_null_pattern(void *pattern)
1.1 shadchin 83: {
84: return (pattern == NULL);
85: }
86:
87: /*
88: * Simple pattern matching function.
89: * It supports no metacharacters like *, etc.
90: */
1.6 ! nicm 91: static int
! 92: match(char *pattern, int pattern_len, char *buf, int buf_len,
! 93: char **pfound, char **pend)
! 94: {
! 95: char *pp, *lp;
! 96: char *pattern_end = pattern + pattern_len;
! 97: char *buf_end = buf + buf_len;
! 98:
! 99: for (; buf < buf_end; buf++) {
! 100: for (pp = pattern, lp = buf; *pp == *lp; pp++, lp++)
1.1 shadchin 101: if (pp == pattern_end || lp == buf_end)
102: break;
1.6 ! nicm 103: if (pp == pattern_end) {
1.1 shadchin 104: if (pfound != NULL)
105: *pfound = buf;
106: if (pend != NULL)
107: *pend = lp;
108: return (1);
109: }
110: }
111: return (0);
112: }
113:
114: /*
115: * Perform a pattern match with the previously compiled pattern.
116: * Set sp and ep to the start and end of the matched string.
117: */
1.6 ! nicm 118: int
! 119: match_pattern(void *pattern, char *tpattern, char *line, int line_len,
! 120: char **sp, char **ep, int notbol, int search_type)
1.1 shadchin 121: {
122: int matched;
1.6 ! nicm 123: regex_t *spattern = (regex_t *)pattern;
1.1 shadchin 124:
1.6 ! nicm 125: if (search_type & SRCH_NO_REGEX) {
! 126: matched = match(tpattern, strlen(tpattern), line, line_len,
! 127: sp, ep);
! 128: } else {
1.1 shadchin 129: regmatch_t rm;
130: int flags = (notbol) ? REG_NOTBOL : 0;
1.6 ! nicm 131: #ifdef REG_STARTEND
1.4 guenther 132: flags |= REG_STARTEND;
133: rm.rm_so = 0;
134: rm.rm_eo = line_len;
135: #endif
1.1 shadchin 136: matched = !regexec(spattern, line, 1, &rm, flags);
1.6 ! nicm 137: if (matched) {
1.1 shadchin 138: *sp = line + rm.rm_so;
139: *ep = line + rm.rm_eo;
140: }
141: }
142: matched = (!(search_type & SRCH_NO_MATCH) && matched) ||
1.6 ! nicm 143: ((search_type & SRCH_NO_MATCH) && !matched);
1.1 shadchin 144: return (matched);
145: }