[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.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: }