[BACK]Return to pattern.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / less

Annotation of src/usr.bin/less/pattern.c, Revision 1.10

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