From 870a3ef8ffa23a0e62d6036586cab5312f915ed1 Mon Sep 17 00:00:00 2001
From: Michael Jerris <mike@jerris.com>
Date: Tue, 23 Sep 2008 16:05:12 +0000
Subject: [PATCH] (FSCORE-192) expose api for partial regex matching

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9623 d0543943-73ff-0310-b7d9-9358b9ac24b2
---
 src/include/switch_regex.h | 11 +++++++++++
 src/switch_regex.c         | 23 ++++++++++++++++++++---
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/src/include/switch_regex.h b/src/include/switch_regex.h
index 6c92d58e81..e73e030e1d 100644
--- a/src/include/switch_regex.h
+++ b/src/include/switch_regex.h
@@ -61,11 +61,22 @@ SWITCH_DECLARE(void) switch_perform_substitution(switch_regex_t *re, int match_c
 */
 SWITCH_DECLARE(switch_status_t) switch_regex_match(const char *target, const char *expression);
 
+/*!
+ \brief Function to evaluate an expression against a string
+ \param target The string to find a match in
+ \param expression The regular expression to run against the string
+ \param partial If non-zero returns SUCCESS if the target is a partial match, on successful return, this is set to non-zero if the match was partial and zero if it was a full match
+ \return Boolean if a match was found or not
+*/
+SWITCH_DECLARE(switch_status_t) switch_regex_match_partial(const char *target, const char *expression, int * partial_match);
+
+
 #define switch_regex_safe_free(re)	if (re) {\
 				switch_regex_free(re);\
 				re = NULL;\
 			}
 
+
 /** @} */
 
 SWITCH_END_EXTERN_C
diff --git a/src/switch_regex.c b/src/switch_regex.c
index 651d89e310..93b28f03e4 100644
--- a/src/switch_regex.c
+++ b/src/switch_regex.c
@@ -161,14 +161,15 @@ SWITCH_DECLARE(void) switch_perform_substitution(switch_regex_t *re, int match_c
 	substituted[y++] = '\0';
 }
 
-SWITCH_DECLARE(switch_status_t) switch_regex_match(const char *target, const char *expression)
+SWITCH_DECLARE(switch_status_t) switch_regex_match_partial(const char *target, const char *expression, int * partial)
 {
 	const char *error = NULL;	/* Used to hold any errors                                           */
 	int error_offset = 0;		/* Holds the offset of an error                                      */
 	pcre *pcre_prepared = NULL;	/* Holds the compiled regex                                          */
 	int match_count = 0;		/* Number of times the regex was matched                             */
 	int offset_vectors[2];		/* not used, but has to exist or pcre won't even try to find a match */
-
+	int pcre_flags = 0;
+	
 	/* Compile the expression */
 	pcre_prepared = pcre_compile(expression, 0, &error, &error_offset, NULL);
 
@@ -186,8 +187,13 @@ SWITCH_DECLARE(switch_status_t) switch_regex_match(const char *target, const cha
 		/* We definitely didn't match anything */
 		return SWITCH_STATUS_FALSE;
 	}
+	
+	if (*partial) {
+		pcre_flags = PCRE_PARTIAL;
+	}
+	
 	/* So far so good, run the regex */
-	match_count = pcre_exec(pcre_prepared, NULL, target, (int) strlen(target), 0, 0, offset_vectors, sizeof(offset_vectors) / sizeof(offset_vectors[0]));
+	match_count = pcre_exec(pcre_prepared, NULL, target, (int) strlen(target), 0, pcre_flags, offset_vectors, sizeof(offset_vectors) / sizeof(offset_vectors[0]));
 
 	/* Clean up */
 	if (pcre_prepared) {
@@ -199,12 +205,23 @@ SWITCH_DECLARE(switch_status_t) switch_regex_match(const char *target, const cha
 
 	/* Was it a match made in heaven? */
 	if (match_count > 0) {
+		*partial = 0;
+		return SWITCH_STATUS_SUCCESS;
+	} else if (match_count == PCRE_ERROR_PARTIAL) {
+		/* yes it is already set, but the code is clearer this way */
+		*partial = 1;
 		return SWITCH_STATUS_SUCCESS;
 	} else {
 		return SWITCH_STATUS_FALSE;
 	}
 }
 
+SWITCH_DECLARE(switch_status_t) switch_regex_match(const char *target, const char *expression)
+{
+	int partial = 0;
+	return switch_regex_match_partial(target, expression, &partial);
+}
+
 /* For Emacs:
  * Local Variables:
  * mode:c