From - Tue Jun 10 10:41:22 2003
Return-Path: <asterisk-dev-admin@lists.digium.com>
Received: from localhost.localdomain (rattler.digium.com [216.207.245.21])
	by quark.dynx.net (8.11.6/8.11.6) with ESMTP id h5ABC7D30762
	for <pchammer@dynx.net>; Tue, 10 Jun 2003 07:12:07 -0400
Received: from localhost.localdomain (localhost.localdomain [127.0.0.1])
	by localhost.localdomain (8.12.5/8.12.5) with ESMTP id h5AG9mCs023860;
	Tue, 10 Jun 2003 11:09:48 -0500
Received: from smtp.inode.at (smtp-02.inode.at [62.99.194.4])
	by localhost.localdomain (8.12.5/8.12.5) with ESMTP id h5AG2lCs023649
	for <asterisk-dev@lists.digium.com>; Tue, 10 Jun 2003 11:02:47 -0500
Received: from torwaechter.inode.at ([213.229.17.132]:2133 helo=inode.at)
	by smtp.inode.at with esmtp (Exim 4.10)
	id 19PlMg-0004UV-00
	for asterisk-dev@lists.digium.com; Tue, 10 Jun 2003 17:48:51 +0200
Message-ID: <3EE5FDE6.4040900@inode.at>
From: Reini Urban <r.urban@inode.at>
Organization: inode.at
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; de-AT; rv:1.4a; MultiZilla v1.4.0.3I) Gecko/20030315
X-Accept-Language: de-at, de, en-us, en
MIME-Version: 1.0
To: asterisk-dev@lists.digium.com
Subject: Re: [Asterisk-Dev] better pattern matcher
References: <3EE029F8.7020709@inode.at> <p0521062bbb05eb85981e@loligo.com> <3EE087CA.3020008@inode.at> <3EE5E8A7.9050400@inode.at>
In-Reply-To: <3EE5E8A7.9050400@inode.at>
Content-Type: multipart/mixed;
 boundary="------------040900050308090004030101"
Sender: asterisk-dev-admin@lists.digium.com
Errors-To: asterisk-dev-admin@lists.digium.com
X-BeenThere: asterisk-dev@lists.digium.com
X-Mailman-Version: 2.0.13
Precedence: bulk
Reply-To: asterisk-dev@lists.digium.com
List-Unsubscribe: <http://lists.digium.com/mailman/listinfo/asterisk-dev>,
	<mailto:asterisk-dev-request@lists.digium.com?subject=unsubscribe>
List-Id: Asterisk Developers Mailing List <asterisk-dev.lists.digium.com>
List-Post: <mailto:asterisk-dev@lists.digium.com>
List-Help: <mailto:asterisk-dev-request@lists.digium.com?subject=help>
List-Subscribe: <http://lists.digium.com/mailman/listinfo/asterisk-dev>,
	<mailto:asterisk-dev-request@lists.digium.com?subject=subscribe>
List-Archive: <http://lists.digium.com/pipermail/asterisk-dev/>
Date: Tue, 10 Jun 2003 17:48:54 +0200
Status:  O
X-Mozilla-Status: 8011
X-Mozilla-Status2: 00000000
X-UIDL: 3ee5ca5b00000099

This is a multi-part message in MIME format.
--------------040900050308090004030101
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Reini Urban wrote:
> This is my matcher. Most code is in public domain.

And attached is the patch to pbx.c to be applied to CVS.

>> well, for the beginning I added support to continue to match after a "."
>> to be able to add extensions after the dialed number and not only 
>> before. :)
>>
>> e.g "_0N.8500" matches my voicemail extension for all dialed numbers.
>>
>> I'll commit this short patch on Tuesday, because I have to do more 
>> testing and the weekend is free.
-- 
Reini Urban - Entwicklung - http://inode.at

--------------040900050308090004030101
Content-Type: text/plain;
 name="matcher.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="matcher.patch"

Index: pbx.c
===================================================================
RCS file: /usr/cvsroot/asterisk/pbx.c,v
retrieving revision 1.21
diff -u -b -b -u -r1.21 pbx.c
--- pbx.c	22 May 2003 04:38:46 -0000	1.21
+++ pbx.c	10 Jun 2003 16:04:59 -0000
@@ -148,6 +148,7 @@
     struct ast_hint *next;
 };
 
+int ast_extension_patmatch(const char *pattern, const char *data);
 
 static int pbx_builtin_prefix(struct ast_channel *, void *);
 static int pbx_builtin_suffix(struct ast_channel *, void *);
@@ -558,16 +559,100 @@
 	}\
 }
 
+/* derived from code by Steffen Offermann 1991 (public domain)
+   http://www.cs.umu.se/~isak/Snippets/xstrcmp.c
+*/
+int ast_extension_patmatch(const char *pattern, const char *data) 
+{
+    ast_log(LOG_DEBUG, " >>> %s =~ /%s/\n", data, pattern);
+    switch (toupper(*pattern))
+	{
+	case '\0':
+	    ast_log(LOG_DEBUG, " !>>> %s => %s\n", data, !*data ? "OK" : "FAIL");
+	    return !*data;
+	    
+	case ' ':
+	case '-':
+	    /* Ignore these characters in the pattern */
+	    return *data && ast_extension_patmatch(pattern+1, data);
+
+	case '.' : /* wildcard */
+	    if (! *(pattern+1) ) 
+		return *data;
+	    else
+		return ast_extension_patmatch(pattern+1, data) || (*data && ast_extension_patmatch(pattern, data+1));
+
+/*	    
+	case '?' :
+	    return *data && ast_extension_patmatch(pattern+1, data+1);
+*/	    
+	case 'X':
+	    return ((*data >= '0') && (*data <= '9')) && ast_extension_patmatch(pattern+1, data+1);
+	    
+	case 'Z':
+	    return ((*data >= '1') && (*data <= '9')) && ast_extension_patmatch(pattern+1, data+1);
+	    
+	case 'N':
+	    return ((*data >= '2') && (*data <= '9')) && ast_extension_patmatch(pattern+1, data+1);
+	    
+	case '[':
+	    /* Begin Mark Spencer CODE */
+	    {
+		int i,border=0;
+		char *where;
+		pattern++;
+		where=strchr(pattern,']');
+		if (where)
+		    border=(int)(where-pattern);
+		if (!where || border > strlen(pattern)) {
+		    ast_log(LOG_WARNING, "Wrong [%s] pattern usage\n", pattern);
+		    return 0;
+		}
+		for (i=0; i<border; i++) {
+		    if (i+2<border) {
+			if (*data==pattern[i])
+			    return 1;
+		        else if (pattern[i+1]=='-') {
+			    if (*data >= pattern[i] && *data <= pattern[i+2]) {
+				return ast_extension_patmatch(where+1, data+1);
+			    } else {
+				i+=2;
+				continue;
+			    }
+			}
+		    }
+		}
+		pattern+=border;
+		break;
+	    }
+	    /* End Mark Spencer CODE */
+	    
+	default  :
+	    return (toupper(*pattern) == toupper(*data)) && ast_extension_patmatch(pattern+1, data+1);
+	}
+    return 0;
+}
+
 int ast_extension_match(char *pattern, char *data)
 {
 	int match;
-	/* If they're the same return */
-	if (!strcmp(pattern, data))
-		return 1;
-	EXTENSION_MATCH_CORE(data,pattern,match);
-	/* Must be at the end of both */
-	if (*data || (*pattern && (*pattern != '/')))
-		match = 0;
+	if (!*pattern) {
+	    ast_log(LOG_WARNING, "ast_extension_match: empty pattern\n");
+	    return 0;
+	}
+	if (!*data) {
+	    ast_log(LOG_WARNING, "ast_extension_match: empty data\n");
+	    return 0;
+	}
+	if (pattern[0] != '_') {
+	    match = (strcmp(pattern, data) == 0);
+	    ast_log(LOG_DEBUG, "ast_extension_match %s == /%s/", data, pattern);
+	    return (strcmp(pattern, data) == 0);
+	} else {
+	    ast_log(LOG_DEBUG, "ast_extension_match %s =~ /%s/", data, pattern);
+	    match = ast_extension_patmatch(data,pattern+1);
+	}
+	ast_log(LOG_DEBUG, " => %d\n", match);
 	return match;
 }
 
@@ -583,7 +668,9 @@
 		(!needmore || (strlen(pattern) > strlen(data)))) {
 		return 1;
 	}
-	EXTENSION_MATCH_CORE(data,pattern,match);
+	if (pattern[0] == '_') {
+	    match = ast_extension_patmatch(data,pattern+1);
+	}
 	/* If there's more or we don't care about more, return non-zero, otlherwise it's a miss */
 	if (!needmore || *pattern) {
 		return match;

--------------040900050308090004030101--

_______________________________________________
Asterisk-Dev mailing list
Asterisk-Dev@lists.digium.com
http://lists.digium.com/mailman/listinfo/asterisk-dev
