Permalink
Browse files

add re2_match

  • Loading branch information...
1 parent 41461f2 commit ec6f60c7e1c45b5d85dd246c45b06c0339965aa3 @arraypad committed Jun 13, 2011
Showing with 138 additions and 20 deletions.
  1. +16 −17 config.m4
  2. +11 −1 php_re2.h
  3. +71 −2 re2.cpp
  4. +40 −0 tests/match.phpt
View
@@ -4,29 +4,28 @@ PHP_ARG_WITH(re2, for re2 support,
[ --with-re2 Include re2 support])
if test "$PHP_RE2" != "no"; then
- SEARCH_PATH="/usr/local /usr"
- SEARCH_FOR="/include/re2/re2.h"
- if test -r $PHP_RE2/$SEARCH_FOR; then
- RE2_DIR=$PHP_RE2
- else
- AC_MSG_CHECKING([for re2 files in default path])
- for i in $SEARCH_PATH ; do
- if test -r $i/$SEARCH_FOR; then
- RE2_DIR=$i
- AC_MSG_RESULT(found in $i)
- fi
- done
- fi
+ SEARCH_PATH="$PHP_RE2 /usr/local /usr"
+ SEARCH_INC="include/re2/re2.h"
+ SEARCH_LIB="lib/libre2.so"
+ AC_MSG_CHECKING([for re2 files])
+ for i in $SEARCH_PATH ; do
+ if test -r $i/$SEARCH_INC && test -r $i/$SEARCH_LIB; then
+ RE2_DIR=$i
+ AC_MSG_RESULT(found in $i)
+ fi
+ done
if test -z "$RE2_DIR"; then
AC_MSG_RESULT([not found])
- AC_MSG_ERROR([Please reinstall the re2 distribution])
+ AC_MSG_ERROR([Please ensure the re2 headers and shared library are installed])
fi
- PHP_ADD_INCLUDE($RE2_DIR/include/re2)
- PHP_ADD_LIBRARY(re2)
+ PHP_ADD_INCLUDE($RE2_DIR/include)
PHP_REQUIRE_CXX()
+
PHP_SUBST(RE2_SHARED_LIBADD)
PHP_ADD_LIBRARY(stdc++, 1, RE2_SHARED_LIBADD)
- PHP_NEW_EXTENSION(re2, re2.cpp, $ext_shared)
+ PHP_ADD_LIBRARY_WITH_PATH(re2, $RE2_DIR/lib, RE2_SHARED_LIBADD)
+
+ PHP_NEW_EXTENSION(re2, re2.cpp, $ext_shared,,,1)
fi
View
@@ -12,7 +12,7 @@
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
- | Author: |
+ | Author: Arpad Ray <arpad@php.net> |
+----------------------------------------------------------------------+
*/
@@ -21,6 +21,10 @@
#define PHP_RE2_EXTVER "0.0.1-dev"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern zend_module_entry re2_module_entry;
#define phpext_re2_ptr &re2_module_entry
@@ -36,12 +40,18 @@ extern zend_module_entry re2_module_entry;
#include "TSRM.h"
#endif
+PHP_FUNCTION(re2_match);
+
PHP_MINIT_FUNCTION(re2);
PHP_MSHUTDOWN_FUNCTION(re2);
PHP_RINIT_FUNCTION(re2);
PHP_RSHUTDOWN_FUNCTION(re2);
PHP_MINFO_FUNCTION(re2);
+#ifdef __cplusplus
+}
+#endif
+
#ifdef ZTS
#define RE2_G(v) TSRMG(re2_globals_id, zend_re2_globals *, v)
#else
View
73 re2.cpp
@@ -16,24 +16,91 @@
+----------------------------------------------------------------------+
*/
+extern "C" {
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
+}
+
#include "php_re2.h"
-#include <re2.h>
+#include <re2/re2.h>
+#include <string>
+
+
+/* {{{ arg info */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_re2_match, 0, 0, 2)
+ ZEND_ARG_INFO(0, pattern)
+ ZEND_ARG_INFO(0, subject)
+ ZEND_ARG_INFO(0, argc)
+ ZEND_ARG_INFO(1, matches)
+ZEND_END_ARG_INFO()
+/* }}} */
/* {{{ re2_functions[]
*/
const zend_function_entry re2_functions[] = {
+ PHP_FE(re2_match, arginfo_re2_match)
{NULL, NULL, NULL}
};
/* }}} */
+/* {{{ */
+PHP_FUNCTION(re2_match)
+{
+ char *subject, *pattern;
+ std::string subject_str, pattern_str;
+ int subject_len, pattern_len;
+ long argc;
+ zval *matches = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|lz", &pattern, &pattern_len, &subject, &subject_len, &argc, &matches) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ subject_str = std::string(subject);
+ pattern_str = std::string(pattern);
+
+ if (ZEND_NUM_ARGS() > 2) {
+ int i;
+ std::string str[argc];
+ RE2::Arg argv[argc];
+ RE2::Arg *args[argc];
+
+ for (i = 0; i < argc; i++) {
+ argv[i] = &str[i];
+ args[i] = &argv[i];
+ }
+
+ bool match = RE2::PartialMatchN(subject_str, pattern_str, args, argc);
+
+ if (match) {
+ if (matches != NULL) {
+ zval_dtor(matches);
+ }
+
+ array_init_size(matches, argc);
+ for (i = 0; i < argc; i++) {
+ add_next_index_string(matches, str[i].c_str(), 1);
+ }
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
+ } else {
+ bool match = RE2::PartialMatch(subject_str, pattern_str);
+ if (match) {
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
+ }
+}
+/* }}} */
+
/* {{{ re2_module_entry
*/
zend_module_entry re2_module_entry = {
@@ -55,7 +122,9 @@ zend_module_entry re2_module_entry = {
/* }}} */
#ifdef COMPILE_DL_RE2
+extern "C" {
ZEND_GET_MODULE(re2)
+}
#endif
/* {{{ PHP_MINIT_FUNCTION
View
@@ -0,0 +1,40 @@
+--TEST--
+re2 - re2_match
+--FILE--
+<?php
+
+echo "*** Testing re2_match(): no subpatterns, positive match\n";
+var_dump(re2_match('Hello \w+ world', 'Hello regex world'));
+
+echo "*** Testing re2_match(): no subpatterns, negative match\n";
+var_dump(re2_match('Hello \w+ world', 'Hello "regex" world'));
+
+echo "*** Testing re2_match(): 1 subpattern\n";
+var_dump(re2_match('Hello (\w+) world', 'Hello regex world', 1, $matches), $matches);
+unset($matches);
+
+echo "*** Testing re2_match(): 3 subpatterns\n";
+var_dump(re2_match('(Hello) (\w+) (.*)', 'Hello regex world', 3, $matches), $matches);
+
+?>
+--EXPECTF--
+*** Testing re2_match(): no subpatterns, positive match
+bool(true)
+*** Testing re2_match(): no subpatterns, negative match
+bool(false)
+*** Testing re2_match(): 1 subpattern
+bool(true)
+array(1) {
+ [0]=>
+ string(5) "regex"
+}
+*** Testing re2_match(): 3 subpatterns
+bool(true)
+array(3) {
+ [0]=>
+ string(5) "Hello"
+ [1]=>
+ string(5) "regex"
+ [2]=>
+ string(5) "world"
+}

0 comments on commit ec6f60c

Please sign in to comment.