[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

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