[BACK]Return to match.c CVS log [TXT][DIR] Up to [local] / ircnowd / src / ngircd

Annotation of ircnowd/src/ngircd/match.c, Revision 1.1

1.1     ! tomglok     1: /*
        !             2:  * ngIRCd -- The Next Generation IRC Daemon
        !             3:  * Copyright (c)2001-2018 Alexander Barton (alex@barton.de) and Contributors.
        !             4:  *
        !             5:  * This program is free software; you can redistribute it and/or modify
        !             6:  * it under the terms of the GNU General Public License as published by
        !             7:  * the Free Software Foundation; either version 2 of the License, or
        !             8:  * (at your option) any later version.
        !             9:  * Please read the file COPYING, README and AUTHORS for more information.
        !            10:  */
        !            11:
        !            12: #include "portab.h"
        !            13:
        !            14: /**
        !            15:  * @file
        !            16:  * Wildcard pattern matching
        !            17:  */
        !            18:
        !            19: #include <assert.h>
        !            20: #include <string.h>
        !            21:
        !            22: #include "defines.h"
        !            23: #include "tool.h"
        !            24:
        !            25: #include "match.h"
        !            26:
        !            27: /*
        !            28:  * The pattern matching functions [Matche(), Matche_After_Star()] are based
        !            29:  * on code of J. Kercheval. Version 1.1 has been released on 1991-03-12 as
        !            30:  * "public domain": <http://c.snippets.org/snip_lister.php?fname=match.c>
        !            31:  */
        !            32:
        !            33: static int Matche PARAMS(( const char *p, const char *t ));
        !            34: static int Matche_After_Star PARAMS(( const char *p, const char *t ));
        !            35:
        !            36: #define MATCH_PATTERN  6       /**< bad pattern */
        !            37: #define MATCH_LITERAL  5       /**< match failure on literal match */
        !            38: #define MATCH_RANGE    4       /**< match failure on [..] construct */
        !            39: #define MATCH_ABORT    3       /**< premature end of text string */
        !            40: #define MATCH_END      2       /**< premature end of pattern string */
        !            41: #define MATCH_VALID    1       /**< valid match */
        !            42:
        !            43: /**
        !            44:  * Match string with pattern.
        !            45:  *
        !            46:  * @param Pattern Pattern to match with
        !            47:  * @param String Input string
        !            48:  * @return true if pattern matches
        !            49:  */
        !            50: GLOBAL bool
        !            51: Match( const char *Pattern, const char *String )
        !            52: {
        !            53:        if (Matche(Pattern, String) == MATCH_VALID)
        !            54:                return true;
        !            55:        else
        !            56:                return false;
        !            57: } /* Match */
        !            58:
        !            59: /**
        !            60:  * Match string with pattern case-insensitive.
        !            61:  *
        !            62:  * @param Pattern Pattern to match with
        !            63:  * @param String Input string, at most COMMAND_LEN-1 characters long
        !            64:  * @return true if pattern matches
        !            65:  */
        !            66: GLOBAL bool
        !            67: MatchCaseInsensitive(const char *Pattern, const char *String)
        !            68: {
        !            69:        char needle[COMMAND_LEN], haystack[COMMAND_LEN];
        !            70:
        !            71:        strlcpy(needle, Pattern, sizeof(needle));
        !            72:        strlcpy(haystack, String, sizeof(haystack));
        !            73:
        !            74:        return Match(ngt_LowerStr(needle), ngt_LowerStr(haystack));
        !            75: } /* MatchCaseInsensitive */
        !            76:
        !            77: /**
        !            78:  * Match string with pattern case-insensitive.
        !            79:  *
        !            80:  * @param Pattern Pattern to match with
        !            81:  * @param String Input string, at most COMMAND_LEN-1 characters long
        !            82:  * @param Separator Character separating the individual patterns in the list
        !            83:  * @return true if pattern matches
        !            84:  */
        !            85: GLOBAL bool
        !            86: MatchCaseInsensitiveList(const char *Pattern, const char *String,
        !            87:                     const char *Separator)
        !            88: {
        !            89:        char tmp_pattern[COMMAND_LEN], *ptr;
        !            90:
        !            91:        strlcpy(tmp_pattern, Pattern, sizeof(tmp_pattern));
        !            92:
        !            93:        ptr = strtok(tmp_pattern, Separator);
        !            94:        while (ptr) {
        !            95:                ngt_TrimStr(ptr);
        !            96:                if (MatchCaseInsensitive(ptr, String))
        !            97:                        return true;
        !            98:                ptr = strtok(NULL, Separator);
        !            99:        }
        !           100:        return false;
        !           101: } /* MatchCaseInsensitive */
        !           102:
        !           103: static int
        !           104: Matche( const char *p, const char *t )
        !           105: {
        !           106:        for( ; *p; p++, t++ )
        !           107:        {
        !           108:                /* if this is the end of the text then this is the end of the match */
        !           109:                if( ! *t )
        !           110:                {
        !           111:                        return ( *p == '*' && *++p == '\0' ) ? MATCH_VALID : MATCH_ABORT;
        !           112:                }
        !           113:
        !           114:                /* determine and react to pattern type */
        !           115:                switch( *p )
        !           116:                {
        !           117:                        case '?':       /* single any character match */
        !           118:                                break;
        !           119:
        !           120:                        case '*':       /* multiple any character match */
        !           121:                                return Matche_After_Star( p, t );
        !           122:
        !           123:                        default:        /* must match this character exactly */
        !           124:                                if( *p != *t ) return MATCH_LITERAL;
        !           125:                }
        !           126:        }
        !           127:        /* if end of text not reached then the pattern fails */
        !           128:
        !           129:        if( *t ) return MATCH_END;
        !           130:        else return MATCH_VALID;
        !           131: } /* Matche */
        !           132:
        !           133: static int
        !           134: Matche_After_Star( const char *p, const char *t )
        !           135: {
        !           136:        register int nextp, match = 0;
        !           137:
        !           138:        /* pass over existing ? and * in pattern */
        !           139:        while( *p == '?' || *p == '*' )
        !           140:        {
        !           141:                /* take one char for each ? and + */
        !           142:                if (*p == '?')
        !           143:                {
        !           144:                        /* if end of text then no match */
        !           145:                        if( ! *t++ ) return MATCH_ABORT;
        !           146:                }
        !           147:
        !           148:                /* move to next char in pattern */
        !           149:                p++;
        !           150:        }
        !           151:
        !           152:        /* if end of pattern we have matched regardless of text left */
        !           153:        if( ! *p ) return MATCH_VALID;
        !           154:
        !           155:        /* get the next character to match which must be a literal or '[' */
        !           156:        nextp = *p;
        !           157:        if( nextp == '\\' )
        !           158:        {
        !           159:                nextp = p[1];
        !           160:
        !           161:                /* if end of text then we have a bad pattern */
        !           162:                if( ! nextp ) return MATCH_PATTERN;
        !           163:        }
        !           164:
        !           165:        /* Continue until we run out of text or definite result seen */
        !           166:        do
        !           167:        {
        !           168:                /* a precondition for matching is that the next character
        !           169:                 * in the pattern match the next character in the text or that
        !           170:                 * the next pattern char is the beginning of a range.  Increment
        !           171:                 * text pointer as we go here */
        !           172:                if( nextp == *t || nextp == '[' ) match = Matche( p, t );
        !           173:
        !           174:                /* if the end of text is reached then no match */
        !           175:                if( ! *t++ ) match = MATCH_ABORT;
        !           176:        } while( match != MATCH_VALID && match != MATCH_ABORT && match != MATCH_PATTERN );
        !           177:
        !           178:        /* return result */
        !           179:        return match;
        !           180: } /* Matche_After_Star */
        !           181:
        !           182: /* -eof- */

CVSweb