[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.1

1.1     ! shadchin    1: /*
        !             2:  * Copyright (C) 1984-2011  Mark Nudelman
        !             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:  *
        !             7:  * For more information about less, or for information on how to
        !             8:  * contact the author, see the README file.
        !             9:  */
        !            10:
        !            11: /*
        !            12:  * Routines to do pattern matching.
        !            13:  */
        !            14:
        !            15: #include "less.h"
        !            16: #include "pattern.h"
        !            17:
        !            18: extern int caseless;
        !            19:
        !            20: /*
        !            21:  * Compile a search pattern, for future use by match_pattern.
        !            22:  */
        !            23:        static int
        !            24: compile_pattern2(pattern, search_type, comp_pattern)
        !            25:        char *pattern;
        !            26:        int search_type;
        !            27:        void **comp_pattern;
        !            28: {
        !            29:        if ((search_type & SRCH_NO_REGEX) == 0)
        !            30:        {
        !            31: #if HAVE_POSIX_REGCOMP
        !            32:                regex_t *comp = (regex_t *) ecalloc(1, sizeof(regex_t));
        !            33:                regex_t **pcomp = (regex_t **) comp_pattern;
        !            34:                if (regcomp(comp, pattern, REGCOMP_FLAG))
        !            35:                {
        !            36:                        free(comp);
        !            37:                        error("Invalid pattern", NULL_PARG);
        !            38:                        return (-1);
        !            39:                }
        !            40:                if (*pcomp != NULL)
        !            41:                        regfree(*pcomp);
        !            42:                *pcomp = comp;
        !            43: #endif
        !            44: #if HAVE_PCRE
        !            45:                pcre *comp;
        !            46:                pcre **pcomp = (pcre **) comp_pattern;
        !            47:                const char *errstring;
        !            48:                int erroffset;
        !            49:                PARG parg;
        !            50:                comp = pcre_compile(pattern, 0,
        !            51:                                &errstring, &erroffset, NULL);
        !            52:                if (comp == NULL)
        !            53:                {
        !            54:                        parg.p_string = (char *) errstring;
        !            55:                        error("%s", &parg);
        !            56:                        return (-1);
        !            57:                }
        !            58:                *pcomp = comp;
        !            59: #endif
        !            60: #if HAVE_RE_COMP
        !            61:                PARG parg;
        !            62:                int *pcomp = (int *) comp_pattern;
        !            63:                if ((parg.p_string = re_comp(pattern)) != NULL)
        !            64:                {
        !            65:                        error("%s", &parg);
        !            66:                        return (-1);
        !            67:                }
        !            68:                *pcomp = 1;
        !            69: #endif
        !            70: #if HAVE_REGCMP
        !            71:                char *comp;
        !            72:                char **pcomp = (char **) comp_pattern;
        !            73:                if ((comp = regcmp(pattern, 0)) == NULL)
        !            74:                {
        !            75:                        error("Invalid pattern", NULL_PARG);
        !            76:                        return (-1);
        !            77:                }
        !            78:                if (pcomp != NULL)
        !            79:                        free(*pcomp);
        !            80:                *pcomp = comp;
        !            81: #endif
        !            82: #if HAVE_V8_REGCOMP
        !            83:                struct regexp *comp;
        !            84:                struct regexp **pcomp = (struct regexp **) comp_pattern;
        !            85:                if ((comp = regcomp(pattern)) == NULL)
        !            86:                {
        !            87:                        /*
        !            88:                         * regcomp has already printed an error message
        !            89:                         * via regerror().
        !            90:                         */
        !            91:                        return (-1);
        !            92:                }
        !            93:                if (*pcomp != NULL)
        !            94:                        free(*pcomp);
        !            95:                *pcomp = comp;
        !            96: #endif
        !            97:        }
        !            98:        return (0);
        !            99: }
        !           100:
        !           101: /*
        !           102:  * Like compile_pattern2, but convert the pattern to lowercase if necessary.
        !           103:  */
        !           104:        public int
        !           105: compile_pattern(pattern, search_type, comp_pattern)
        !           106:        char *pattern;
        !           107:        int search_type;
        !           108:        void **comp_pattern;
        !           109: {
        !           110:        char *cvt_pattern;
        !           111:        int result;
        !           112:
        !           113:        if (caseless != OPT_ONPLUS)
        !           114:                cvt_pattern = pattern;
        !           115:        else
        !           116:        {
        !           117:                cvt_pattern = (char*) ecalloc(1, cvt_length(strlen(pattern), CVT_TO_LC));
        !           118:                cvt_text(cvt_pattern, pattern, (int *)NULL, (int *)NULL, CVT_TO_LC);
        !           119:        }
        !           120:        result = compile_pattern2(cvt_pattern, search_type, comp_pattern);
        !           121:        if (cvt_pattern != pattern)
        !           122:                free(cvt_pattern);
        !           123:        return (result);
        !           124: }
        !           125:
        !           126: /*
        !           127:  * Forget that we have a compiled pattern.
        !           128:  */
        !           129:        public void
        !           130: uncompile_pattern(pattern)
        !           131:        void **pattern;
        !           132: {
        !           133: #if HAVE_POSIX_REGCOMP
        !           134:        regex_t **pcomp = (regex_t **) pattern;
        !           135:        if (*pcomp != NULL)
        !           136:                regfree(*pcomp);
        !           137:        *pcomp = NULL;
        !           138: #endif
        !           139: #if HAVE_PCRE
        !           140:        pcre **pcomp = (pcre **) pattern;
        !           141:        if (*pcomp != NULL)
        !           142:                pcre_free(*pcomp);
        !           143:        *pcomp = NULL;
        !           144: #endif
        !           145: #if HAVE_RE_COMP
        !           146:        int *pcomp = (int *) pattern;
        !           147:        *pcomp = 0;
        !           148: #endif
        !           149: #if HAVE_REGCMP
        !           150:        char **pcomp = (char **) pattern;
        !           151:        if (*pcomp != NULL)
        !           152:                free(*pcomp);
        !           153:        *pcomp = NULL;
        !           154: #endif
        !           155: #if HAVE_V8_REGCOMP
        !           156:        struct regexp **pcomp = (struct regexp **) pattern;
        !           157:        if (*pcomp != NULL)
        !           158:                free(*pcomp);
        !           159:        *pcomp = NULL;
        !           160: #endif
        !           161: }
        !           162:
        !           163: /*
        !           164:  * Is a compiled pattern null?
        !           165:  */
        !           166:        public int
        !           167: is_null_pattern(pattern)
        !           168:        void *pattern;
        !           169: {
        !           170: #if HAVE_POSIX_REGCOMP
        !           171:        return (pattern == NULL);
        !           172: #endif
        !           173: #if HAVE_PCRE
        !           174:        return (pattern == NULL);
        !           175: #endif
        !           176: #if HAVE_RE_COMP
        !           177:        return (pattern == 0);
        !           178: #endif
        !           179: #if HAVE_REGCMP
        !           180:        return (pattern == NULL);
        !           181: #endif
        !           182: #if HAVE_V8_REGCOMP
        !           183:        return (pattern == NULL);
        !           184: #endif
        !           185: #if NO_REGEX
        !           186:        return (search_pattern != NULL);
        !           187: #endif
        !           188: }
        !           189:
        !           190: /*
        !           191:  * Simple pattern matching function.
        !           192:  * It supports no metacharacters like *, etc.
        !           193:  */
        !           194:        static int
        !           195: match(pattern, pattern_len, buf, buf_len, pfound, pend)
        !           196:        char *pattern;
        !           197:        int pattern_len;
        !           198:        char *buf;
        !           199:        int buf_len;
        !           200:        char **pfound, **pend;
        !           201: {
        !           202:        register char *pp, *lp;
        !           203:        register char *pattern_end = pattern + pattern_len;
        !           204:        register char *buf_end = buf + buf_len;
        !           205:
        !           206:        for ( ;  buf < buf_end;  buf++)
        !           207:        {
        !           208:                for (pp = pattern, lp = buf;  *pp == *lp;  pp++, lp++)
        !           209:                        if (pp == pattern_end || lp == buf_end)
        !           210:                                break;
        !           211:                if (pp == pattern_end)
        !           212:                {
        !           213:                        if (pfound != NULL)
        !           214:                                *pfound = buf;
        !           215:                        if (pend != NULL)
        !           216:                                *pend = lp;
        !           217:                        return (1);
        !           218:                }
        !           219:        }
        !           220:        return (0);
        !           221: }
        !           222:
        !           223: /*
        !           224:  * Perform a pattern match with the previously compiled pattern.
        !           225:  * Set sp and ep to the start and end of the matched string.
        !           226:  */
        !           227:        public int
        !           228: match_pattern(pattern, tpattern, line, line_len, sp, ep, notbol, search_type)
        !           229:        void *pattern;
        !           230:        char *tpattern;
        !           231:        char *line;
        !           232:        int line_len;
        !           233:        char **sp;
        !           234:        char **ep;
        !           235:        int notbol;
        !           236:        int search_type;
        !           237: {
        !           238:        int matched;
        !           239: #if HAVE_POSIX_REGCOMP
        !           240:        regex_t *spattern = (regex_t *) pattern;
        !           241: #endif
        !           242: #if HAVE_PCRE
        !           243:        pcre *spattern = (pcre *) pattern;
        !           244: #endif
        !           245: #if HAVE_RE_COMP
        !           246:        int spattern = (int) pattern;
        !           247: #endif
        !           248: #if HAVE_REGCMP
        !           249:        char *spattern = (char *) pattern;
        !           250: #endif
        !           251: #if HAVE_V8_REGCOMP
        !           252:        struct regexp *spattern = (struct regexp *) pattern;
        !           253: #endif
        !           254:
        !           255:        if (search_type & SRCH_NO_REGEX)
        !           256:                matched = match(tpattern, strlen(tpattern), line, line_len, sp, ep);
        !           257:        else
        !           258:        {
        !           259: #if HAVE_POSIX_REGCOMP
        !           260:        {
        !           261:                regmatch_t rm;
        !           262:                int flags = (notbol) ? REG_NOTBOL : 0;
        !           263:                matched = !regexec(spattern, line, 1, &rm, flags);
        !           264:                if (matched)
        !           265:                {
        !           266: #ifndef __WATCOMC__
        !           267:                        *sp = line + rm.rm_so;
        !           268:                        *ep = line + rm.rm_eo;
        !           269: #else
        !           270:                        *sp = rm.rm_sp;
        !           271:                        *ep = rm.rm_ep;
        !           272: #endif
        !           273:                }
        !           274:        }
        !           275: #endif
        !           276: #if HAVE_PCRE
        !           277:        {
        !           278:                int flags = (notbol) ? PCRE_NOTBOL : 0;
        !           279:                int ovector[3];
        !           280:                matched = pcre_exec(spattern, NULL, line, line_len,
        !           281:                        0, flags, ovector, 3) >= 0;
        !           282:                if (matched)
        !           283:                {
        !           284:                        *sp = line + ovector[0];
        !           285:                        *ep = line + ovector[1];
        !           286:                }
        !           287:        }
        !           288: #endif
        !           289: #if HAVE_RE_COMP
        !           290:        matched = (re_exec(line) == 1);
        !           291:        /*
        !           292:         * re_exec doesn't seem to provide a way to get the matched string.
        !           293:         */
        !           294:        *sp = *ep = NULL;
        !           295: #endif
        !           296: #if HAVE_REGCMP
        !           297:        *ep = regex(spattern, line);
        !           298:        matched = (*ep != NULL);
        !           299:        if (matched)
        !           300:                *sp = __loc1;
        !           301: #endif
        !           302: #if HAVE_V8_REGCOMP
        !           303: #if HAVE_REGEXEC2
        !           304:        matched = regexec2(spattern, line, notbol);
        !           305: #else
        !           306:        matched = regexec(spattern, line);
        !           307: #endif
        !           308:        if (matched)
        !           309:        {
        !           310:                *sp = spattern->startp[0];
        !           311:                *ep = spattern->endp[0];
        !           312:        }
        !           313: #endif
        !           314: #if NO_REGEX
        !           315:        matched = match(tpattern, strlen(tpattern), line, line_len, sp, ep);
        !           316: #endif
        !           317:        }
        !           318:        matched = (!(search_type & SRCH_NO_MATCH) && matched) ||
        !           319:                        ((search_type & SRCH_NO_MATCH) && !matched);
        !           320:        return (matched);
        !           321: }
        !           322: