├── .gitignore ├── AUTHORS ├── COPYING ├── ChangeLog ├── INSTALL ├── LICENSE ├── Makefile.am ├── Makefile.in ├── NEWS ├── README.md ├── aclocal.m4 ├── config.h.in ├── config.h.in~ ├── config ├── ._ax_lib_mysql.m4 ├── ax_lib_mysql.m4 ├── ax_mysql_bin.m4 ├── ax_pthread.m4 ├── ax_pthread_np.m4 ├── compile ├── config.guess ├── config.sub ├── depcomp ├── ghmysql.m4 ├── install-sh ├── ltmain.sh ├── missing └── pcre.m4 ├── configure ├── configure.ac ├── doc ├── Doxyfile ├── INSTALL.windows ├── Makefile.am ├── Makefile.in ├── index.html ├── index.php.in └── mainpage.c ├── from_php.c ├── from_php.h ├── ghfcns.c ├── ghfcns.h ├── ghmysql.c ├── ghmysql.h ├── installdb.sql ├── lib_mysqludf_preg_capture.c ├── lib_mysqludf_preg_check.c ├── lib_mysqludf_preg_info.c ├── lib_mysqludf_preg_position.c ├── lib_mysqludf_preg_replace.c ├── lib_mysqludf_preg_rlike.c ├── preg.c ├── preg.h ├── preg_utils.c ├── preg_utils.h ├── test ├── Makefile.am ├── Makefile.in ├── ManualTests.txt ├── create_testdb.sql ├── lib_mysqludf_preg_capture.result ├── lib_mysqludf_preg_capture.test ├── lib_mysqludf_preg_check.result ├── lib_mysqludf_preg_check.test ├── lib_mysqludf_preg_info.result ├── lib_mysqludf_preg_info.test ├── lib_mysqludf_preg_position.result ├── lib_mysqludf_preg_position.test ├── lib_mysqludf_preg_replace.result ├── lib_mysqludf_preg_replace.test ├── lib_mysqludf_preg_rlike.result └── lib_mysqludf_preg_rlike.test └── uninstalldb.sql /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | doc/html/doxygen.css 3 | doc/html/doxygen.png 4 | doc/html/index.html 5 | .deps/ 6 | .libs/ 7 | Makefile 8 | autom4te.cache/ 9 | config.h 10 | config.log 11 | config.status 12 | doc/Makefile 13 | doc/html/ 14 | doc/index.php 15 | doc/lib_mysqludf_preg.frag 16 | lib_mysqludf_preg-1.0.2.tar.gz 17 | lib_mysqludf_preg.la 18 | lib_mysqludf_preg_la-from_php.lo 19 | lib_mysqludf_preg_la-from_php.o 20 | lib_mysqludf_preg_la-ghmysql.lo 21 | lib_mysqludf_preg_la-ghmysql.o 22 | lib_mysqludf_preg_la-lib_mysqludf_preg_capture.lo 23 | lib_mysqludf_preg_la-lib_mysqludf_preg_capture.o 24 | lib_mysqludf_preg_la-lib_mysqludf_preg_check.lo 25 | lib_mysqludf_preg_la-lib_mysqludf_preg_check.o 26 | lib_mysqludf_preg_la-lib_mysqludf_preg_info.lo 27 | lib_mysqludf_preg_la-lib_mysqludf_preg_info.o 28 | lib_mysqludf_preg_la-lib_mysqludf_preg_position.lo 29 | lib_mysqludf_preg_la-lib_mysqludf_preg_position.o 30 | lib_mysqludf_preg_la-lib_mysqludf_preg_replace.lo 31 | lib_mysqludf_preg_la-lib_mysqludf_preg_replace.o 32 | lib_mysqludf_preg_la-lib_mysqludf_preg_rlike.lo 33 | lib_mysqludf_preg_la-lib_mysqludf_preg_rlike.o 34 | lib_mysqludf_preg_la-preg.lo 35 | lib_mysqludf_preg_la-preg.o 36 | lib_mysqludf_preg_la-ghfcns.lo 37 | lib_mysqludf_preg_la-ghfcns.o 38 | lib_mysqludf_preg_la-pregUtils.lo 39 | lib_mysqludf_preg_la-pregUtils.o 40 | lib_mysqludf_preg_la-preg_utils.lo 41 | lib_mysqludf_preg_la-preg_utils.o 42 | test/lib_mysqludf_preg_capture.log 43 | test/lib_mysqludf_preg_check.log 44 | test/lib_mysqludf_preg_info.log 45 | test/lib_mysqludf_preg_position.log 46 | test/lib_mysqludf_preg_replace.log 47 | test/lib_mysqludf_preg_rlike.log 48 | libtool 49 | stamp-h1 50 | test/Makefile 51 | lib_mysqludf_preg-*.tar.gz 52 | 53 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | 2 | UDFs 3 | ---- 4 | PREG_CAPTURE - Rich Waters 5 | PREG_RLIKE - Rich Waters 6 | PREG_REPLACE - Rich Waters 7 | LIB_MYSQLUDF_PREG_INFO - Rich Waters 8 | 9 | 10 | Regex Compilation & PCRE 11 | ------------------------ 12 | from_php.c - contains code that was written for php by Philip Hazel. 13 | libpcre, itself, was also written by Philip Hazel. 14 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | 2 | =========================================================================== 3 | License for the lib_mysqludf_pref library, excluding the code in from_php.c 4 | =========================================================================== 5 | 6 | Copyright (C) 2007-2013 Rich Waters 7 | 8 | The MIT License (MIT) 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | 29 | 30 | 31 | 32 | =========================================================================== 33 | License for the code in from_php.c 34 | =========================================================================== 35 | PCRE is a library of functions to support regular expressions whose syntax 36 | and semantics are as close as possible to those of the Perl 5 language. 37 | 38 | Written by Philip Hazel 39 | Copyright (c) 1997-2006 University of Cambridge 40 | 41 | ----------------------------------------------------------------------------- 42 | Redistribution and use in source and binary forms, with or without 43 | modification, are permitted provided that the following conditions are met: 44 | 45 | * Redistributions of source code must retain the above copyright notice, 46 | this list of conditions and the following disclaimer. 47 | 48 | * Redistributions in binary form must reproduce the above copyright 49 | notice, this list of conditions and the following disclaimer in the 50 | documentation and/or other materials provided with the distribution. 51 | 52 | * Neither the name of the University of Cambridge nor the names of its 53 | contributors may be used to endorse or promote products derived from 54 | this software without specific prior written permission. 55 | 56 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 57 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 58 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 59 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 60 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 61 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 62 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 63 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 64 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 65 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 66 | POSSIBILITY OF SUCH DAMAGE. 67 | ----------------------------------------------------------------------------- 68 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | 2 | 1.2 3 | === 4 | - Fixed problems with preg_position 5 | - Documentation improvements 6 | - Fixed crashes when caused by pcre recursion exceeding stack limits 7 | - Changed to MIT license from LGPL 8 | - Improved error reporting 9 | 10 | 11 | 1.1 12 | --- 13 | Fixed potential garbage results due to uninitialized argument to pcre_exec 14 | Return NULL in most cases when NULL is passed in as an argument 15 | Fixed problem where PREG_CAPTURE didn't return NULL if occurrence was out of bounds 16 | 17 | 18 | 1.0.1 19 | ----- 20 | Fixed autoconf with pcre on Snow Leaopard by upgrading to new pcre.m4 21 | 22 | 1.0 23 | --- 24 | Install correctly into plugin directory for 5.1 versions of mysql 25 | Fixed problem causing mysqltest to crash 26 | Added PCRE_CHECK function to test if string is a valid pcre 27 | Improved configure script to check some standard locations for pcre library 28 | Fixed preg_capture and preg_position tests so orders are deterministic 29 | 30 | 31 | 0.8.1 32 | ----- 33 | Ported to Windows usiong MinGW 34 | Added option for configure --with-mysqlinclude instead of mysql_config instead 35 | of relying on mysql_config 36 | 37 | 38 | 0.7.1 39 | ----- 40 | Fixed some documentation generation problems 41 | 42 | 43 | 0.7.0 44 | ----- 45 | Made group argument of preg_capture optional 46 | Changed preg_offset to preg_position since it does not return an offset 47 | Added documentation for preg_position 48 | Modified documentation of preg_capture to include occurence argument 49 | Autogenerate more of the documentation 50 | 51 | 52 | 0.6.7 53 | ----- 54 | Added preg_offset function 55 | Added preg_capture argument that specifies the match occurence to capture from 56 | 57 | 58 | 0.6.6 59 | ----- 60 | Repository checkpoint to overcome the missing 0.6.5 tag 61 | 62 | 63 | 0.6.5 64 | ----- 65 | Fixed possible overflow bug in preg_replace 66 | Fixed problem with older pcre annd undefined PCRE_EXTRA_MATCH_LIMIT_RECURSION 67 | 68 | 69 | 0.6.4 70 | ----- 71 | Modified ax_mysql_bin.m4 macros to use path if available 72 | Modified ax_mysql_bin.m4 to work without -p if not needed 73 | Fixed ax_mysql_bin.m4 MYSQLBIN_PATH error due to extra spaces before = 74 | 75 | 76 | 0.6.3 77 | ----- 78 | Fixed preg_replace bug - longblobs columns could caused crash 79 | Fixed preg_capture bug - handling error return from pregCreateOffsetsVector 80 | Added maintainer-diff target to Makefile.am for diffing with svn tag 81 | Incorporated Arnold's ax_mysql_bin.m4 macros 82 | 83 | 84 | 0.6.2 85 | ------ 86 | Fixed overflow bug that could cause crash in preg_capture. 87 | Fixed bug in preg_capture that caused initid->max_length to be sent incorrectly 88 | Fixed memory leaks in preg_capture by reorganizing alloc for string returns 89 | Removed arbitrary limit on requested capture group number in preg_capture 90 | Added preg_replace function 91 | Made fixes to autotools set up and added config directory 92 | Separated tests into separate set for each UDF. 93 | Added appropriate --disable_warnings to tests when dropping tables & dbs 94 | Added Makefile.am to test subdirectory and added target to create results 95 | 96 | 97 | 0.6.1 98 | ----- 99 | Changed names from libmysql_udf_... to lib_mysqludf_... 100 | Removed 'gh' prefix from SQL functions names and other places 101 | Changed pcre_ prefix to preg_ for all functions so as to collision with libpcre 102 | Fixed configure.ac so that PACKAGE_ veriables are correctly set 103 | Enhanced documentation 104 | Removed some of the less useful doxgen generated files from the distribution 105 | 106 | 107 | 0.5.2 108 | ----- 109 | Fixed file naming problems and README 110 | First public release 111 | 112 | 113 | 0.5.1 114 | ----- 115 | Almost the initial public release 116 | 117 | 118 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | 2 | 3 | lib_mysqludf_preg - PCRE functions for mysql 4 | =============================================== 5 | 6 | 7 | == Configuration == 8 | 9 | Most users should be able to simply type ./configure to run the configuration 10 | script. If mysql is in an unusual place, try: 11 | 12 | ./configure --with-mysql=/mysql_config 13 | 14 | If libpcre is in an unusual place, try adding: 15 | 16 | --with-pcre-prefix= 17 | 18 | Version 1.1 changes the way NULLs are handled. To restore the legacy NULL handling: 19 | 20 | --enable-legacy-nulls 21 | 22 | 23 | Example (on Ubuntu 20.04 with MySQl 8.0.28) 24 | ------------------------------ 25 | == Install Build Libraries == 26 | `sudo apt install build-essential libpcre3-dev git autoconf libtool libmysqlclient-dev` 27 | 28 | == Configure == 29 | `autoreconf -f -i` 30 | `./configure` 31 | `make` 32 | `sudo make install` 33 | ` mysql -u root -p < installdb.sql` 34 | 35 | Example (on macosx with fink) 36 | ------------------------------ 37 | ./configure --with-pcre-prefix=/sw --with-mysql=/sw/bin/mysql_config 38 | 39 | Please use: ./configure --help to see the other options 40 | 41 | Example (on macosx with MAMP) 42 | ------------------------------ 43 | Follow the example at the link below to compile Mysql and place the lib files in the correct folders 44 | http://addto.it/Patching-MAMP-2.0.5-to-work-with-Sphinx-2.02 45 | 46 | Then configure lib_mysqludf_preg with 47 | ./configure --with-mysql=/Applications/MAMP/Library/bin/mysql_config 48 | 49 | == Compile == 50 | Type make 51 | 52 | 53 | == Install the library == 54 | make install 55 | 56 | This will install the library in the configured installation directory, 57 | which is defaulted to /usr/local/lib. For the mysql-5.0 series, 58 | this will need to be in the LD_LIBRARY_PATH of the server. For the 59 | 5.1 series server, this directory needs to be the 'plugin' directory 60 | (and still needs to be in the LD_LIBRARY_PATH) of the server). 61 | 62 | 63 | == Install the SQL functions == 64 | 65 | make installdb 66 | 67 | If you receive an 'access denied' type of an error, try using something like: 68 | 69 | make MYSQL="mysql -p" installdb 70 | 71 | to enable the ability to enter a password. 72 | 73 | 74 | To uninstall the functions, you can use: make uninstalldb 75 | 76 | == Run some tests == 77 | make test 78 | 79 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | =========================================================================== 3 | License for the lib_mysqludf_pref library, excluding the code in from_php.c 4 | =========================================================================== 5 | 6 | Copyright (C) 2007-2013 Rich Waters 7 | 8 | The MIT License (MIT) 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | 29 | 30 | 31 | 32 | =========================================================================== 33 | License for the code in from_php.c 34 | =========================================================================== 35 | PCRE is a library of functions to support regular expressions whose syntax 36 | and semantics are as close as possible to those of the Perl 5 language. 37 | 38 | Written by Philip Hazel 39 | Copyright (c) 1997-2006 University of Cambridge 40 | 41 | ----------------------------------------------------------------------------- 42 | Redistribution and use in source and binary forms, with or without 43 | modification, are permitted provided that the following conditions are met: 44 | 45 | * Redistributions of source code must retain the above copyright notice, 46 | this list of conditions and the following disclaimer. 47 | 48 | * Redistributions in binary form must reproduce the above copyright 49 | notice, this list of conditions and the following disclaimer in the 50 | documentation and/or other materials provided with the distribution. 51 | 52 | * Neither the name of the University of Cambridge nor the names of its 53 | contributors may be used to endorse or promote products derived from 54 | this software without specific prior written permission. 55 | 56 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 57 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 58 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 59 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 60 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 61 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 62 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 63 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 64 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 65 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 66 | POSSIBILITY OF SUCH DAMAGE. 67 | ----------------------------------------------------------------------------- 68 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | AUTOMAKE_OPTIONS = foreign 3 | 4 | .PHONY : test mrproper 5 | 6 | lib_LTLIBRARIES = lib_mysqludf_preg.la 7 | 8 | CFILES= \ 9 | preg.c \ 10 | preg_utils.c \ 11 | ghmysql.c \ 12 | ghfcns.c \ 13 | from_php.c \ 14 | lib_mysqludf_preg_capture.c \ 15 | lib_mysqludf_preg_check.c \ 16 | lib_mysqludf_preg_info.c \ 17 | lib_mysqludf_preg_position.c \ 18 | lib_mysqludf_preg_replace.c \ 19 | lib_mysqludf_preg_rlike.c 20 | 21 | HFILES = \ 22 | preg.h \ 23 | ghmysql.h \ 24 | ghfcns.h \ 25 | preg_utils.h \ 26 | from_php.h 27 | 28 | lib_mysqludf_preg_la_SOURCES = \ 29 | $(CFILES) \ 30 | $(HFILES) 31 | 32 | DLL_OBJS=$(CFILES:%.c=.libs/lib_mysqludf_preg_la-%.o) 33 | 34 | SUBDIRS=test doc 35 | DIFFPROGRAM:=kompare - 36 | 37 | lib_mysqludf_preg_la_CFLAGS = -DSTANDARD -DMYSQL_SERVER @MYSQL_CFLAGS@ @MYSQL_HEADERS@ @PCRE_CFLAGS@ @GHMYSQL_CFLAGS@ @PTHREAD_CFLAGS@ 38 | #lib_mysqludf_preg_la_LDFLAGS = -module -avoid-version -no-undefined @PCRE_LIBS@ @PTHREAD_LIBS@ 39 | lib_mysqludf_preg_la_LDFLAGS = -module -avoid-version @PCRE_LIBS@ @PTHREAD_LIBS@ 40 | 41 | EXTRA_DIST = *.sql 42 | 43 | mrproper: clean maintainer-clean 44 | for i in $(SUBDIRS) . ; do ( cd $$i && rm -rf config/config.guess config.h.* config/config.status configure config/missing config/config.sub config/ltmain.sh config/depcomp aclocal.m4 config/install-sh config.log installdb_win.sql config/compile Makefile.in *.tar.gz *.loT config/mkinstalldirs *~); done 45 | 46 | mysqlbin: 47 | @if test -z "$(MYSQL)" ; then echo "mysql client app (mysql) not found"; exit 1; fi 48 | 49 | installdb_win.sql:installdb.sql 50 | cat installdb.sql | sed 's/\.so/.dll/g' >installdb_win.sql 51 | 52 | installdb: uninstalldb installdb_win.sql 53 | if test -f .libs/lib_mysqludf_preg.dll; then \ 54 | $(MYSQL) <./installdb_win.sql; \ 55 | else \ 56 | $(MYSQL) <./installdb.sql;\ 57 | fi 58 | 59 | uninstalldb: mysqlbin 60 | $(MYSQL) <./uninstalldb.sql 61 | 62 | test: 63 | cd test; make test 64 | 65 | dist-hook: 66 | rm -rf `find $(distdir) -name .svn` 67 | rm -rf `find $(distdir) -name .git` 68 | rm -rf `find $(distdir) -name .DS_Store` 69 | 70 | maintainer-dist: 71 | make dist 72 | git tag "$(PACKAGE)-$(VERSION)" 73 | 74 | maintainer-diff: 75 | git diff "$(PACKAGE)-$(DIFFVERSION)" . | $(DIFFPROGRAM) 76 | 77 | lib_mysqludf_preg.dll: $(DLL_OBJS) 78 | $(CC) -shared -o lib_mysqludf_preg.dll -Wl,"--strip-all" -Wl,"--export-all-symbols" $(DLL_OBJS) /opt/mingw/pcre/lib/libpcre.a 79 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysqludf/lib_mysqludf_preg/6395901adaf987a9f9e4e1b859daad4f2d665eff/NEWS -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | lib_mysqludf_preg 3 | ================= 4 | PREG functions for mysql 5 | ------------------------ 6 | 7 | lib_mysqludf_preg is a library of mysql UDFs (user-defined-functions) 8 | that provide access to the PCRE (perl compatible-regular-expressions) 9 | library for pattern matching. The PCRE library is a set of functions 10 | that implement regular expression pattern matching using the same 11 | syntax and semantics as Perl 5. This syntax can often handle more 12 | complex expressions and capturing than standard regular expression 13 | implementations. For more information about PCRE, please see: 14 | http://www.pcre.org/. 15 | 16 | lib_mysqludf_preg currently provides the following functions: 17 | 18 | `PREG_RLIKE( pattern , subject )` - test whether subject matches pattern, 19 | which is a perl compatible regular expression. 20 | 21 | `PREG_CAPTURE(pattern, subject [, capture-group] [, occurence] )` - capture a 22 | named or numeric parenthesized subexpression from a pcre pattern. Capture 23 | from a specific match of the regex or the first match is occurence 24 | not specified. 25 | 26 | `PREG_CHECK( pattern )` - test whether the given pattern is a valid perl 27 | compatible regular expression. 28 | 29 | `PREG_POSITION(pattern, subject [, capture-group] [, occurence] )` - get the 30 | position in subject of a named or numeric parenthesized subexpression 31 | from a pcre pattern. Capture from a specific match of the regex or 32 | the first match if occurence not specified. 33 | 34 | `PREG_REPLACE(pattern, replacement, subject [ ,limit ] )` - perform 35 | a regular expression search and replace using a PCRE pattern. 36 | 37 | `LIB_MYSQLUDF_PREG_INFO()` - obtain information about the currently installed 38 | version of lib_mysqludf_preg. 39 | 40 | 41 | 42 | Some examples: 43 | ------------- 44 | ```SQL 45 | SELECT captured, description FROM 46 | (SELECT PREG_CAPTURE( '/(new)\\\\s+([a-zA-Z]*)(.*)/i' , description, 2 ) as captured FROM state WHERE description LIKE 'new%') as t1 47 | WHERE captured IS NOT NULL; 48 | ``` 49 | 50 | ```SQL 51 | SELECT position, description FROM 52 | (SELECT PREG_POSITION( '/(new)\\\\s+([a-zA-Z]*)(.*)/i' , description, 2 ) as position FROM state WHERE description LIKE 'new%') as t1 53 | WHERE position IS NOT NULL; 54 | ``` 55 | 56 | ```SQL 57 | SELECT * from products WHERE PREG_RLIKE( '/hemp/i' , products.title ) 58 | ``` 59 | 60 | ```SQL 61 | SELECT CONVERT( PREG_REPLACE( '/fox/i' , 'dog' , 'The brown fox' ) USING UTF8) as replaced; 62 | ``` 63 | 64 | Please see test/lib_udfmysql_preg.test and test/lib_udfmysql_preg.result for 65 | more examples. 66 | 67 | 68 | 69 | More Documentation 70 | ------------------ 71 | Please see doc/html/index.html for more detailed documentation 72 | of the SQL functions. 73 | 74 | 75 | 76 | Installation 77 | ============ 78 | Please see the file INSTALL or (doc/INSTALL.windows) 79 | for the full installation instructions. 80 | 81 | The short instructions are: 82 | 83 | ./configure; make install; make installdb ; make test 84 | 85 | 86 | 87 | Getting lib_mysqludf_preg 88 | =========================== 89 | The best place to get the library is from the github repository at: https://github.com/mysqludf/lib_mysqludf_preg. Please help with the testing by using the code on the testing branch. You can also download tarred source archives from http://www.goodhumans.com/Misc/lib_mysqludf/. 90 | 91 | 92 | 93 | Reporting Bugs & Feedback 94 | ========================= 95 | Please send information regarding bugs and any other feedback to: 96 | raw@goodhumans.net 97 | 98 | 99 | 100 | Known Issues & Caveats 101 | ====================== 102 | - Version 1.2 respects mysqld stack limitations. This should reduce crashing, but you might need to set the thread_stack mysqld variable in order to accommodate some recursion intensive patterns. 103 | - Version 1.1 changes the way NULLs are handled. To restore the legacy NULL handling, use configure --enable-legacy-nulls 104 | - pcre_study should be used (but isn't) for constant patterns; 105 | - there is no localization or locale support 106 | - some program locations that should be set in autoconf are not 107 | - It would be nice if there were a persistent cache of compiled regexes 108 | - It would also be nice if there were a peresistent cache of regex matches. 109 | This would allow for a more efficient way of retrieving multiple matches than 110 | repeated called with different 'occurence' arguments. 111 | 112 | 113 | 114 | When & When not to use these UDF's 115 | ================================== 116 | These UDF's are useful in the following circumstances: 117 | - you already have pcre regex's that need to be applied in mysql 118 | - you need to use a more complex regex than is supported by RLIKE 119 | - you need to capture portions of a regex from mysql 120 | - you are looking for a slight performance improvement over RLIKE 121 | 122 | For optimal performance, these (or any) UDF's should not be used: 123 | - as a replacement for a prefixed LIKE or RLIKE (ie. LIKE 'foo%') 124 | - as a replacement for MATCH .. AGAINST ... IN BOOLEAN MODE. 125 | - on large databases without other query constraints. Often the PCRE (or 126 | any function or UDF) can be used in conjunction with a fulltext index 127 | constraint in order to reduce the number of rows the need to be operated on. 128 | (ie. `SELECT PREG_CAPTURE ... WHERE MATCH AGAINST`) 129 | 130 | 131 | 132 | Motivations & Explanations 133 | ========================== 134 | -The 'occurence' argument to PREG_CAPTURE and PREG_POSITION was originally 135 | thought not to be needed, since the {} notation in the regex itself 136 | could be used. For instance, /.{2}(.)/ could be used to get the 137 | 3rd character of a string. This was found not to work for a 138 | large 'occurence'. (ie. /.{65536}(.)/) 139 | 140 | 141 | 142 | Copyright and copying: 143 | ====================== 144 | Copyright (C) 2007-2013 Rich Waters . 145 | 146 | This file and most contents of this package are licensed under The 147 | MIT License. Please see the COPYING file in this directory for details. 148 | 149 | 150 | Acknowledgements 151 | ================ 152 | The amazing PCRE was written by Philip Hazel, and this project uses 153 | some of his code from the php preg extension in from_php.c 154 | 155 | The documentation for this project is generated using 156 | doxygen which is available at: http://www.stack.nl/~dimitri/doxygen/ 157 | 158 | I referenced the following projects while trying to put together this 159 | library: 160 | 161 | http://udf-regexp.php-baustelle.de/trac/ - a UDF that implements Oracle-like 162 | REGEX functions - written by Hartmut Holzgraefe 163 | 164 | http://www.github.com/mysqludf - The repository for MySQL UDFs. 165 | 166 | Much of the documentation was generated using Doxygen, at 167 | http://www.stack.nl/~dimitri/doxygen/ , which was written 168 | by Dimitri van Heesch. 169 | 170 | lib_mysqludf_preg bug fixes & improvements have been contributed by Dan Kozlowski, Serkan Serttop, Travers Carter, employees of the NY State Senate, and some other folks :>). If that includes you and you'd like to be listed here, please send me an email. 171 | 172 | -------------------------------------------------------------------------------- /config.h.in: -------------------------------------------------------------------------------- 1 | /* config.h.in. Generated from configure.ac by autoheader. */ 2 | 3 | /* Is pthread_attr_get_np() declared in ? */ 4 | #undef ATTRGETNP_NOT_DECLARED 5 | 6 | /* Is pthread_getattr_np declared in ? */ 7 | #undef GETATTRNP_NOT_DECLARED 8 | 9 | /* Define to 1 if you have the header file. */ 10 | #undef HAVE_DLFCN_H 11 | 12 | /* Define to 1 if you have the header file. */ 13 | #undef HAVE_INTTYPES_H 14 | 15 | /* Define to 1 if you have the header file. */ 16 | #undef HAVE_MEMORY_H 17 | 18 | /* Define to 1 if MySQL libraries are available */ 19 | #undef HAVE_MYSQL 20 | 21 | /* Define if you have POSIX threads libraries and header files. */ 22 | #undef HAVE_PTHREAD 23 | 24 | /* Do we want a BSD-like thread-attribute interface? */ 25 | #undef HAVE_PTHREAD_ATTR_GET_NP 26 | 27 | /* Define to 1 if you have the `pthread_attr_setstacksize' function. */ 28 | #undef HAVE_PTHREAD_ATTR_SETSTACKSIZE 29 | 30 | /* Do we want a Linux-like thread-attribute interface? */ 31 | #undef HAVE_PTHREAD_GETATTR_NP 32 | 33 | /* Define to 1 if you have the `pthread_get_stacksize_np' function. */ 34 | #undef HAVE_PTHREAD_GET_STACKSIZE_NP 35 | 36 | /* Have PTHREAD_PRIO_INHERIT. */ 37 | #undef HAVE_PTHREAD_PRIO_INHERIT 38 | 39 | /* Define to 1 if you have the header file. */ 40 | #undef HAVE_STDINT_H 41 | 42 | /* Define to 1 if you have the header file. */ 43 | #undef HAVE_STDLIB_H 44 | 45 | /* Define to 1 if you have the header file. */ 46 | #undef HAVE_STRINGS_H 47 | 48 | /* Define to 1 if you have the header file. */ 49 | #undef HAVE_STRING_H 50 | 51 | /* Define to 1 if you have the header file. */ 52 | #undef HAVE_SYS_STAT_H 53 | 54 | /* Define to 1 if you have the header file. */ 55 | #undef HAVE_SYS_TYPES_H 56 | 57 | /* Define to 1 if you have the header file. */ 58 | #undef HAVE_UNISTD_H 59 | 60 | /* Define to the sub-directory where libtool stores uninstalled libraries. */ 61 | #undef LT_OBJDIR 62 | 63 | /* Name of package */ 64 | #undef PACKAGE 65 | 66 | /* Define to the address where bug reports for this package should be sent. */ 67 | #undef PACKAGE_BUGREPORT 68 | 69 | /* Define to the full name of this package. */ 70 | #undef PACKAGE_NAME 71 | 72 | /* Define to the full name and version of this package. */ 73 | #undef PACKAGE_STRING 74 | 75 | /* Define to the one symbol short name of this package. */ 76 | #undef PACKAGE_TARNAME 77 | 78 | /* Define to the home page for this package. */ 79 | #undef PACKAGE_URL 80 | 81 | /* Define to the version of this package. */ 82 | #undef PACKAGE_VERSION 83 | 84 | /* Define to necessary symbol if this constant uses a non-standard name on 85 | your system. */ 86 | #undef PTHREAD_CREATE_JOINABLE 87 | 88 | /* Define to 1 if you have the ANSI C header files. */ 89 | #undef STDC_HEADERS 90 | 91 | /* Version number of package */ 92 | #undef VERSION 93 | -------------------------------------------------------------------------------- /config.h.in~: -------------------------------------------------------------------------------- 1 | /* config.h.in. Generated from configure.ac by autoheader. */ 2 | 3 | /* Is pthread_attr_get_np() declared in ? */ 4 | #undef ATTRGETNP_NOT_DECLARED 5 | 6 | /* Is pthread_getattr_np declared in ? */ 7 | #undef GETATTRNP_NOT_DECLARED 8 | 9 | /* Define to 1 if you have the header file. */ 10 | #undef HAVE_DLFCN_H 11 | 12 | /* Define to 1 if you have the header file. */ 13 | #undef HAVE_INTTYPES_H 14 | 15 | /* Define to 1 if you have the header file. */ 16 | #undef HAVE_MEMORY_H 17 | 18 | /* Define to 1 if MySQL libraries are available */ 19 | #undef HAVE_MYSQL 20 | 21 | /* Define if you have POSIX threads libraries and header files. */ 22 | #undef HAVE_PTHREAD 23 | 24 | /* Do we want a BSD-like thread-attribute interface? */ 25 | #undef HAVE_PTHREAD_ATTR_GET_NP 26 | 27 | /* Define to 1 if you have the `pthread_attr_setstacksize' function. */ 28 | #undef HAVE_PTHREAD_ATTR_SETSTACKSIZE 29 | 30 | /* Do we want a Linux-like thread-attribute interface? */ 31 | #undef HAVE_PTHREAD_GETATTR_NP 32 | 33 | /* Define to 1 if you have the `pthread_get_stacksize_np' function. */ 34 | #undef HAVE_PTHREAD_GET_STACKSIZE_NP 35 | 36 | /* Have PTHREAD_PRIO_INHERIT. */ 37 | #undef HAVE_PTHREAD_PRIO_INHERIT 38 | 39 | /* Define to 1 if you have the header file. */ 40 | #undef HAVE_STDINT_H 41 | 42 | /* Define to 1 if you have the header file. */ 43 | #undef HAVE_STDLIB_H 44 | 45 | /* Define to 1 if you have the header file. */ 46 | #undef HAVE_STRINGS_H 47 | 48 | /* Define to 1 if you have the header file. */ 49 | #undef HAVE_STRING_H 50 | 51 | /* Define to 1 if you have the header file. */ 52 | #undef HAVE_SYS_STAT_H 53 | 54 | /* Define to 1 if you have the header file. */ 55 | #undef HAVE_SYS_TYPES_H 56 | 57 | /* Define to 1 if you have the header file. */ 58 | #undef HAVE_UNISTD_H 59 | 60 | /* Define to the sub-directory where libtool stores uninstalled libraries. */ 61 | #undef LT_OBJDIR 62 | 63 | /* Name of package */ 64 | #undef PACKAGE 65 | 66 | /* Define to the address where bug reports for this package should be sent. */ 67 | #undef PACKAGE_BUGREPORT 68 | 69 | /* Define to the full name of this package. */ 70 | #undef PACKAGE_NAME 71 | 72 | /* Define to the full name and version of this package. */ 73 | #undef PACKAGE_STRING 74 | 75 | /* Define to the one symbol short name of this package. */ 76 | #undef PACKAGE_TARNAME 77 | 78 | /* Define to the home page for this package. */ 79 | #undef PACKAGE_URL 80 | 81 | /* Define to the version of this package. */ 82 | #undef PACKAGE_VERSION 83 | 84 | /* Define to necessary symbol if this constant uses a non-standard name on 85 | your system. */ 86 | #undef PTHREAD_CREATE_JOINABLE 87 | 88 | /* Define to 1 if you have the ANSI C header files. */ 89 | #undef STDC_HEADERS 90 | 91 | /* Version number of package */ 92 | #undef VERSION 93 | -------------------------------------------------------------------------------- /config/._ax_lib_mysql.m4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysqludf/lib_mysqludf_preg/6395901adaf987a9f9e4e1b859daad4f2d665eff/config/._ax_lib_mysql.m4 -------------------------------------------------------------------------------- /config/ax_lib_mysql.m4: -------------------------------------------------------------------------------- 1 | ##### http://autoconf-archive.cryp.to/ax_lib_mysql.html 2 | # 3 | # SYNOPSIS 4 | # 5 | # AX_LIB_MYSQL([MINIMUM-VERSION]) 6 | # 7 | # DESCRIPTION 8 | # 9 | # This macro provides tests of availability of MySQL client library 10 | # of particular version or newer. 11 | # 12 | # AX_LIB_MYSQL macro takes only one argument which is optional. If 13 | # there is no required version passed, then macro does not run 14 | # version test. 15 | # 16 | # The --with-mysql option takes one of three possible values: 17 | # 18 | # no - do not check for MySQL client library 19 | # 20 | # yes - do check for MySQL library in standard locations 21 | # (mysql_config should be in the PATH) 22 | # 23 | # path - complete path to mysql_config utility, use this option if 24 | # mysql_config can't be found in the PATH 25 | # 26 | # This macro calls: 27 | # 28 | # AC_SUBST(MYSQL_CFLAGS) 29 | # AC_SUBST(MYSQL_LDFLAGS) 30 | # AC_SUBST(MYSQL_VERSION) 31 | # AC_SUBST(MYSQL_PLUGINDIR) 32 | # 33 | # And sets: 34 | # 35 | # HAVE_MYSQL 36 | # 37 | # LAST MODIFICATION 38 | # 39 | # 2006-07-16 40 | # 41 | # COPYLEFT 42 | # 43 | # Copyright (c) 2006 Mateusz Loskot 44 | # 45 | # Copying and distribution of this file, with or without 46 | # modification, are permitted in any medium without royalty provided 47 | # the copyright notice and this notice are preserved. 48 | 49 | AC_DEFUN([AX_LIB_MYSQL], 50 | [ 51 | AC_ARG_WITH([mysql], 52 | AC_HELP_STRING([--with-mysql=@<:@ARG@:>@], 53 | [use MySQL client library @<:@default=yes@:>@, optionally specify path to mysql_config] 54 | ), 55 | [ 56 | if test "$withval" = "no"; then 57 | want_mysql="no" 58 | elif test "$withval" = "yes"; then 59 | want_mysql="yes" 60 | else 61 | want_mysql="yes" 62 | MYSQL_CONFIG="$withval" 63 | fi 64 | ], 65 | [want_mysql="yes"] 66 | ) 67 | 68 | MYSQL_CFLAGS="" 69 | MYSQL_LDFLAGS="" 70 | MYSQL_VERSION="" 71 | MYSQL_PLUGINDIR="" 72 | 73 | dnl 74 | dnl Check MySQL libraries (libpq) 75 | dnl 76 | 77 | if test "$want_mysql" = "yes"; then 78 | 79 | if test -z "$MYSQL_CONFIG" -o test; then 80 | AC_PATH_PROG([MYSQL_CONFIG], [mysql_config], [no]) 81 | fi 82 | 83 | if test "$MYSQL_CONFIG" != "no"; then 84 | AC_MSG_CHECKING([for MySQL libraries]) 85 | 86 | MYSQL_CFLAGS="`$MYSQL_CONFIG --cflags`" 87 | MYSQL_LDFLAGS="`$MYSQL_CONFIG --libs`" 88 | 89 | MYSQL_VERSION=`$MYSQL_CONFIG --version` 90 | if $MYSQL_CONFIG --plugindir > /dev/null; then 91 | MYSQL_PLUGINDIR=`$MYSQL_CONFIG --plugindir` 92 | fi 93 | 94 | AC_DEFINE([HAVE_MYSQL], [1], 95 | [Define to 1 if MySQL libraries are available]) 96 | 97 | found_mysql="yes" 98 | AC_MSG_RESULT([yes]) 99 | m4_ifval($2,$2) 100 | else 101 | found_mysql="no" 102 | AC_MSG_RESULT([no]) 103 | m4_ifval($3,$3) 104 | fi 105 | fi 106 | 107 | dnl 108 | dnl Check if required version of MySQL is available 109 | dnl 110 | 111 | 112 | mysql_version_req=ifelse([$1], [], [], [$1]) 113 | 114 | if test "$found_mysql" = "yes" -a -n "$mysql_version_req"; then 115 | 116 | AC_MSG_CHECKING([if MySQL version is >= $mysql_version_req]) 117 | 118 | dnl Decompose required version string of MySQL 119 | dnl and calculate its number representation 120 | mysql_version_req_major=`expr $mysql_version_req : '\([[0-9]]*\)'` 121 | mysql_version_req_minor=`expr $mysql_version_req : '[[0-9]]*\.\([[0-9]]*\)'` 122 | mysql_version_req_micro=`expr $mysql_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'` 123 | if test "x$mysql_version_req_micro" = "x"; then 124 | mysql_version_req_micro="0" 125 | fi 126 | 127 | mysql_version_req_number=`expr $mysql_version_req_major \* 1000000 \ 128 | \+ $mysql_version_req_minor \* 1000 \ 129 | \+ $mysql_version_req_micro` 130 | 131 | dnl Decompose version string of installed MySQL 132 | dnl and calculate its number representation 133 | mysql_version_major=`expr $MYSQL_VERSION : '\([[0-9]]*\)'` 134 | mysql_version_minor=`expr $MYSQL_VERSION : '[[0-9]]*\.\([[0-9]]*\)'` 135 | mysql_version_micro=`expr $MYSQL_VERSION : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'` 136 | if test "x$mysql_version_micro" = "x"; then 137 | mysql_version_micro="0" 138 | fi 139 | 140 | mysql_version_number=`expr $mysql_version_major \* 1000000 \ 141 | \+ $mysql_version_minor \* 1000 \ 142 | \+ $mysql_version_micro` 143 | 144 | mysql_version_check=`expr $mysql_version_number \>\= $mysql_version_req_number` 145 | if test "$mysql_version_check" = "1"; then 146 | AC_MSG_RESULT([yes]) 147 | m4_ifval($2,$2) 148 | else 149 | AC_MSG_RESULT([no]) 150 | m4_ifval($3,$3) 151 | fi 152 | fi 153 | 154 | AC_SUBST([MYSQL_VERSION]) 155 | AC_SUBST([MYSQL_CFLAGS]) 156 | AC_SUBST([MYSQL_LDFLAGS]) 157 | AC_SUBST([MYSQL_PLUGINDIR]) 158 | ]) 159 | -------------------------------------------------------------------------------- /config/ax_mysql_bin.m4: -------------------------------------------------------------------------------- 1 | ##### 2 | # 3 | # SYNOPSIS 4 | # 5 | # AX_MYSQL_BIN() 6 | # 7 | # DESCRIPTION 8 | # 9 | # This macro defines location of MySQL client (mysql), mysqladmin and mysqltest 10 | # 11 | # This macro calls: 12 | # 13 | # AC_SUBST(MYSQL) 14 | # AC_SUBST(MYSQLADMIN) 15 | # AC_SUBST(MYSQLTEST) 16 | # 17 | ##### 18 | 19 | AC_DEFUN([AX_MYSQL_BIN], [ 20 | AC_MSG_CHECKING(for mysqlbin) 21 | AC_ARG_WITH(mysqlbin, 22 | [[ --with-mysqlbin[=CMD] command to run mysql.]], 23 | [withmysqlbin="$withval"], 24 | [withmysqlbin="yes"] 25 | ) 26 | 27 | AC_ARG_WITH(mysqladmin, 28 | [[ --with-mysqladmin[=CMD] command to run mysqladmin.]], 29 | [withmysqladmin="$withval"], 30 | [withmysqladmin="yes"] 31 | ) 32 | 33 | AC_ARG_WITH(mysqlinclude, 34 | [[ --with-mysqlinclude[=PATH] path to mysql header files.]], 35 | [withmysqlinclude="$withval"], 36 | [withmysqlinclude="yes"] 37 | ) 38 | 39 | AC_ARG_WITH(mysqltest, 40 | [[ --with-mysqltest[=CMD] command to run mysqltest.]], 41 | [withmysqltest="$withval"], 42 | [withmysqltest="yes"] 43 | ) 44 | 45 | if test -z "$withmysqlbin" -o "$withmysqlbin" = "yes"; then 46 | for i in `dirname $(which mysql)` /usr/bin /usr/local/bin ; do 47 | if test -f "$i/mysql" ; then 48 | MYSQL="$i/mysql" 49 | fi 50 | done 51 | elif test "$withmysqlbin" != "no"; then 52 | MYSQL="$withmysqlbin" 53 | fi 54 | 55 | if test -n "$MYSQL" ; then 56 | MYSQLBIN_PATH=`dirname "$MYSQL"` 57 | 58 | if test -f /etc/mysql/debian.cnf ; then 59 | MYSQL_ARGS="--defaults-file=/etc/mysql/debian.cnf" 60 | else 61 | ${MYSQL} 57 | # Copyright (c) 2011 Daniel Richard G. 58 | # 59 | # This program is free software: you can redistribute it and/or modify it 60 | # under the terms of the GNU General Public License as published by the 61 | # Free Software Foundation, either version 3 of the License, or (at your 62 | # option) any later version. 63 | # 64 | # This program is distributed in the hope that it will be useful, but 65 | # WITHOUT ANY WARRANTY; without even the implied warranty of 66 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 67 | # Public License for more details. 68 | # 69 | # You should have received a copy of the GNU General Public License along 70 | # with this program. If not, see . 71 | # 72 | # As a special exception, the respective Autoconf Macro's copyright owner 73 | # gives unlimited permission to copy, distribute and modify the configure 74 | # scripts that are the output of Autoconf when processing the Macro. You 75 | # need not follow the terms of the GNU General Public License when using 76 | # or distributing such scripts, even though portions of the text of the 77 | # Macro appear in them. The GNU General Public License (GPL) does govern 78 | # all other use of the material that constitutes the Autoconf Macro. 79 | # 80 | # This special exception to the GPL applies to versions of the Autoconf 81 | # Macro released by the Autoconf Archive. When you make and distribute a 82 | # modified version of the Autoconf Macro, you may extend this special 83 | # exception to the GPL to apply to your modified version as well. 84 | 85 | #serial 20 86 | 87 | AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) 88 | AC_DEFUN([AX_PTHREAD], [ 89 | AC_REQUIRE([AC_CANONICAL_HOST]) 90 | AC_LANG_PUSH([C]) 91 | ax_pthread_ok=no 92 | 93 | # We used to check for pthread.h first, but this fails if pthread.h 94 | # requires special compiler flags (e.g. on True64 or Sequent). 95 | # It gets checked for in the link test anyway. 96 | 97 | # First of all, check if the user has set any of the PTHREAD_LIBS, 98 | # etcetera environment variables, and if threads linking works using 99 | # them: 100 | if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then 101 | save_CFLAGS="$CFLAGS" 102 | CFLAGS="$CFLAGS $PTHREAD_CFLAGS" 103 | save_LIBS="$LIBS" 104 | LIBS="$PTHREAD_LIBS $LIBS" 105 | AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) 106 | AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes) 107 | AC_MSG_RESULT($ax_pthread_ok) 108 | if test x"$ax_pthread_ok" = xno; then 109 | PTHREAD_LIBS="" 110 | PTHREAD_CFLAGS="" 111 | fi 112 | LIBS="$save_LIBS" 113 | CFLAGS="$save_CFLAGS" 114 | fi 115 | 116 | # We must check for the threads library under a number of different 117 | # names; the ordering is very important because some systems 118 | # (e.g. DEC) have both -lpthread and -lpthreads, where one of the 119 | # libraries is broken (non-POSIX). 120 | 121 | # Create a list of thread flags to try. Items starting with a "-" are 122 | # C compiler flags, and other items are library names, except for "none" 123 | # which indicates that we try without any flags at all, and "pthread-config" 124 | # which is a program returning the flags for the Pth emulation library. 125 | 126 | ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" 127 | 128 | # The ordering *is* (sometimes) important. Some notes on the 129 | # individual items follow: 130 | 131 | # pthreads: AIX (must check this before -lpthread) 132 | # none: in case threads are in libc; should be tried before -Kthread and 133 | # other compiler flags to prevent continual compiler warnings 134 | # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) 135 | # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) 136 | # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) 137 | # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) 138 | # -pthreads: Solaris/gcc 139 | # -mthreads: Mingw32/gcc, Lynx/gcc 140 | # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it 141 | # doesn't hurt to check since this sometimes defines pthreads too; 142 | # also defines -D_REENTRANT) 143 | # ... -mt is also the pthreads flag for HP/aCC 144 | # pthread: Linux, etcetera 145 | # --thread-safe: KAI C++ 146 | # pthread-config: use pthread-config program (for GNU Pth library) 147 | 148 | case ${host_os} in 149 | solaris*) 150 | 151 | # On Solaris (at least, for some versions), libc contains stubbed 152 | # (non-functional) versions of the pthreads routines, so link-based 153 | # tests will erroneously succeed. (We need to link with -pthreads/-mt/ 154 | # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather 155 | # a function called by this macro, so we could check for that, but 156 | # who knows whether they'll stub that too in a future libc.) So, 157 | # we'll just look for -pthreads and -lpthread first: 158 | 159 | ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" 160 | ;; 161 | 162 | darwin*) 163 | ax_pthread_flags="-pthread $ax_pthread_flags" 164 | ;; 165 | 166 | linux-gnu*) # R.A.W. Otherwise none gets chosen and that leaves the pthread_getattr_np stuff not found 167 | ax_pthread_flags="pthread $ax_pthread_flags" 168 | ;; 169 | esac 170 | 171 | if test x"$ax_pthread_ok" = xno; then 172 | for flag in $ax_pthread_flags; do 173 | 174 | case $flag in 175 | none) 176 | AC_MSG_CHECKING([whether pthreads work without any flags]) 177 | ;; 178 | 179 | -*) 180 | AC_MSG_CHECKING([whether pthreads work with $flag]) 181 | PTHREAD_CFLAGS="$flag" 182 | ;; 183 | 184 | pthread-config) 185 | AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no) 186 | if test x"$ax_pthread_config" = xno; then continue; fi 187 | PTHREAD_CFLAGS="`pthread-config --cflags`" 188 | PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" 189 | ;; 190 | 191 | *) 192 | AC_MSG_CHECKING([for the pthreads library -l$flag]) 193 | PTHREAD_LIBS="-l$flag" 194 | ;; 195 | esac 196 | 197 | save_LIBS="$LIBS" 198 | save_CFLAGS="$CFLAGS" 199 | LIBS="$PTHREAD_LIBS $LIBS" 200 | CFLAGS="$CFLAGS $PTHREAD_CFLAGS" 201 | 202 | # Check for various functions. We must include pthread.h, 203 | # since some functions may be macros. (On the Sequent, we 204 | # need a special flag -Kthread to make this header compile.) 205 | # We check for pthread_join because it is in -lpthread on IRIX 206 | # while pthread_create is in libc. We check for pthread_attr_init 207 | # due to DEC craziness with -lpthreads. We check for 208 | # pthread_cleanup_push because it is one of the few pthread 209 | # functions on Solaris that doesn't have a non-functional libc stub. 210 | # We try pthread_create on general principles. 211 | AC_LINK_IFELSE([AC_LANG_PROGRAM([#include 212 | static void routine(void *a) { a = 0; } 213 | static void *start_routine(void *a) { return a; }], 214 | [pthread_t th; pthread_attr_t attr; 215 | pthread_create(&th, 0, start_routine, 0); 216 | pthread_join(th, 0); 217 | pthread_attr_init(&attr); 218 | pthread_cleanup_push(routine, 0); 219 | pthread_cleanup_pop(0) /* ; */])], 220 | [ax_pthread_ok=yes], 221 | []) 222 | 223 | LIBS="$save_LIBS" 224 | CFLAGS="$save_CFLAGS" 225 | 226 | AC_MSG_RESULT($ax_pthread_ok) 227 | if test "x$ax_pthread_ok" = xyes; then 228 | break; 229 | fi 230 | 231 | PTHREAD_LIBS="" 232 | PTHREAD_CFLAGS="" 233 | done 234 | fi 235 | 236 | # Various other checks: 237 | if test "x$ax_pthread_ok" = xyes; then 238 | save_LIBS="$LIBS" 239 | LIBS="$PTHREAD_LIBS $LIBS" 240 | save_CFLAGS="$CFLAGS" 241 | CFLAGS="$CFLAGS $PTHREAD_CFLAGS" 242 | 243 | # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. 244 | AC_MSG_CHECKING([for joinable pthread attribute]) 245 | attr_name=unknown 246 | for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do 247 | AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], 248 | [int attr = $attr; return attr /* ; */])], 249 | [attr_name=$attr; break], 250 | []) 251 | done 252 | AC_MSG_RESULT($attr_name) 253 | if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then 254 | AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, 255 | [Define to necessary symbol if this constant 256 | uses a non-standard name on your system.]) 257 | fi 258 | 259 | AC_MSG_CHECKING([if more special flags are required for pthreads]) 260 | flag=no 261 | case ${host_os} in 262 | aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; 263 | osf* | hpux*) flag="-D_REENTRANT";; 264 | solaris*) 265 | if test "$GCC" = "yes"; then 266 | flag="-D_REENTRANT" 267 | else 268 | flag="-mt -D_REENTRANT" 269 | fi 270 | ;; 271 | esac 272 | AC_MSG_RESULT(${flag}) 273 | if test "x$flag" != xno; then 274 | PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" 275 | fi 276 | 277 | AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], 278 | ax_cv_PTHREAD_PRIO_INHERIT, [ 279 | AC_LINK_IFELSE([ 280 | AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], 281 | [ax_cv_PTHREAD_PRIO_INHERIT=yes], 282 | [ax_cv_PTHREAD_PRIO_INHERIT=no]) 283 | ]) 284 | AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], 285 | AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.])) 286 | 287 | LIBS="$save_LIBS" 288 | CFLAGS="$save_CFLAGS" 289 | 290 | # More AIX lossage: compile with *_r variant 291 | if test "x$GCC" != xyes; then 292 | case $host_os in 293 | aix*) 294 | AS_CASE(["x/$CC"], 295 | [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], 296 | [#handle absolute path differently from PATH based program lookup 297 | AS_CASE(["x$CC"], 298 | [x/*], 299 | [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], 300 | [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) 301 | ;; 302 | esac 303 | fi 304 | fi 305 | 306 | test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" 307 | 308 | AC_SUBST(PTHREAD_LIBS) 309 | AC_SUBST(PTHREAD_CFLAGS) 310 | AC_SUBST(PTHREAD_CC) 311 | 312 | # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: 313 | if test x"$ax_pthread_ok" = xyes; then 314 | ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) 315 | : 316 | else 317 | ax_pthread_ok=no 318 | $2 319 | fi 320 | AC_LANG_POP 321 | ])dnl AX_PTHREAD 322 | -------------------------------------------------------------------------------- /config/ax_pthread_np.m4: -------------------------------------------------------------------------------- 1 | 2 | AC_DEFUN([AX_PTHREAD_NP], [ 3 | 4 | 5 | # from tcl.m4 http://svn.apache.org/repos/asf/trafficserver/attic/traffic/trunk/build/tcl.m4 6 | # Does the pthread-implementation provide 7 | # 'pthread_attr_setstacksize' ? 8 | 9 | ac_saved_libs=$LIBS 10 | LIBS="$LIBS $PTHREAD_LIBS" 11 | AC_CHECK_FUNCS(pthread_attr_setstacksize) 12 | AC_CHECK_FUNC(pthread_attr_get_np,tcl_ok=yes,tcl_ok=no) 13 | if test $tcl_ok = yes ; then 14 | AC_DEFINE(HAVE_PTHREAD_ATTR_GET_NP, 1, 15 | [Do we want a BSD-like thread-attribute interface?]) 16 | AC_CACHE_CHECK([for pthread_attr_get_np declaration], 17 | tcl_cv_grep_pthread_attr_get_np, [ 18 | AC_EGREP_HEADER(pthread_attr_get_np, pthread.h, 19 | tcl_cv_grep_pthread_attr_get_np=present, 20 | tcl_cv_grep_pthread_attr_get_np=missing)]) 21 | if test $tcl_cv_grep_pthread_attr_get_np = missing ; then 22 | AC_DEFINE(ATTRGETNP_NOT_DECLARED, 1, 23 | [Is pthread_attr_get_np() declared in ?]) 24 | fi 25 | else 26 | AC_CHECK_FUNC(pthread_getattr_np,tcl_ok=yes,tcl_ok=no) 27 | if test $tcl_ok = yes ; then 28 | AC_DEFINE(HAVE_PTHREAD_GETATTR_NP, 1, 29 | [Do we want a Linux-like thread-attribute interface?]) 30 | AC_CACHE_CHECK([for pthread_getattr_np declaration], 31 | tcl_cv_grep_pthread_getattr_np, [ 32 | AC_EGREP_HEADER(pthread_getattr_np, pthread.h, 33 | tcl_cv_grep_pthread_getattr_np=present, 34 | tcl_cv_grep_pthread_getattr_np=missing)]) 35 | if test $tcl_cv_grep_pthread_getattr_np = missing ; then 36 | AC_DEFINE(GETATTRNP_NOT_DECLARED, 1, 37 | [Is pthread_getattr_np declared in ?]) 38 | fi 39 | fi 40 | fi 41 | if test $tcl_ok = no; then 42 | # Darwin thread stacksize API 43 | AC_CHECK_FUNCS(pthread_get_stacksize_np) 44 | fi 45 | LIBS=$ac_saved_libs 46 | ] ) -------------------------------------------------------------------------------- /config/compile: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Wrapper for compilers which do not understand '-c -o'. 3 | 4 | scriptversion=2018-03-07.03; # UTC 5 | 6 | # Copyright (C) 1999-2018 Free Software Foundation, Inc. 7 | # Written by Tom Tromey . 8 | # 9 | # This program is free software; you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License as published by 11 | # the Free Software Foundation; either version 2, or (at your option) 12 | # any later version. 13 | # 14 | # This program is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU General Public License 20 | # along with this program. If not, see . 21 | 22 | # As a special exception to the GNU General Public License, if you 23 | # distribute this file as part of a program that contains a 24 | # configuration script generated by Autoconf, you may include it under 25 | # the same distribution terms that you use for the rest of that program. 26 | 27 | # This file is maintained in Automake, please report 28 | # bugs to or send patches to 29 | # . 30 | 31 | nl=' 32 | ' 33 | 34 | # We need space, tab and new line, in precisely that order. Quoting is 35 | # there to prevent tools from complaining about whitespace usage. 36 | IFS=" "" $nl" 37 | 38 | file_conv= 39 | 40 | # func_file_conv build_file lazy 41 | # Convert a $build file to $host form and store it in $file 42 | # Currently only supports Windows hosts. If the determined conversion 43 | # type is listed in (the comma separated) LAZY, no conversion will 44 | # take place. 45 | func_file_conv () 46 | { 47 | file=$1 48 | case $file in 49 | / | /[!/]*) # absolute file, and not a UNC file 50 | if test -z "$file_conv"; then 51 | # lazily determine how to convert abs files 52 | case `uname -s` in 53 | MINGW*) 54 | file_conv=mingw 55 | ;; 56 | CYGWIN*) 57 | file_conv=cygwin 58 | ;; 59 | *) 60 | file_conv=wine 61 | ;; 62 | esac 63 | fi 64 | case $file_conv/,$2, in 65 | *,$file_conv,*) 66 | ;; 67 | mingw/*) 68 | file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` 69 | ;; 70 | cygwin/*) 71 | file=`cygpath -m "$file" || echo "$file"` 72 | ;; 73 | wine/*) 74 | file=`winepath -w "$file" || echo "$file"` 75 | ;; 76 | esac 77 | ;; 78 | esac 79 | } 80 | 81 | # func_cl_dashL linkdir 82 | # Make cl look for libraries in LINKDIR 83 | func_cl_dashL () 84 | { 85 | func_file_conv "$1" 86 | if test -z "$lib_path"; then 87 | lib_path=$file 88 | else 89 | lib_path="$lib_path;$file" 90 | fi 91 | linker_opts="$linker_opts -LIBPATH:$file" 92 | } 93 | 94 | # func_cl_dashl library 95 | # Do a library search-path lookup for cl 96 | func_cl_dashl () 97 | { 98 | lib=$1 99 | found=no 100 | save_IFS=$IFS 101 | IFS=';' 102 | for dir in $lib_path $LIB 103 | do 104 | IFS=$save_IFS 105 | if $shared && test -f "$dir/$lib.dll.lib"; then 106 | found=yes 107 | lib=$dir/$lib.dll.lib 108 | break 109 | fi 110 | if test -f "$dir/$lib.lib"; then 111 | found=yes 112 | lib=$dir/$lib.lib 113 | break 114 | fi 115 | if test -f "$dir/lib$lib.a"; then 116 | found=yes 117 | lib=$dir/lib$lib.a 118 | break 119 | fi 120 | done 121 | IFS=$save_IFS 122 | 123 | if test "$found" != yes; then 124 | lib=$lib.lib 125 | fi 126 | } 127 | 128 | # func_cl_wrapper cl arg... 129 | # Adjust compile command to suit cl 130 | func_cl_wrapper () 131 | { 132 | # Assume a capable shell 133 | lib_path= 134 | shared=: 135 | linker_opts= 136 | for arg 137 | do 138 | if test -n "$eat"; then 139 | eat= 140 | else 141 | case $1 in 142 | -o) 143 | # configure might choose to run compile as 'compile cc -o foo foo.c'. 144 | eat=1 145 | case $2 in 146 | *.o | *.[oO][bB][jJ]) 147 | func_file_conv "$2" 148 | set x "$@" -Fo"$file" 149 | shift 150 | ;; 151 | *) 152 | func_file_conv "$2" 153 | set x "$@" -Fe"$file" 154 | shift 155 | ;; 156 | esac 157 | ;; 158 | -I) 159 | eat=1 160 | func_file_conv "$2" mingw 161 | set x "$@" -I"$file" 162 | shift 163 | ;; 164 | -I*) 165 | func_file_conv "${1#-I}" mingw 166 | set x "$@" -I"$file" 167 | shift 168 | ;; 169 | -l) 170 | eat=1 171 | func_cl_dashl "$2" 172 | set x "$@" "$lib" 173 | shift 174 | ;; 175 | -l*) 176 | func_cl_dashl "${1#-l}" 177 | set x "$@" "$lib" 178 | shift 179 | ;; 180 | -L) 181 | eat=1 182 | func_cl_dashL "$2" 183 | ;; 184 | -L*) 185 | func_cl_dashL "${1#-L}" 186 | ;; 187 | -static) 188 | shared=false 189 | ;; 190 | -Wl,*) 191 | arg=${1#-Wl,} 192 | save_ifs="$IFS"; IFS=',' 193 | for flag in $arg; do 194 | IFS="$save_ifs" 195 | linker_opts="$linker_opts $flag" 196 | done 197 | IFS="$save_ifs" 198 | ;; 199 | -Xlinker) 200 | eat=1 201 | linker_opts="$linker_opts $2" 202 | ;; 203 | -*) 204 | set x "$@" "$1" 205 | shift 206 | ;; 207 | *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) 208 | func_file_conv "$1" 209 | set x "$@" -Tp"$file" 210 | shift 211 | ;; 212 | *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) 213 | func_file_conv "$1" mingw 214 | set x "$@" "$file" 215 | shift 216 | ;; 217 | *) 218 | set x "$@" "$1" 219 | shift 220 | ;; 221 | esac 222 | fi 223 | shift 224 | done 225 | if test -n "$linker_opts"; then 226 | linker_opts="-link$linker_opts" 227 | fi 228 | exec "$@" $linker_opts 229 | exit 1 230 | } 231 | 232 | eat= 233 | 234 | case $1 in 235 | '') 236 | echo "$0: No command. Try '$0 --help' for more information." 1>&2 237 | exit 1; 238 | ;; 239 | -h | --h*) 240 | cat <<\EOF 241 | Usage: compile [--help] [--version] PROGRAM [ARGS] 242 | 243 | Wrapper for compilers which do not understand '-c -o'. 244 | Remove '-o dest.o' from ARGS, run PROGRAM with the remaining 245 | arguments, and rename the output as expected. 246 | 247 | If you are trying to build a whole package this is not the 248 | right script to run: please start by reading the file 'INSTALL'. 249 | 250 | Report bugs to . 251 | EOF 252 | exit $? 253 | ;; 254 | -v | --v*) 255 | echo "compile $scriptversion" 256 | exit $? 257 | ;; 258 | cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ 259 | icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) 260 | func_cl_wrapper "$@" # Doesn't return... 261 | ;; 262 | esac 263 | 264 | ofile= 265 | cfile= 266 | 267 | for arg 268 | do 269 | if test -n "$eat"; then 270 | eat= 271 | else 272 | case $1 in 273 | -o) 274 | # configure might choose to run compile as 'compile cc -o foo foo.c'. 275 | # So we strip '-o arg' only if arg is an object. 276 | eat=1 277 | case $2 in 278 | *.o | *.obj) 279 | ofile=$2 280 | ;; 281 | *) 282 | set x "$@" -o "$2" 283 | shift 284 | ;; 285 | esac 286 | ;; 287 | *.c) 288 | cfile=$1 289 | set x "$@" "$1" 290 | shift 291 | ;; 292 | *) 293 | set x "$@" "$1" 294 | shift 295 | ;; 296 | esac 297 | fi 298 | shift 299 | done 300 | 301 | if test -z "$ofile" || test -z "$cfile"; then 302 | # If no '-o' option was seen then we might have been invoked from a 303 | # pattern rule where we don't need one. That is ok -- this is a 304 | # normal compilation that the losing compiler can handle. If no 305 | # '.c' file was seen then we are probably linking. That is also 306 | # ok. 307 | exec "$@" 308 | fi 309 | 310 | # Name of file we expect compiler to create. 311 | cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` 312 | 313 | # Create the lock directory. 314 | # Note: use '[/\\:.-]' here to ensure that we don't use the same name 315 | # that we are using for the .o file. Also, base the name on the expected 316 | # object file name, since that is what matters with a parallel build. 317 | lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d 318 | while true; do 319 | if mkdir "$lockdir" >/dev/null 2>&1; then 320 | break 321 | fi 322 | sleep 1 323 | done 324 | # FIXME: race condition here if user kills between mkdir and trap. 325 | trap "rmdir '$lockdir'; exit 1" 1 2 15 326 | 327 | # Run the compile. 328 | "$@" 329 | ret=$? 330 | 331 | if test -f "$cofile"; then 332 | test "$cofile" = "$ofile" || mv "$cofile" "$ofile" 333 | elif test -f "${cofile}bj"; then 334 | test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" 335 | fi 336 | 337 | rmdir "$lockdir" 338 | exit $ret 339 | 340 | # Local Variables: 341 | # mode: shell-script 342 | # sh-indentation: 2 343 | # eval: (add-hook 'before-save-hook 'time-stamp) 344 | # time-stamp-start: "scriptversion=" 345 | # time-stamp-format: "%:y-%02m-%02d.%02H" 346 | # time-stamp-time-zone: "UTC0" 347 | # time-stamp-end: "; # UTC" 348 | # End: 349 | -------------------------------------------------------------------------------- /config/ghmysql.m4: -------------------------------------------------------------------------------- 1 | ##### 2 | # 3 | # SYNOPSIS 4 | # 5 | # AX_GHMYSQL 6 | # 7 | # DESCRIPTION 8 | # 9 | # 10 | ##### 11 | 12 | AC_DEFUN([AX_GHMYSQL], [ 13 | AC_ARG_ENABLE( 14 | [legacy-nulls], 15 | AC_HELP_STRING([--enable-legacy-nulls],[replace NULLs with empty strings]) , 16 | [GHMYSQL_CFLAGS="-DGH_1_0_NULL_HANDLING=1"], 17 | [GHMYSQL_CFLAGS=""] 18 | 19 | ) 20 | AC_SUBST(GHMYSQL_CFLAGS) 21 | ]) 22 | 23 | -------------------------------------------------------------------------------- /config/missing: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Common wrapper for a few potentially missing GNU programs. 3 | 4 | scriptversion=2018-03-07.03; # UTC 5 | 6 | # Copyright (C) 1996-2018 Free Software Foundation, Inc. 7 | # Originally written by Fran,cois Pinard , 1996. 8 | 9 | # This program is free software; you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License as published by 11 | # the Free Software Foundation; either version 2, or (at your option) 12 | # any later version. 13 | 14 | # This program is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | 19 | # You should have received a copy of the GNU General Public License 20 | # along with this program. If not, see . 21 | 22 | # As a special exception to the GNU General Public License, if you 23 | # distribute this file as part of a program that contains a 24 | # configuration script generated by Autoconf, you may include it under 25 | # the same distribution terms that you use for the rest of that program. 26 | 27 | if test $# -eq 0; then 28 | echo 1>&2 "Try '$0 --help' for more information" 29 | exit 1 30 | fi 31 | 32 | case $1 in 33 | 34 | --is-lightweight) 35 | # Used by our autoconf macros to check whether the available missing 36 | # script is modern enough. 37 | exit 0 38 | ;; 39 | 40 | --run) 41 | # Back-compat with the calling convention used by older automake. 42 | shift 43 | ;; 44 | 45 | -h|--h|--he|--hel|--help) 46 | echo "\ 47 | $0 [OPTION]... PROGRAM [ARGUMENT]... 48 | 49 | Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due 50 | to PROGRAM being missing or too old. 51 | 52 | Options: 53 | -h, --help display this help and exit 54 | -v, --version output version information and exit 55 | 56 | Supported PROGRAM values: 57 | aclocal autoconf autoheader autom4te automake makeinfo 58 | bison yacc flex lex help2man 59 | 60 | Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 61 | 'g' are ignored when checking the name. 62 | 63 | Send bug reports to ." 64 | exit $? 65 | ;; 66 | 67 | -v|--v|--ve|--ver|--vers|--versi|--versio|--version) 68 | echo "missing $scriptversion (GNU Automake)" 69 | exit $? 70 | ;; 71 | 72 | -*) 73 | echo 1>&2 "$0: unknown '$1' option" 74 | echo 1>&2 "Try '$0 --help' for more information" 75 | exit 1 76 | ;; 77 | 78 | esac 79 | 80 | # Run the given program, remember its exit status. 81 | "$@"; st=$? 82 | 83 | # If it succeeded, we are done. 84 | test $st -eq 0 && exit 0 85 | 86 | # Also exit now if we it failed (or wasn't found), and '--version' was 87 | # passed; such an option is passed most likely to detect whether the 88 | # program is present and works. 89 | case $2 in --version|--help) exit $st;; esac 90 | 91 | # Exit code 63 means version mismatch. This often happens when the user 92 | # tries to use an ancient version of a tool on a file that requires a 93 | # minimum version. 94 | if test $st -eq 63; then 95 | msg="probably too old" 96 | elif test $st -eq 127; then 97 | # Program was missing. 98 | msg="missing on your system" 99 | else 100 | # Program was found and executed, but failed. Give up. 101 | exit $st 102 | fi 103 | 104 | perl_URL=https://www.perl.org/ 105 | flex_URL=https://github.com/westes/flex 106 | gnu_software_URL=https://www.gnu.org/software 107 | 108 | program_details () 109 | { 110 | case $1 in 111 | aclocal|automake) 112 | echo "The '$1' program is part of the GNU Automake package:" 113 | echo "<$gnu_software_URL/automake>" 114 | echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" 115 | echo "<$gnu_software_URL/autoconf>" 116 | echo "<$gnu_software_URL/m4/>" 117 | echo "<$perl_URL>" 118 | ;; 119 | autoconf|autom4te|autoheader) 120 | echo "The '$1' program is part of the GNU Autoconf package:" 121 | echo "<$gnu_software_URL/autoconf/>" 122 | echo "It also requires GNU m4 and Perl in order to run:" 123 | echo "<$gnu_software_URL/m4/>" 124 | echo "<$perl_URL>" 125 | ;; 126 | esac 127 | } 128 | 129 | give_advice () 130 | { 131 | # Normalize program name to check for. 132 | normalized_program=`echo "$1" | sed ' 133 | s/^gnu-//; t 134 | s/^gnu//; t 135 | s/^g//; t'` 136 | 137 | printf '%s\n' "'$1' is $msg." 138 | 139 | configure_deps="'configure.ac' or m4 files included by 'configure.ac'" 140 | case $normalized_program in 141 | autoconf*) 142 | echo "You should only need it if you modified 'configure.ac'," 143 | echo "or m4 files included by it." 144 | program_details 'autoconf' 145 | ;; 146 | autoheader*) 147 | echo "You should only need it if you modified 'acconfig.h' or" 148 | echo "$configure_deps." 149 | program_details 'autoheader' 150 | ;; 151 | automake*) 152 | echo "You should only need it if you modified 'Makefile.am' or" 153 | echo "$configure_deps." 154 | program_details 'automake' 155 | ;; 156 | aclocal*) 157 | echo "You should only need it if you modified 'acinclude.m4' or" 158 | echo "$configure_deps." 159 | program_details 'aclocal' 160 | ;; 161 | autom4te*) 162 | echo "You might have modified some maintainer files that require" 163 | echo "the 'autom4te' program to be rebuilt." 164 | program_details 'autom4te' 165 | ;; 166 | bison*|yacc*) 167 | echo "You should only need it if you modified a '.y' file." 168 | echo "You may want to install the GNU Bison package:" 169 | echo "<$gnu_software_URL/bison/>" 170 | ;; 171 | lex*|flex*) 172 | echo "You should only need it if you modified a '.l' file." 173 | echo "You may want to install the Fast Lexical Analyzer package:" 174 | echo "<$flex_URL>" 175 | ;; 176 | help2man*) 177 | echo "You should only need it if you modified a dependency" \ 178 | "of a man page." 179 | echo "You may want to install the GNU Help2man package:" 180 | echo "<$gnu_software_URL/help2man/>" 181 | ;; 182 | makeinfo*) 183 | echo "You should only need it if you modified a '.texi' file, or" 184 | echo "any other file indirectly affecting the aspect of the manual." 185 | echo "You might want to install the Texinfo package:" 186 | echo "<$gnu_software_URL/texinfo/>" 187 | echo "The spurious makeinfo call might also be the consequence of" 188 | echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" 189 | echo "want to install GNU make:" 190 | echo "<$gnu_software_URL/make/>" 191 | ;; 192 | *) 193 | echo "You might have modified some files without having the proper" 194 | echo "tools for further handling them. Check the 'README' file, it" 195 | echo "often tells you about the needed prerequisites for installing" 196 | echo "this package. You may also peek at any GNU archive site, in" 197 | echo "case some other package contains this missing '$1' program." 198 | ;; 199 | esac 200 | } 201 | 202 | give_advice "$1" | sed -e '1s/^/WARNING: /' \ 203 | -e '2,$s/^/ /' >&2 204 | 205 | # Propagate the correct exit status (expected to be 127 for a program 206 | # not found, 63 for a program that failed due to version mismatch). 207 | exit $st 208 | 209 | # Local variables: 210 | # eval: (add-hook 'before-save-hook 'time-stamp) 211 | # time-stamp-start: "scriptversion=" 212 | # time-stamp-format: "%:y-%02m-%02d.%02H" 213 | # time-stamp-time-zone: "UTC0" 214 | # time-stamp-end: "; # UTC" 215 | # End: 216 | -------------------------------------------------------------------------------- /config/pcre.m4: -------------------------------------------------------------------------------- 1 | 2 | dnl 3 | dnl AM_PATH_PCRE(MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) 4 | dnl 5 | dnl based on cppunit.m4 found in wxWidgets distrubution 6 | dnl 7 | AC_DEFUN([AM_PATH_PCRE], 8 | [ 9 | 10 | AC_ARG_WITH(pcre-prefix,[ --with-pcre-prefix=PFX Prefix where PCRE is installed (optional)], 11 | pcre_config_prefix="$withval", pcre_config_prefix="") 12 | 13 | AC_ARG_WITH(pcre,[ --with-pcre=PFX Prefix where PCRE is installed (deprecated)], 14 | pcre_config_prefix="$withval", pcre_config_prefix="") 15 | 16 | AC_ARG_WITH(pcre-exec-prefix,[ --with-pcre-exec-prefix=PFX Exec prefix where PCRE is installed (optional)], 17 | pcre_config_exec_prefix="$withval", pcre_config_exec_prefix="") 18 | 19 | if test x$pcre_config_exec_prefix != x ; then 20 | pcre_config_args="$pcre_config_args --exec-prefix=$pcre_config_exec_prefix" 21 | if test x${PCRE_CONFIG+set} != xset ; then 22 | PCRE_CONFIG=$pcre_config_exec_prefix/bin/pcre-config 23 | fi 24 | fi 25 | if test x$pcre_config_prefix != x ; then 26 | pcre_config_args="$pcre_config_args --prefix=$pcre_config_prefix" 27 | if test x${PCRE_CONFIG+set} != xset ; then 28 | PCRE_CONFIG=$pcre_config_prefix/bin/pcre-config 29 | fi 30 | fi 31 | 32 | AC_PATH_PROG(PCRE_CONFIG, pcre-config, no) 33 | pcre_version_min=$1 34 | 35 | AC_MSG_CHECKING(for PCRE - version >= $pcre_version_min) 36 | no_pcre="" 37 | if test "$PCRE_CONFIG" = "no" ; then 38 | AC_MSG_RESULT(no) 39 | no_pcre=yes 40 | else 41 | PCRE_CFLAGS=`$PCRE_CONFIG --cflags` 42 | PCRE_LIBS=`$PCRE_CONFIG --libs` 43 | pcre_version=`$PCRE_CONFIG --version` 44 | 45 | pcre_major_version=`echo $pcre_version | cut -d. -f1` 46 | pcre_minor_version=`echo $pcre_version | cut -d. -f2` 47 | 48 | pcre_major_min=`echo $pcre_version_min | cut -d. -f1` 49 | pcre_minor_min=`echo $pcre_version_min | cut -d. -f2` 50 | 51 | pcre_version_proper=`expr \ 52 | $pcre_major_version \> $pcre_major_min \| \ 53 | $pcre_major_version \= $pcre_major_min \& \ 54 | $pcre_minor_version \> $pcre_minor_min \| \ 55 | $pcre_major_version \= $pcre_major_min \& \ 56 | $pcre_minor_version \= $pcre_minor_min` 57 | 58 | if test "$pcre_version_proper" = "1" ; then 59 | AC_MSG_RESULT([$pcre_major_version.$pcre_minor_version]) 60 | else 61 | AC_MSG_RESULT(no) 62 | no_pcre=yes 63 | fi 64 | fi 65 | 66 | if test "x$no_pcre" = x ; then 67 | ifelse([$2], , :, [$2]) 68 | else 69 | PCRE_CFLAGS="" 70 | PCRE_LIBS="" 71 | ifelse([$3], , :, [$3]) 72 | fi 73 | 74 | AC_SUBST(PCRE_CFLAGS) 75 | AC_SUBST(PCRE_LIBS) 76 | ]) 77 | 78 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_PREREQ(2.59) 2 | 3 | AC_INIT(lib_mysqludf_preg,1.2-rc2,raw@goodhumans.net) 4 | 5 | AC_CONFIG_AUX_DIR(config) 6 | 7 | m4_include([config/ax_lib_mysql.m4]) 8 | m4_include([config/ax_mysql_bin.m4]) 9 | m4_include([config/pcre.m4]) 10 | m4_include([config/ghmysql.m4]) 11 | m4_include([config/ax_pthread.m4]) 12 | m4_include([config/ax_pthread_np.m4]) 13 | 14 | AM_INIT_AUTOMAKE 15 | 16 | AC_LIBTOOL_WIN32_DLL 17 | AM_PROG_LIBTOOL 18 | AC_PROG_CC 19 | 20 | AX_MYSQL_BIN 21 | 22 | AX_LIB_MYSQL(,,AC_MSG_ERROR("Can't find mysql library" ) ) 23 | if test -n "$MYSQL_PLUGINDIR" && test "$libdir" == '${exec_prefix}/lib' ; then 24 | AC_MSG_NOTICE(setting libdir to mysql plugin dir $MYSQL_PLUGINDIR) 25 | libdir=$MYSQL_PLUGINDIR 26 | AC_SUBST(libdir) 27 | fi 28 | 29 | AM_PATH_PCRE(1,,AC_MSG_ERROR( "Can't find libpcre" ) ) 30 | 31 | AX_PTHREAD(,AC_MSG_ERROR( "Can't find libpthread" ) ) 32 | AX_PTHREAD_NP(,AC_MSG_ERROR( "Can't find libpthread" ) ) 33 | 34 | AX_GHMYSQL 35 | 36 | AC_CONFIG_HEADERS(config.h) 37 | 38 | AC_OUTPUT([ Makefile 39 | test/Makefile 40 | doc/Makefile 41 | ]) 42 | -------------------------------------------------------------------------------- /doc/INSTALL.windows: -------------------------------------------------------------------------------- 1 | 2 | 3 | lib_mysqludf_preg - PCRE functions for mysql on Windows 4 | ======================================================== 5 | 6 | 7 | == Runtime Prerequisites === 8 | The pcre dll is the runtime prerequisite in order that the 9 | lib_mysqludf_preg udf works properly. This file can be 10 | downloaded from the bin archive at: 11 | 12 | http://sourceforge.net/project/showfiles.php?group_id=214730&package_id=261982 13 | 14 | 15 | From this archive, copy the bin/libpcre.dll file to the same place 16 | where lib_mysqludf_preg.dll will be installed. For the 5.0 series of 17 | mysql server, this should be the bin directory directly under the 18 | Mysql\ Server installation. For the 5.1 MySQL servers this is the 19 | directory as specified by the 'plugin_dir' MySQL variable. 20 | 21 | The libpcre.dll can also be downloaded from: 22 | 23 | http://www.mysqludf.com/lib_mysqludf_preg/index.php 24 | 25 | Please note that the dll at the above link was compiled from 26 | the stock pcre source and not the above referenced sourceforge 27 | project. If you decide to compile pcre from the stock source, it 28 | makes sense to add "LDFLAGS=-avoid-version" to the "make" line. 29 | 30 | 31 | === Compiling Prerequisites === 32 | Compiling lib_mysqludf_preg requires the MinGW compiler and either 33 | the msys or cywin environment. Of the 2, the msys environment 34 | is encouraged. In either case, the MinGW version of libpcre 35 | is necessary. This can be downloaded from the lib archive at: 36 | 37 | http://sourceforge.net/project/showfiles.php?group_id=214730&package_id=261982 38 | 39 | The MinGW compiler and MSYS environment can be downloaded from 40 | http://www.ming.org/ 41 | 42 | Additionally, for the 'mysql' client binary must be available in 43 | the PATH and must be in a directory *without any spaces in it's name*. 44 | 45 | 46 | === Configuration === 47 | When compiling from the msys environment, a line similar to 48 | the following should be used: 49 | 50 | ./configure --with-mysql=no --with-mysqlinclude= --with-pcre= 51 | 52 | If compiling in the cygwin environment, the following should be added 53 | to the above line: 54 | 55 | CC="gcc -mno-cygwin" 56 | 57 | 58 | == Compile == 59 | Type make 60 | 61 | 62 | == Install the library == 63 | make install 64 | 65 | This will install the library in the configured installation directory, 66 | which is defaulted to /usr/local/lib. The lib_mysqludf_preg.dll in 67 | this directory should then be copied to the same directory that 68 | the libpcre.dll was copied to, as described in the Prerequisites 69 | section of this document. 70 | 71 | == Install the SQL functions == 72 | 73 | make installdb 74 | 75 | To uninstall the functions, you can use: make uninstalldb 76 | 77 | 78 | == Run some tests == 79 | make test 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /doc/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | UDF_DOCS_HTML=index.html doxygen.css doxygen.png 3 | 4 | UDF_DOCS_HTML_D=$(UDF_DOCS_HTML:%=html/%) 5 | 6 | 7 | EXTRA_DIST = $(UDF_DOCS_HTML_D) INSTALL.windows 8 | 9 | DOXYGEN=doxygen 10 | 11 | all: 12 | 13 | doc: 14 | $(DOXYGEN) Doxyfile 15 | cat html/index.html | awk '//,/
' | sed 's//

/g' | sed 's/<\/h2>/<\/h1>/g' | sed 's/index.html/index.php/g' > lib_mysqludf_preg.frag 16 | cat index.php.in | sed 's//$(PACKAGE_TARNAME)-$(PACKAGE_VERSION).tar.gz/g'| sed 's/<__VERSION__>/$(PACKAGE_VERSION)/g' | sed 's//$(PACKAGE)-$(PACKAGE_VERSION)-bin.zip/g' >index.php 17 | 18 | $(UDF_DOCS_HTML_D):doc 19 | 20 | clean-local: 21 | rm -rf html *.frag index.php 22 | 23 | -------------------------------------------------------------------------------- /doc/Makefile.in: -------------------------------------------------------------------------------- 1 | # Makefile.in generated by automake 1.16.1 from Makefile.am. 2 | # @configure_input@ 3 | 4 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. 5 | 6 | # This Makefile.in is free software; the Free Software Foundation 7 | # gives unlimited permission to copy and/or distribute it, 8 | # with or without modifications, as long as this notice is preserved. 9 | 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY, to the extent permitted by law; without 12 | # even the implied warranty of MERCHANTABILITY or FITNESS FOR A 13 | # PARTICULAR PURPOSE. 14 | 15 | @SET_MAKE@ 16 | VPATH = @srcdir@ 17 | am__is_gnu_make = { \ 18 | if test -z '$(MAKELEVEL)'; then \ 19 | false; \ 20 | elif test -n '$(MAKE_HOST)'; then \ 21 | true; \ 22 | elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ 23 | true; \ 24 | else \ 25 | false; \ 26 | fi; \ 27 | } 28 | am__make_running_with_option = \ 29 | case $${target_option-} in \ 30 | ?) ;; \ 31 | *) echo "am__make_running_with_option: internal error: invalid" \ 32 | "target option '$${target_option-}' specified" >&2; \ 33 | exit 1;; \ 34 | esac; \ 35 | has_opt=no; \ 36 | sane_makeflags=$$MAKEFLAGS; \ 37 | if $(am__is_gnu_make); then \ 38 | sane_makeflags=$$MFLAGS; \ 39 | else \ 40 | case $$MAKEFLAGS in \ 41 | *\\[\ \ ]*) \ 42 | bs=\\; \ 43 | sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ 44 | | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ 45 | esac; \ 46 | fi; \ 47 | skip_next=no; \ 48 | strip_trailopt () \ 49 | { \ 50 | flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ 51 | }; \ 52 | for flg in $$sane_makeflags; do \ 53 | test $$skip_next = yes && { skip_next=no; continue; }; \ 54 | case $$flg in \ 55 | *=*|--*) continue;; \ 56 | -*I) strip_trailopt 'I'; skip_next=yes;; \ 57 | -*I?*) strip_trailopt 'I';; \ 58 | -*O) strip_trailopt 'O'; skip_next=yes;; \ 59 | -*O?*) strip_trailopt 'O';; \ 60 | -*l) strip_trailopt 'l'; skip_next=yes;; \ 61 | -*l?*) strip_trailopt 'l';; \ 62 | -[dEDm]) skip_next=yes;; \ 63 | -[JT]) skip_next=yes;; \ 64 | esac; \ 65 | case $$flg in \ 66 | *$$target_option*) has_opt=yes; break;; \ 67 | esac; \ 68 | done; \ 69 | test $$has_opt = yes 70 | am__make_dryrun = (target_option=n; $(am__make_running_with_option)) 71 | am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) 72 | pkgdatadir = $(datadir)/@PACKAGE@ 73 | pkgincludedir = $(includedir)/@PACKAGE@ 74 | pkglibdir = $(libdir)/@PACKAGE@ 75 | pkglibexecdir = $(libexecdir)/@PACKAGE@ 76 | am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd 77 | install_sh_DATA = $(install_sh) -c -m 644 78 | install_sh_PROGRAM = $(install_sh) -c 79 | install_sh_SCRIPT = $(install_sh) -c 80 | INSTALL_HEADER = $(INSTALL_DATA) 81 | transform = $(program_transform_name) 82 | NORMAL_INSTALL = : 83 | PRE_INSTALL = : 84 | POST_INSTALL = : 85 | NORMAL_UNINSTALL = : 86 | PRE_UNINSTALL = : 87 | POST_UNINSTALL = : 88 | build_triplet = @build@ 89 | host_triplet = @host@ 90 | subdir = doc 91 | ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 92 | am__aclocal_m4_deps = $(top_srcdir)/config/ax_lib_mysql.m4 \ 93 | $(top_srcdir)/config/ax_mysql_bin.m4 \ 94 | $(top_srcdir)/config/pcre.m4 $(top_srcdir)/config/ghmysql.m4 \ 95 | $(top_srcdir)/config/ax_pthread.m4 \ 96 | $(top_srcdir)/config/ax_pthread_np.m4 \ 97 | $(top_srcdir)/configure.ac 98 | am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ 99 | $(ACLOCAL_M4) 100 | DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) 101 | mkinstalldirs = $(install_sh) -d 102 | CONFIG_HEADER = $(top_builddir)/config.h 103 | CONFIG_CLEAN_FILES = 104 | CONFIG_CLEAN_VPATH_FILES = 105 | AM_V_P = $(am__v_P_@AM_V@) 106 | am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) 107 | am__v_P_0 = false 108 | am__v_P_1 = : 109 | AM_V_GEN = $(am__v_GEN_@AM_V@) 110 | am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) 111 | am__v_GEN_0 = @echo " GEN " $@; 112 | am__v_GEN_1 = 113 | AM_V_at = $(am__v_at_@AM_V@) 114 | am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) 115 | am__v_at_0 = @ 116 | am__v_at_1 = 117 | SOURCES = 118 | DIST_SOURCES = 119 | am__can_run_installinfo = \ 120 | case $$AM_UPDATE_INFO_DIR in \ 121 | n|no|NO) false;; \ 122 | *) (install-info --version) >/dev/null 2>&1;; \ 123 | esac 124 | am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) 125 | am__DIST_COMMON = $(srcdir)/Makefile.in 126 | DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) 127 | ACLOCAL = @ACLOCAL@ 128 | AMTAR = @AMTAR@ 129 | AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ 130 | AR = @AR@ 131 | AS = @AS@ 132 | AUTOCONF = @AUTOCONF@ 133 | AUTOHEADER = @AUTOHEADER@ 134 | AUTOMAKE = @AUTOMAKE@ 135 | AWK = @AWK@ 136 | CC = @CC@ 137 | CCDEPMODE = @CCDEPMODE@ 138 | CFLAGS = @CFLAGS@ 139 | CPP = @CPP@ 140 | CPPFLAGS = @CPPFLAGS@ 141 | CYGPATH_W = @CYGPATH_W@ 142 | DEFS = @DEFS@ 143 | DEPDIR = @DEPDIR@ 144 | DLLTOOL = @DLLTOOL@ 145 | DSYMUTIL = @DSYMUTIL@ 146 | DUMPBIN = @DUMPBIN@ 147 | ECHO_C = @ECHO_C@ 148 | ECHO_N = @ECHO_N@ 149 | ECHO_T = @ECHO_T@ 150 | EGREP = @EGREP@ 151 | EXEEXT = @EXEEXT@ 152 | FGREP = @FGREP@ 153 | GHMYSQL_CFLAGS = @GHMYSQL_CFLAGS@ 154 | GREP = @GREP@ 155 | INSTALL = @INSTALL@ 156 | INSTALL_DATA = @INSTALL_DATA@ 157 | INSTALL_PROGRAM = @INSTALL_PROGRAM@ 158 | INSTALL_SCRIPT = @INSTALL_SCRIPT@ 159 | INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ 160 | LD = @LD@ 161 | LDFLAGS = @LDFLAGS@ 162 | LIBOBJS = @LIBOBJS@ 163 | LIBS = @LIBS@ 164 | LIBTOOL = @LIBTOOL@ 165 | LIPO = @LIPO@ 166 | LN_S = @LN_S@ 167 | LTLIBOBJS = @LTLIBOBJS@ 168 | LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ 169 | MAKEINFO = @MAKEINFO@ 170 | MANIFEST_TOOL = @MANIFEST_TOOL@ 171 | MKDIR_P = @MKDIR_P@ 172 | MYSQL = @MYSQL@ 173 | MYSQLADMIN = @MYSQLADMIN@ 174 | MYSQLTEST = @MYSQLTEST@ 175 | MYSQL_CFLAGS = @MYSQL_CFLAGS@ 176 | MYSQL_CONFIG = @MYSQL_CONFIG@ 177 | MYSQL_HEADERS = @MYSQL_HEADERS@ 178 | MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ 179 | MYSQL_PLUGINDIR = @MYSQL_PLUGINDIR@ 180 | MYSQL_VERSION = @MYSQL_VERSION@ 181 | NM = @NM@ 182 | NMEDIT = @NMEDIT@ 183 | OBJDUMP = @OBJDUMP@ 184 | OBJEXT = @OBJEXT@ 185 | OTOOL = @OTOOL@ 186 | OTOOL64 = @OTOOL64@ 187 | PACKAGE = @PACKAGE@ 188 | PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ 189 | PACKAGE_NAME = @PACKAGE_NAME@ 190 | PACKAGE_STRING = @PACKAGE_STRING@ 191 | PACKAGE_TARNAME = @PACKAGE_TARNAME@ 192 | PACKAGE_URL = @PACKAGE_URL@ 193 | PACKAGE_VERSION = @PACKAGE_VERSION@ 194 | PATH_SEPARATOR = @PATH_SEPARATOR@ 195 | PCRE_CFLAGS = @PCRE_CFLAGS@ 196 | PCRE_CONFIG = @PCRE_CONFIG@ 197 | PCRE_LIBS = @PCRE_LIBS@ 198 | PTHREAD_CC = @PTHREAD_CC@ 199 | PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ 200 | PTHREAD_LIBS = @PTHREAD_LIBS@ 201 | RANLIB = @RANLIB@ 202 | SED = @SED@ 203 | SET_MAKE = @SET_MAKE@ 204 | SHELL = @SHELL@ 205 | STRIP = @STRIP@ 206 | VERSION = @VERSION@ 207 | abs_builddir = @abs_builddir@ 208 | abs_srcdir = @abs_srcdir@ 209 | abs_top_builddir = @abs_top_builddir@ 210 | abs_top_srcdir = @abs_top_srcdir@ 211 | ac_ct_AR = @ac_ct_AR@ 212 | ac_ct_CC = @ac_ct_CC@ 213 | ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 214 | am__include = @am__include@ 215 | am__leading_dot = @am__leading_dot@ 216 | am__quote = @am__quote@ 217 | am__tar = @am__tar@ 218 | am__untar = @am__untar@ 219 | ax_pthread_config = @ax_pthread_config@ 220 | bindir = @bindir@ 221 | build = @build@ 222 | build_alias = @build_alias@ 223 | build_cpu = @build_cpu@ 224 | build_os = @build_os@ 225 | build_vendor = @build_vendor@ 226 | builddir = @builddir@ 227 | datadir = @datadir@ 228 | datarootdir = @datarootdir@ 229 | docdir = @docdir@ 230 | dvidir = @dvidir@ 231 | exec_prefix = @exec_prefix@ 232 | host = @host@ 233 | host_alias = @host_alias@ 234 | host_cpu = @host_cpu@ 235 | host_os = @host_os@ 236 | host_vendor = @host_vendor@ 237 | htmldir = @htmldir@ 238 | includedir = @includedir@ 239 | infodir = @infodir@ 240 | install_sh = @install_sh@ 241 | libdir = @libdir@ 242 | libexecdir = @libexecdir@ 243 | localedir = @localedir@ 244 | localstatedir = @localstatedir@ 245 | mandir = @mandir@ 246 | mkdir_p = @mkdir_p@ 247 | oldincludedir = @oldincludedir@ 248 | pdfdir = @pdfdir@ 249 | prefix = @prefix@ 250 | program_transform_name = @program_transform_name@ 251 | psdir = @psdir@ 252 | runstatedir = @runstatedir@ 253 | sbindir = @sbindir@ 254 | sharedstatedir = @sharedstatedir@ 255 | srcdir = @srcdir@ 256 | sysconfdir = @sysconfdir@ 257 | target_alias = @target_alias@ 258 | top_build_prefix = @top_build_prefix@ 259 | top_builddir = @top_builddir@ 260 | top_srcdir = @top_srcdir@ 261 | UDF_DOCS_HTML = index.html doxygen.css doxygen.png 262 | UDF_DOCS_HTML_D = $(UDF_DOCS_HTML:%=html/%) 263 | EXTRA_DIST = $(UDF_DOCS_HTML_D) INSTALL.windows 264 | DOXYGEN = doxygen 265 | all: all-am 266 | 267 | .SUFFIXES: 268 | $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) 269 | @for dep in $?; do \ 270 | case '$(am__configure_deps)' in \ 271 | *$$dep*) \ 272 | ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ 273 | && { if test -f $@; then exit 0; else break; fi; }; \ 274 | exit 1;; \ 275 | esac; \ 276 | done; \ 277 | echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ 278 | $(am__cd) $(top_srcdir) && \ 279 | $(AUTOMAKE) --gnu doc/Makefile 280 | Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 281 | @case '$?' in \ 282 | *config.status*) \ 283 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ 284 | *) \ 285 | echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ 286 | cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 287 | esac; 288 | 289 | $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) 290 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 291 | 292 | $(top_srcdir)/configure: $(am__configure_deps) 293 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 294 | $(ACLOCAL_M4): $(am__aclocal_m4_deps) 295 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 296 | $(am__aclocal_m4_deps): 297 | 298 | mostlyclean-libtool: 299 | -rm -f *.lo 300 | 301 | clean-libtool: 302 | -rm -rf .libs _libs 303 | tags TAGS: 304 | 305 | ctags CTAGS: 306 | 307 | cscope cscopelist: 308 | 309 | 310 | distdir: $(BUILT_SOURCES) 311 | $(MAKE) $(AM_MAKEFLAGS) distdir-am 312 | 313 | distdir-am: $(DISTFILES) 314 | @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ 315 | topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ 316 | list='$(DISTFILES)'; \ 317 | dist_files=`for file in $$list; do echo $$file; done | \ 318 | sed -e "s|^$$srcdirstrip/||;t" \ 319 | -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ 320 | case $$dist_files in \ 321 | */*) $(MKDIR_P) `echo "$$dist_files" | \ 322 | sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ 323 | sort -u` ;; \ 324 | esac; \ 325 | for file in $$dist_files; do \ 326 | if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ 327 | if test -d $$d/$$file; then \ 328 | dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ 329 | if test -d "$(distdir)/$$file"; then \ 330 | find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ 331 | fi; \ 332 | if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ 333 | cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ 334 | find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ 335 | fi; \ 336 | cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ 337 | else \ 338 | test -f "$(distdir)/$$file" \ 339 | || cp -p $$d/$$file "$(distdir)/$$file" \ 340 | || exit 1; \ 341 | fi; \ 342 | done 343 | check-am: all-am 344 | check: check-am 345 | all-am: Makefile 346 | installdirs: 347 | install: install-am 348 | install-exec: install-exec-am 349 | install-data: install-data-am 350 | uninstall: uninstall-am 351 | 352 | install-am: all-am 353 | @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am 354 | 355 | installcheck: installcheck-am 356 | install-strip: 357 | if test -z '$(STRIP)'; then \ 358 | $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ 359 | install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ 360 | install; \ 361 | else \ 362 | $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ 363 | install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ 364 | "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ 365 | fi 366 | mostlyclean-generic: 367 | 368 | clean-generic: 369 | 370 | distclean-generic: 371 | -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) 372 | -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) 373 | 374 | maintainer-clean-generic: 375 | @echo "This command is intended for maintainers to use" 376 | @echo "it deletes files that may require special tools to rebuild." 377 | clean: clean-am 378 | 379 | clean-am: clean-generic clean-libtool clean-local mostlyclean-am 380 | 381 | distclean: distclean-am 382 | -rm -f Makefile 383 | distclean-am: clean-am distclean-generic 384 | 385 | dvi: dvi-am 386 | 387 | dvi-am: 388 | 389 | html: html-am 390 | 391 | html-am: 392 | 393 | info: info-am 394 | 395 | info-am: 396 | 397 | install-data-am: 398 | 399 | install-dvi: install-dvi-am 400 | 401 | install-dvi-am: 402 | 403 | install-exec-am: 404 | 405 | install-html: install-html-am 406 | 407 | install-html-am: 408 | 409 | install-info: install-info-am 410 | 411 | install-info-am: 412 | 413 | install-man: 414 | 415 | install-pdf: install-pdf-am 416 | 417 | install-pdf-am: 418 | 419 | install-ps: install-ps-am 420 | 421 | install-ps-am: 422 | 423 | installcheck-am: 424 | 425 | maintainer-clean: maintainer-clean-am 426 | -rm -f Makefile 427 | maintainer-clean-am: distclean-am maintainer-clean-generic 428 | 429 | mostlyclean: mostlyclean-am 430 | 431 | mostlyclean-am: mostlyclean-generic mostlyclean-libtool 432 | 433 | pdf: pdf-am 434 | 435 | pdf-am: 436 | 437 | ps: ps-am 438 | 439 | ps-am: 440 | 441 | uninstall-am: 442 | 443 | .MAKE: install-am install-strip 444 | 445 | .PHONY: all all-am check check-am clean clean-generic clean-libtool \ 446 | clean-local cscopelist-am ctags-am distclean distclean-generic \ 447 | distclean-libtool distdir dvi dvi-am html html-am info info-am \ 448 | install install-am install-data install-data-am install-dvi \ 449 | install-dvi-am install-exec install-exec-am install-html \ 450 | install-html-am install-info install-info-am install-man \ 451 | install-pdf install-pdf-am install-ps install-ps-am \ 452 | install-strip installcheck installcheck-am installdirs \ 453 | maintainer-clean maintainer-clean-generic mostlyclean \ 454 | mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ 455 | tags-am uninstall uninstall-am 456 | 457 | .PRECIOUS: Makefile 458 | 459 | 460 | all: 461 | 462 | doc: 463 | $(DOXYGEN) Doxyfile 464 | cat html/index.html | awk '//,/
' | sed 's//

/g' | sed 's/<\/h2>/<\/h1>/g' | sed 's/index.html/index.php/g' > lib_mysqludf_preg.frag 465 | cat index.php.in | sed 's//$(PACKAGE_TARNAME)-$(PACKAGE_VERSION).tar.gz/g'| sed 's/<__VERSION__>/$(PACKAGE_VERSION)/g' | sed 's//$(PACKAGE)-$(PACKAGE_VERSION)-bin.zip/g' >index.php 466 | 467 | $(UDF_DOCS_HTML_D):doc 468 | 469 | clean-local: 470 | rm -rf html *.frag index.php 471 | 472 | # Tell versions [3.59,3.63) of GNU make to not export all variables. 473 | # Otherwise a system limit (for SysV at least) may be exceeded. 474 | .NOEXPORT: 475 | -------------------------------------------------------------------------------- /doc/index.php.in: -------------------------------------------------------------------------------- 1 | 4 | 5 | mark('column1'); ?> 6 |
7 |
8 |

Download

9 |
10 | 17 |
18 |
19 |
20 |

Information

21 |
22 |
23 |

24 | A library of functions that add support for perl compatible regular expressions to MySQL. 25 |

26 |
27 |
28 | endmark(); ?> 29 | 30 | 31 | 32 | mark('column1'); ?> 33 |
34 |
35 |

See also

36 |
37 |
38 | 40 |
41 |
42 | endmark(); ?> 43 | 44 |
45 |

 

46 |
47 |
 
48 |
49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /doc/mainpage.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2013 Rich Waters 3 | * 4 | * This file is part of lib_mysqludf_preg. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | // This file contains comments intended to help doxygen generate the 26 | // main page of the documentation. 27 | 28 | 29 | /** @mainpage lib_mysqludf_preg 30 | * 31 | * @section intro_sec Introduction 32 | * 33 | * lib_mysqludf_preg is a library of mysql UDFs 34 | * (user-defined-functions) that provide access to the PCRE (perl 35 | * compatible-regular-expressions) library for pattern matching. The 36 | * PCRE library is a set of functions that implement regular 37 | * expression pattern matching using the same syntax and semantics as 38 | * Perl 5. This syntax can often handle more complex expressions and 39 | * capturing than standard regular expression implementations. For 40 | * more information about PCRE, please see: http://www.pcre.org/ 41 | * 42 | * @n lib_mysqludf_preg is a useful performance optimization for those 43 | * applications that are already performing these regular expression 44 | * matches in a high level language (ie. PHP) on the client side. It 45 | * is also helpful when there is a need to capture a parenthesized 46 | * subexpression from a regular expression, or simply as a slight 47 | * performance boost over the builtin RLIKE/REGEXP functions. 48 | * 49 | * @section Installation 50 | * 51 | * lib_mysqludf_preg is distributed as a source package. (Binaries are 52 | * available for the Windows version.) The instructions below provide some 53 | * information about how to configure and compile the library. Please 54 | * consult the INSTALL file included with the source package for 55 | * more details. If installing from source for Windows please consult 56 | * the doc/INSTALL.win file. 57 | * 58 | * @subsection FromSource From Source 59 | * 60 | * @subsubsection Prerequisites 61 | * 62 | * These UDFs require that the libpcre headers and library are 63 | * installed. For debian/ubuntu type systems, installing libpcre3-dev 64 | * should be sufficient. (apt-get install libpcre3-dev). 65 | * 66 | * @subsubsection Compilation 67 | * 68 | * Most users should be able to simply type: 69 | * ./configure ; make install 70 | * 71 | * If mysql is an unusual place, you might need to 72 | * add --with-mysql=<mysql directory>/bin/mysql_config. 73 | * 74 | * Similarly, if licpcre is in an unusual place, --with-pcre can be added. 75 | * 76 | * Example (for osx using fink): ./configure --with-pcre=/sw --with-mysql=/sw/bin/mysql_config 77 | * 78 | * Also, version 1.1 changes the way NULLs are handled. To restore the legacy NULL handling, add 79 | * --enable-legacy-nulls to the configure line 80 | * 81 | * @subsubsection "Installing the functions" 82 | * 83 | * Provided the library has been installled into a directory that 84 | * mysql server already has in its LD_LIBRARY_PATH, installation of 85 | * the functions should be as easy as typing: make 86 | * installdb. Any problems encountered are likely related to the 87 | * server's environment and the installation directory. If no problems 88 | * are encountered, type 89 | * make test 90 | * to perform some basic 91 | * tests. 92 | * 93 | * 94 | * @subsection WindowsBinaries Windows Binaries 95 | * 96 | * There is a zip file, downloadable from this site, that contains the 97 | * necessary dll files to run this UDF on windows. One of these dll files 98 | * is the UDF, itself, and the other required dll file is the PCRE library. 99 | * These files both need to be installed in directories where the MySQL server 100 | * can find them. For the 5.0 series of mysql server, this should be the 101 | * bin directory directly under the Mysql\ Server installation. For the 102 | * 5.1 MySQL servers this is the directory as specified by the 103 | * 'plugin_dir' MySQL variable. After copying the files and restarting 104 | * the server, the 3rd file in the archive can be used to create 105 | * the functions. 106 | * 107 | * For more information, please consult the doc/INSTALL.windows file in 108 | * the source package. 109 | * 110 | * @n 111 | * @section Functions 112 | * lib_mysqludf_preg provides the following functions that interface with 113 | * the PCRE library. 114 | * 115 | * @li @ref PREG_CAPTURE_SECTION "preg_capture" 116 | * capture a parenthesized subexpression from a PCRE pattern 117 | * 118 | * @li @ref PREG_CHECK_SECTION "preg_check" 119 | * check if a string is a valid perl-compatible regular expression 120 | * 121 | * @li @ref PREG_POSITION_SECTION "preg_position" 122 | * get position of the of a regular expression capture group in a string 123 | 124 | * @li @ref PREG_REPLACE_SECTION "preg_replace" 125 | * perform regular expression search & replace using PCRE. 126 | * 127 | * @li @ref PREG_RLIKE_SECTION "preg_rlike" 128 | * test if a string matches a perl-compatible regular expression 129 | * 130 | * @li @ref LIB_MYSQLUDF_PREG_INFO_SECTION "lib_mysqludf_preg_info" 131 | * get information about the installed lib_mysqludf_preg library 132 | * 133 | * 134 | * @n 135 | * @section PREG_CAPTURE_SECTION preg_capture 136 | * @copydoc PREG_CAPTURE 137 | * 138 | * @n 139 | * @section PREG_CHECK_SECTION preg_check 140 | * @copydoc PREG_CHECK 141 | * 142 | * @n 143 | * @section PREG_POSITION_SECTION preg_position 144 | * @copydoc PREG_POSITION 145 | * 146 | * @n 147 | * @section PREG_REPLACE_SECTION preg_replace 148 | * @copydoc PREG_REPLACE 149 | * 150 | * @n 151 | * @section PREG_RLIKE_SECTION preg_rlike 152 | * @copydoc PREG_RLIKE 153 | * 154 | * @n 155 | * @section LIB_MYSQLUDF_PREG_INFO_SECTION lib_mysqludf_preg_info 156 | * @copydoc LIB_MYSQLUDF_PREG_INFO 157 | * 158 | */ 159 | 160 | 161 | -------------------------------------------------------------------------------- /from_php.h: -------------------------------------------------------------------------------- 1 | /* 2 | * from_php.h 3 | * eMailGanizer 4 | * 5 | * Created by Rich Waters on 9/3/10. 6 | * Copyright 2010 GoodHumans. All rights reserved. 7 | * 8 | */ 9 | 10 | char *pregReplace(pcre *re , pcre_extra *extra , 11 | const char *subject, int subject_len, const char *replace, 12 | int replace_len , 13 | int is_callable_replace, int *result_len, int limit, 14 | int *replace_count, char *msg , int msglen ); 15 | 16 | pcre *compileRegex( const char *regex , int regex_len , char *msg , int msglen ) ; 17 | -------------------------------------------------------------------------------- /ghfcns.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2013 Rich Waters 3 | * 4 | * This file is part of lib_mysqludf_preg. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | /** @file ghfcns.c 26 | * 27 | * @brief Provides some utility functions that are independent of mysql. 28 | * 29 | */ 30 | 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include "ghfcns.h" 39 | 40 | /** 41 | * @fn char *ghstrndup( char *s , int l ) 42 | * 43 | * @brief safe strndup 44 | * 45 | * @param s - bytes to copy 46 | * @param l - number of bytes to copy 47 | * 48 | * @return ptr - to newly allocate memory 49 | * @return NULL - if memory not available 50 | * 51 | * @details - This function copies the given number of bytes from the given 52 | * buffer into a newly allocated memory area. It then adds a '\\0' to the 53 | * end. This function shouldn't be necessary, but since many call rely on 54 | * null-termination instead of lengths, this creates things that can be 55 | * passed to those functions safely. 56 | */ 57 | char *ghstrndup( char *s , size_t l ) 58 | { 59 | char *colval = NULL ; 60 | 61 | colval = malloc( l + 1 ) ; 62 | if( !colval ) 63 | { 64 | fprintf( stderr , "Not enough memory: %zu\n" , l ) ; 65 | return NULL ; 66 | } 67 | memcpy( colval , s , l ) ; 68 | colval[ l ] = '\0'; 69 | 70 | return colval ; 71 | } 72 | 73 | 74 | /** 75 | * @fn void ghlogprintf( fmt, ... ) 76 | * 77 | * @brief log an error message to stderr in MySQL format 78 | * 79 | * @param fmt - a format string as per sprintf() 80 | * @param ... - varargs as per sprintf() 81 | * 82 | * @return void 83 | * 84 | * @details - This function writes the specified error message 85 | * to stderr prefixed by the current time in the same format 86 | * used by MySQL 87 | */ 88 | void ghlogprintf(char *fmt, ...) { 89 | va_list vargs; 90 | char buf[18]; 91 | time_t now; 92 | struct tm time_val; 93 | 94 | memset(&buf, 0, sizeof(buf)); 95 | 96 | now = time(NULL); 97 | localtime_r(&now, &time_val); 98 | strftime(&buf[0], sizeof(buf), "%y%m%d %H:%M:%S ", &time_val); 99 | fprintf(stderr, "%s", buf); 100 | 101 | va_start(vargs, fmt); 102 | vfprintf(stderr, fmt, vargs); 103 | va_end(vargs); 104 | } 105 | -------------------------------------------------------------------------------- /ghfcns.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ghfcns.h 3 | * eMailGanizer 4 | * 5 | * Created by Rich Waters on 9/3/10. 6 | * Copyright 2010 GoodHumans. All rights reserved. 7 | * 8 | */ 9 | 10 | char *ghstrndup( char *s , size_t l ); 11 | void ghlogprintf(char *fmt, ...); 12 | 13 | -------------------------------------------------------------------------------- /ghmysql.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2013 Rich Waters 3 | * 4 | * This file is part of lib_mysqludf_preg. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | 26 | /** @file ghmysql.c 27 | * 28 | * @brief Provides some functions that are shared by the various 29 | * gh udf functions. 30 | * 31 | */ 32 | #include "ghmysql.h" 33 | #include "ghfcns.h" 34 | #include 35 | #include 36 | 37 | 38 | /** 39 | * @fn char *ghargdup( UDF_ARGS *args,int i ) 40 | * 41 | * @brief extract argument as a newly allocated null-terminated memory area 42 | * 43 | * @param args - args from the UDF function call 44 | * @param i - offset of argument to extract. 45 | * 46 | * @return pointer - to newly allocate memory if successful 47 | * @return NULL - if arg is NULL or not enough memory 48 | * 49 | */ 50 | char *ghargdup( UDF_ARGS *args,int i ) 51 | { 52 | int l ; 53 | char *s ; 54 | char *colval = NULL ; 55 | 56 | if( (l=args->lengths[i] ) && (s=args->args[i]) ) 57 | { 58 | colval = ghstrndup( s , l ) ; 59 | } 60 | 61 | return colval ; 62 | } 63 | 64 | /** 65 | * @fn char *ghargdups( UDF_ARGS *args,int i , unsigned long *l) 66 | * 67 | * @brief extract argument as a newly allocated null-terminated memory area, 68 | * and set the length to the size of that area 69 | * 70 | * @param args - args from the UDF function call 71 | * @param i - offset of argument to extract. 72 | * @param l - store the length of the argument here 73 | * 74 | * @return pointer - to newly allocate memory if successful 75 | * 76 | * @details This is useful for guaranteeing not to have NULL as an argument 77 | */ 78 | char *ghargdups( UDF_ARGS *args , int i , unsigned long *l) 79 | { 80 | if( !(*l=args->lengths[ i ])) 81 | { 82 | return strdup( "" ) ; 83 | } 84 | else if( !args->args[i]) { 85 | *l = 0 ; 86 | return strdup( "" ) ; 87 | } 88 | else { 89 | return ghargdup( args , i ) ; 90 | } 91 | } 92 | 93 | 94 | /** 95 | * @fn char *ghargIsNull( UDF_ARGS *args,int argNum) 96 | * 97 | * @brief is the given argument NULL 98 | * 99 | * @param args - args from the UDF function call 100 | * @param i - the argument to test 101 | * 102 | * @return int - 1 if the argument is NULL, 0 otherwise 103 | * 104 | * @details - this only returns true if the arg is specified as NULL 105 | * when in the mysql statement. This does not return true if the 106 | * NULL results from evaluating a column. The purpose of this function 107 | * in so that init functions can differentiate NULL constants from 108 | * NULL meaning that there are no constant arguments. This is important 109 | * because there is better error handling in the API for init functions 110 | * than mains. 111 | */ 112 | int ghargIsNullConstant(UDF_ARGS *args, int argNum) 113 | { 114 | if( args->arg_count > argNum && !args->args[argNum] && 115 | !strncmp( args->attributes[argNum], "NULL" , 4 ) ) { 116 | return 1 ; 117 | } 118 | 119 | return 0 ; 120 | } 121 | 122 | -------------------------------------------------------------------------------- /ghmysql.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) 2007-2013 Rich Waters 4 | * 5 | * This file is part of lib_mysqludf_preg. 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | 26 | #ifndef GHMYSQL_H 27 | 28 | #define GHMYSQL_H 29 | 30 | #if defined(_WIN32) || defined(_WIN64) 31 | #include 32 | #endif 33 | 34 | /** @file ghmysql.h 35 | * 36 | * @brief headers for ghmysql functions 37 | */ 38 | 39 | 40 | // This conflicts with my_config.h. Therefore is it required that 41 | // STANDARD is defined (in Makefile.am) in order that those mysql 42 | // functions are not included. 43 | #include "config.h" 44 | 45 | 46 | // Taken from udf_example.c 47 | 48 | #ifdef STANDARD 49 | /* STANDARD is defined, don't use any mysql functions */ 50 | #include 51 | #include 52 | #include 53 | #ifdef __WIN__ 54 | typedef unsigned __int64 ulonglong; /* Microsofts 64 bit types */ 55 | typedef __int64 longlong; 56 | #else 57 | typedef unsigned long long ulonglong; 58 | typedef long long longlong; 59 | #endif /*__WIN__*/ 60 | #else 61 | #include 62 | #include 63 | #if defined(MYSQL_SERVER) 64 | #include /* To get strmov() */ 65 | #else 66 | /* when compiled as standalone */ 67 | #define strmov(a,b) strcpy(a,b) 68 | #define bzero(a,b) memset(a,0,b) 69 | #define memcpy_fixed(a,b,c) memcpy(a,b,c) 70 | #endif 71 | #endif 72 | #include 73 | #include 74 | 75 | /* 76 | * GHMYSQL utility functions: 77 | */ 78 | char *ghargdup( UDF_ARGS *args,int i ) ; 79 | char *ghargdups( UDF_ARGS *args,int i , unsigned long *l) ; 80 | //char *ghstrndup( char *s , int l ); 81 | int ghargIsNullConstant(UDF_ARGS *args, int argNum); 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /installdb.sql: -------------------------------------------------------------------------------- 1 | 2 | USE mysql; 3 | CREATE FUNCTION lib_mysqludf_preg_info RETURNS STRING SONAME 'lib_mysqludf_preg.so'; 4 | CREATE FUNCTION preg_capture RETURNS STRING SONAME 'lib_mysqludf_preg.so'; 5 | CREATE FUNCTION preg_check RETURNS INTEGER SONAME 'lib_mysqludf_preg.so'; 6 | CREATE FUNCTION preg_replace RETURNS STRING SONAME 'lib_mysqludf_preg.so'; 7 | CREATE FUNCTION preg_rlike RETURNS INTEGER SONAME 'lib_mysqludf_preg.so'; 8 | CREATE FUNCTION preg_position RETURNS INTEGER SONAME 'lib_mysqludf_preg.so'; 9 | 10 | 11 | -------------------------------------------------------------------------------- /lib_mysqludf_preg_capture.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2013 Rich Waters 3 | * 4 | * This file is part of lib_mysqludf_preg. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | 26 | /** 27 | * @file lib_mysqludf_preg_capture.c 28 | * 29 | * @brief Implements the PREG_CAPTURE mysql udf 30 | * 31 | */ 32 | 33 | 34 | /** 35 | * @page PREG_CAPTURE PREG_CAPTURE 36 | * 37 | * @brief capture a parenthesized subexpression from a PCRE pattern 38 | * 39 | * @par Function Installation 40 | * CREATE FUNCTION preg_capture RETURNS STRING SONAME 'lib_mysqludf_preg.so'; 41 | * 42 | * @par Synopsis 43 | * PREG_CAPTURE( pattern , subject [, group] [, occurence] ) 44 | * 45 | * @par 46 | * @param pattern - is a string that is a perl compatible regular 47 | * expression as documented at: 48 | * http://us.php.net/manual/en/ref.pcre.php This expression passed to 49 | * this function should have delimiters and can contain the standard 50 | * perl modifiers after the ending delimiter. 51 | * 52 | * @param subject -is the data to perform the match & capture on 53 | * 54 | * @param group - is the capture group that should be 55 | * returned. This can be a numeric capture group or a named capture group. 56 | * Numeric groups should be passed in as integers while named groups should be 57 | * strings. If not speficied, this defaults to 0, which will capture the 58 | * entire matching regular expression. 59 | * 60 | * @param occurence - which match of the regex to perform capture on. 61 | * This is useful for subjects that have multiple matches of the pattern. If 62 | * not speficied, this defaults to 1, which will capture the requested group, 63 | * from the first matching occurence of the pattern. 64 | * 65 | * @return - string that was captured - if there was a match and the desired 66 | * capture group is valid 67 | * @return - string that is the entire portion of subject which matches the 68 | * pattern - if 0 is passed in as the group and pattern matches subject 69 | * @return - NULL - if pattern does not match the subject or group is not a 70 | * valid capture group for the given pattern and subject. 71 | * 72 | * @details 73 | * preg_capture is a udf that captures parenthesized sub-expressions 74 | * from a pcre pattern. 75 | * 76 | * @par Examples: 77 | * 78 | * 79 | * SELECT PREG_CAPTURE('/(.*?)(fox)/' , 'the quick brown fox' ,2 ); 80 | * 81 | * @b Yields: 82 | * @verbatim 83 | +----------------------------------------------------------+ 84 | | PREG_CAPTURE('/(.*?)(fox)/' , 'the quick brown fox' ,2 ) | 85 | +----------------------------------------------------------+ 86 | | fox | 87 | +----------------------------------------------------------+ 88 | @endverbatim 89 | * 90 | * SELECT PREG_CAPTURE( '/"([^"]+)"/' , 'the "quick" brown fox "jumped" over the "lazy" dog' , 1,2 ); 91 | * 92 | * @verbatim 93 | +--------------------------------------------------------------------------------------------+ 94 | | PREG_CAPTURE( '/"([^"]+)"/' , 'the "quick" brown fox "jumped" over the "lazy" dog' , 1,2 ) | 95 | +--------------------------------------------------------------------------------------------+ 96 | | jumped | 97 | +--------------------------------------------------------------------------------------------+ 98 | @endverbatim 99 | * 100 | * SELECT PREG_CAPTURE( '/b[^\\s]+/' , 'the quick brown fox jumped over' ) 101 | * 102 | * @b Yields: 103 | * 104 | * @verbatim 105 | +------------------------------------------------------------------+ 106 | | PREG_CAPTURE( '/b[^\\s]+/' , 'the quick brown fox jumped over' ) | 107 | +------------------------------------------------------------------+ 108 | | brown | 109 | +------------------------------------------------------------------+ 110 | @endverbatim 111 | * 112 | * @note 113 | * Remember to add a backslash to escape patterns that use \ notation 114 | */ 115 | 116 | 117 | #include "ghmysql.h" 118 | #include "preg.h" 119 | 120 | /* 121 | * Public function declarations: 122 | */ 123 | bool preg_capture_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 124 | char *preg_capture( UDF_INIT *initid __attribute__((unused)), 125 | UDF_ARGS *args, char *result, unsigned long *length, 126 | char *is_null __attribute__((unused)), 127 | char *error __attribute__((unused))); 128 | void preg_capture_deinit( UDF_INIT* initid ); 129 | 130 | 131 | /** 132 | * @fn bool preg_capture_init(UDF_INIT *initid, UDF_ARGS *args, 133 | * char *message) 134 | * 135 | * @brief 136 | * Perform the per-query initializations for PREG_CAPTURE 137 | * 138 | * @param initid - various info supplied by mysql api - read mode at 139 | * http://dev.mysql.com/doc/refman/5.0/en/adding-udf.html 140 | * 141 | * @param args - array of information about arguments from the SQL call 142 | * See file documentation for the description of the SQL arguments 143 | * 144 | * @param message - for error messages. Should be <80 but can be 255. 145 | * 146 | * @return 0 - on success 147 | * @return 1 - on error 148 | * 149 | * @details This function calls pregInit to handle the common init taskes. 150 | * It also checks to make sure there are at least arguments, and checks 151 | * the type of the 'group' and 'occurence' arguments. 152 | */ 153 | bool preg_capture_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 154 | { 155 | if (args->arg_count < 2) 156 | { 157 | strncpy(message,"PREG_CAPTURE: requires at least 2 arguments", MYSQL_ERRMSG_SIZE); 158 | return 1; 159 | } 160 | 161 | if( args->arg_count > 3 && args->arg_type[3] != INT_RESULT ) { 162 | strncpy(message,"PREG_CAPTURE: optional occurence argument must be an integer", MYSQL_ERRMSG_SIZE); 163 | return 1; 164 | } 165 | 166 | // If occurence isn't an int, then it is a named capture group 167 | if( args->arg_count > 2 && args->arg_type[2] != INT_RESULT ) 168 | args->arg_type[2] != STRING_RESULT ; 169 | 170 | // preg_capture can return NULL 171 | initid->maybe_null=1; 172 | 173 | // Default value of max_length should be sufficient 174 | 175 | return ( pregInit( initid , args , message ) ) ; 176 | } 177 | 178 | 179 | /** 180 | * @fn char *preg_capture(UDF_INIT *initid , UDF_ARGS *args, char *result, 181 | * unsigned long *length, char *is_null , char *error ) 182 | * 183 | * @brief 184 | * The main routine for the PREG_CAPTURE udf. 185 | * 186 | * @param initid - various info supplied by mysql api - read more at 187 | * http://dev.mysql.com/doc/refman/5.0/en/adding-udf.html 188 | * 189 | * @param args - array of information about arguments from the SQL call 190 | * See file documentation for the description of the SQL arguments 191 | * 192 | * @param result - a place the captured string can be placed (255 len max) 193 | * @param length - put the length of the captured item here. 194 | * @param is_null - set this if return value is null 195 | * @param error - to be set if an error occurs 196 | * 197 | * @return - string - if the numeric or named group can be captured 198 | * @return - NULL - if no match or some other problem 199 | * 200 | * @details This function uses the pregSkipToOccurence function to call 201 | * pcre_ex repeatedly until the requested occurence is found. 202 | * It then uses pcre_get_substring (or copy) to retrieve any 203 | * capture groups from the pattern. It then returns the appropriate 204 | * string or NULL. 205 | */ 206 | char *preg_capture(UDF_INIT *initid , UDF_ARGS *args, char *result, 207 | unsigned long *length, char *is_null , char *error ) 208 | { 209 | char *ex_subject ; /* part subject starting after occurence*/ 210 | int groupnum ; /* numeric group - found or from args */ 211 | int l ; /* length of captured info */ 212 | char msg[255] ; /* to store errors from regex compile */ 213 | int occurence ; /* occurence of the pattern to capture from */ 214 | int oveccount ; /* number of items captures */ 215 | int *ovector; /* for offsets of captures */ 216 | struct preg_s *ptr ; /* local holder of initid->ptr */ 217 | int rc ; /* number of regex's matched by pattern */ 218 | pcre *re ; /* the compiled pattern */ 219 | const char *res2 ; /* for pcre_get_substring to alloc */ 220 | char *subject ; /* args[1] */ 221 | 222 | ptr = (struct preg_s *) initid->ptr ; 223 | 224 | *is_null = 1 ; /* default to NULL return */ 225 | *error = 0 ; /* default to no error */ 226 | *ptr->return_buffer = '\0'; /* clear return value */ 227 | *length = 0 ; /* just to be safe */ 228 | 229 | #ifndef GH_1_0_NULL_HANDLING 230 | if( ghargIsNullConstant( args , 0 ) || ghargIsNullConstant( args , 1 ) 231 | || ghargIsNullConstant( args , 2 ) ) 232 | { 233 | //fprintf( stderr , "null subject. Returning NULL\n" ) ; 234 | *is_null = 1 ; 235 | return NULL ; 236 | } 237 | #endif 238 | 239 | // compile the regex if necessary 240 | if( ptr->constant_pattern ) 241 | re = ptr->re ; 242 | else 243 | { 244 | re = pregCompileRegexArg( args , msg , sizeof(msg)) ; 245 | if( !re ) 246 | { 247 | ghlogprintf( "PREG_CAPTURE: compile failed: %s\n", msg ); 248 | *error = 1 ; 249 | return NULL ; 250 | } 251 | } 252 | 253 | // create vector to hold offsets for pcre 254 | ovector = pregCreateOffsetsVector( re,NULL, &oveccount ,msg,sizeof(msg)) ; 255 | if( !ovector ) 256 | { 257 | ghlogprintf( "PREG_CAPTURE: can't create offset vector :%s\n", msg ); 258 | *error = 1 ; 259 | if( !ptr->constant_pattern ) 260 | pcre_free( re ) ; 261 | return NULL ; 262 | } 263 | 264 | if( args->arg_count > 3 ) 265 | occurence = (int)(*(longlong *)args->args[3]) ; 266 | else 267 | occurence = 1 ; 268 | 269 | subject = ghargdup( args , 1 ) ; 270 | 271 | if( subject ) 272 | { 273 | ex_subject = pregSkipToOccurence( re , subject , args->lengths[1] , 274 | ovector , oveccount , occurence,&rc); 275 | groupnum = -1 ; 276 | if( rc > 0 ) 277 | groupnum = pregGetGroupNum( re , args , 2 ) ; 278 | 279 | // If groupnum found, get the substring and prepare for return 280 | if( groupnum >= 0 && groupnum < (oveccount/3) ) 281 | { 282 | l = pcre_get_substring( ex_subject, ovector,rc,groupnum, &res2 ) ; 283 | 284 | result = pregMoveToReturnValues( initid,length,is_null , error, 285 | (char *)res2 , l ); 286 | } 287 | free( subject ) ; 288 | } 289 | 290 | free( ovector ) ; 291 | 292 | if( !ptr->constant_pattern ) 293 | pcre_free( re ) ; 294 | 295 | return result ; 296 | } 297 | 298 | /** 299 | * @fn void preg_capture_deinit(UDF_INIT *initid) 300 | * 301 | * @brief cleanup after PREG_CAPTURE 302 | * 303 | * @param initid - pointer to struct to be cleaned. 304 | */ 305 | void preg_capture_deinit(UDF_INIT *initid) 306 | { 307 | pregDeInit(initid); 308 | } 309 | -------------------------------------------------------------------------------- /lib_mysqludf_preg_check.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2013 Rich Waters 3 | * 4 | * This file is part of lib_mysqludf_preg. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | 26 | /** 27 | * @file lib_mysqludf_preg_check.c 28 | * 29 | * @brief Implements the PREG_CHECK mysql udf 30 | */ 31 | 32 | 33 | /** 34 | * @page PREG_CHECK PREG_CHECK 35 | * 36 | * @brief Test if a perl-compatible regular expression is valid 37 | * 38 | * @par Function Installation 39 | * CREATE FUNCTION preg_check RETURNS INTEGER SONAME 'lib_mysqludf_preg.so'; 40 | * 41 | * @par Synopsis 42 | * PREG_CHECK( pattern ) 43 | * 44 | * @par 45 | * @param pattern - is a string that might be a perl compatible regular 46 | * expression as documented at: 47 | * http://us.php.net/manual/en/ref.pcre.php 48 | * 49 | * @return 1 - the pcre is valid 50 | * @return 0 - the pcre is NULL, empty, or a bad regex 51 | * 52 | * @details 53 | * preg_check is a udf that tests if whether or not the given 54 | * perl compatible regular expression is valid. This is a useful 55 | * companion to the other functions in the lib_mysqludf_pref library 56 | * in that those functions all return errors (and stop processing) when 57 | * empty, NULL, or incorrect regular expressions are passed in to them. 58 | * If pcre patterns are stored in rows of a database and it is 59 | * not confirmed that the patterns are valid, PCRE_CHECK is useful either 60 | * as a filter used in conjunction with those calls or as a separate 61 | * query to help cleanup the database before using those other functions. 62 | * 63 | * @par Examples: 64 | * 65 | * SELECT PREG_CHECK('/The quick brown fox/i' ); 66 | * 67 | * @b Yields: 68 | * @verbatim 69 | +---------------------------------------------------------------+ 70 | | PREG_CHECK('/The quick brown fox/i' ) | 71 | +---------------------------------------------------------------+ 72 | | 1 | 73 | +---------------------------------------------------------------+ 74 | @endverbatim 75 | * 76 | * SELECT * from patterns WHERE PREG_CHECK( pattern ); 77 | * 78 | * Yields: all of the rows containing valid pcre's. 79 | */ 80 | 81 | 82 | #include "ghmysql.h" 83 | #include "preg.h" 84 | 85 | 86 | 87 | /** 88 | * Public function declarations: 89 | */ 90 | bool preg_check_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 91 | longlong preg_check(UDF_INIT *initid __attribute__((unused)), 92 | UDF_ARGS *args, 93 | char *is_null __attribute__((unused)), 94 | char *error __attribute__((unused))); 95 | void preg_check_deinit( UDF_INIT* initid ); 96 | 97 | 98 | /* 99 | * Public function definitions: 100 | */ 101 | 102 | /** 103 | * @fn bool preg_check_init(UDF_INIT *initid, UDF_ARGS *args, 104 | * char *message) 105 | * 106 | * @brief 107 | * Perform the per-query initializations 108 | * 109 | * @param initid - various info supplied by mysql api - read mode at 110 | * http://dev.mysql.com/doc/refman/5.0/en/adding-udf.html 111 | * 112 | * @param args - array of information about arguments from the SQL call 113 | * See file documentation for the description of the SQL arguments 114 | * 115 | * @param message - for error messages. Should be <80 but can be 255. 116 | * 117 | * @return 0 - on success 118 | * @return 1 - on error 119 | * 120 | * @details This function checks to make sure there is 1 argument. It 121 | * then call pregInit to perform the common initializations. 122 | */ 123 | bool preg_check_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 124 | { 125 | if (args->arg_count != 1) 126 | { 127 | strncpy(message,"preg_check: needs exactly one argument", MYSQL_ERRMSG_SIZE); 128 | return 1; 129 | } 130 | initid->maybe_null=0; 131 | 132 | pregInit( initid , args , message ); 133 | 134 | return 0; 135 | } 136 | 137 | 138 | /** 139 | * @fn longlong preg_check( UDF_INIT *initid , UDF_ARGS *args, char *is_null, 140 | * char *error ) 141 | * 142 | * @brief 143 | * The main routine for the PREG_CHECK udf. 144 | * 145 | * @param initid - various info supplied by mysql api - read more at 146 | * http://dev.mysql.com/doc/refman/5.0/en/adding-udf.html 147 | * 148 | * @param args - array of information about arguments from the SQL call 149 | * See file documentation for the description of the SQL arguments 150 | * 151 | * @param is_null - set this is return value is null 152 | * @param error - to be set if an error occurs 153 | * 154 | * @return 0 - if the given pattern is empty, NULL, or a bad regex. 155 | * @return 1 - if the given pattern is valid. 156 | * 157 | * @details This function calls pcre_ex from the pcre library to execute 158 | * the compiled pattern (which is either precompiled by ..._init 159 | * or compiled here for non-constant pattern arguments). It then 160 | * does the appropriate thing with the returns :>) 161 | */ 162 | longlong preg_check( UDF_INIT *initid , UDF_ARGS *args, char *is_null, 163 | char *error ) 164 | { 165 | char msg [ 255 ] ; 166 | struct preg_s *ptr ; 167 | pcre *re ; /* the compiled regex */ 168 | 169 | 170 | #ifndef GH_1_0_NULL_HANDLING 171 | if( ghargIsNullConstant( args , 0 ) ) 172 | { 173 | *is_null = 1 ; 174 | return NULL ; 175 | } 176 | #endif 177 | 178 | ptr = (struct preg_s *) initid->ptr ; 179 | if( args->args[0] && args->lengths[0] ) 180 | { 181 | re = pregCompileRegexArg( args , msg , sizeof(msg)) ; 182 | if( !re ) 183 | { 184 | return 0; 185 | } 186 | 187 | pcre_free( re ) ; 188 | return 1 ; 189 | } 190 | 191 | return 0 ; 192 | } 193 | 194 | 195 | /** 196 | * @fn void preg_check_deinit(UDF_INIT *initid) 197 | * 198 | * @brief cleanup after PREG_CHECK 199 | * 200 | * @param initid - pointer to struct to be cleaned. 201 | */ 202 | void preg_check_deinit(UDF_INIT *initid) 203 | { 204 | pregDeInit( initid ) ; 205 | } 206 | 207 | 208 | 209 | -------------------------------------------------------------------------------- /lib_mysqludf_preg_info.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2013 Rich Waters 3 | * 4 | * This file is part of lib_mysqludf_preg. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | 26 | /** 27 | * @file lib_mysqludf_preg_info.c 28 | * 29 | * @brief Implements the LIB_MYSQLUDF_INFO mysql udf 30 | */ 31 | 32 | 33 | /** 34 | * @page LIB_MYSQLUDF_PREG_INFO LIB_MYSQLUDF_PREG_INFO 35 | * 36 | * @brief Return version information for lib_mysqludf_preg package 37 | * 38 | * @par Function Installation 39 | * CREATE FUNCTION lib_mysqludf_preg_info RETURNS STRING SONAME 'lib_mysqludf_preg.so' ; 40 | * 41 | * @par Synopsis 42 | * LIB_MYSQLUDF_PREG_INFO() 43 | * 44 | * @return string - version information for the lib_mysqludf_preg package 45 | * 46 | * @par Examples: 47 | * SELECT LIB_MYSQLUDF_PREG_INFO(); 48 | * 49 | * @b Yields: 50 | * @verbatim 51 | +--------------------------+ 52 | | LIB_MYSQLUDF_PREG_INFO() | 53 | +--------------------------+ 54 | | lib_mysqludf_preg 0.6.1 | 55 | +--------------------------+ 56 | @endverbatim 57 | */ 58 | 59 | 60 | #include "ghmysql.h" 61 | //#include "preg.h" 62 | 63 | 64 | /** 65 | * Public function declarations: 66 | */ 67 | bool lib_mysqludf_preg_info_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 68 | char *lib_mysqludf_preg_info(UDF_INIT *initid __attribute__((unused)), 69 | UDF_ARGS *args, 70 | char *result, unsigned long *length, 71 | char *is_null __attribute__((unused)), 72 | char *error __attribute__((unused))); 73 | void lib_mysqludf_info_deinit( UDF_INIT* initid ); 74 | 75 | 76 | /* 77 | * Public function definitions: 78 | */ 79 | 80 | 81 | /** 82 | * @fn bool lib_mysqludf_preg_info_init(UDF_INIT *initid, UDF_ARGS *args, 83 | * char *message) 84 | * 85 | * @brief 86 | * Perform the per-query initializations 87 | * 88 | * @param initid - various info supplied by mysql api - read more at 89 | * http://dev.mysql.com/doc/refman/5.0/en/adding-udf.html 90 | * 91 | * @param args - array of information about arguments from the SQL call 92 | * See file documentation for the description of the SQL arguments 93 | * 94 | * @param message - for error messages. Should be <80 but can be 255. 95 | * 96 | * @return 0 - on success 97 | * @return 1 - on error 98 | * 99 | * @details This function checks to make sure there are no arguments. 100 | */ 101 | bool lib_mysqludf_preg_info_init(UDF_INIT *initid, UDF_ARGS *args, 102 | char *message) 103 | { 104 | if (args->arg_count != 0) 105 | { 106 | strncpy(message, "lib_mysqludf_preg_info: does not accept arguments", MYSQL_ERRMSG_SIZE) ; 107 | return 1; 108 | } 109 | 110 | return 0; 111 | } 112 | 113 | 114 | /** 115 | * @fn char *lib_mysqludf_preg_info( UDF_INIT *initid , UDF_ARGS *args, 116 | * char *result, unsigned long *length, 117 | * char *is_null , char *error ) 118 | * 119 | * @brief 120 | * Get information about the installed lib_mysqludf_preg library 121 | * 122 | * @param initid - various info supplied by mysql api - read more at 123 | * http://dev.mysql.com/doc/refman/5.0/en/adding-udf.html 124 | * 125 | * @param args - array of information about arguments from the SQL call 126 | * See file documentation for the description of the SQL arguments 127 | * 128 | * @param result - a place the captured string can be placed (255 len max) 129 | * @param length - put the length of the captured item here. 130 | * @param is_null - set this if return value is null 131 | * @param error - to be set if an error occurs 132 | * 133 | * @return string - The information requested. 134 | * 135 | * @note: PACKAGE_STRING comes from autotools 136 | */ 137 | char *lib_mysqludf_preg_info( UDF_INIT *initid , UDF_ARGS *args, 138 | char *result, unsigned long *length, 139 | char *is_null , char *error ) 140 | { 141 | strcpy( result , PACKAGE_STRING ); 142 | *length = strlen( result ) ; 143 | *is_null = 0 ; 144 | *error = 0 ; 145 | return result ; 146 | } 147 | 148 | 149 | /** 150 | * @fn void lib_mysqludf_preg_info_deinit(UDF_INIT *initid) 151 | * 152 | * @brief cleanup after LIB_MYSQLUDF_PREG_INFO call 153 | * 154 | * @param initid - pointer to struct to be cleaned. 155 | */ 156 | void lib_mysqludf_preg_info_deinit(UDF_INIT *initid) 157 | { 158 | } 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /lib_mysqludf_preg_position.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2013 Rich Waters 3 | * 4 | * This file is part of lib_mysqludf_preg. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | 26 | /** 27 | * @file lib_mysqludf_preg_position.c 28 | * 29 | * @brief Implements the PREG_POSITION mysql udf 30 | * 31 | */ 32 | 33 | 34 | /** 35 | * @page PREG_POSITION PREG_POSITION 36 | * 37 | * @brief get position of the of a regular expression capture group in a string 38 | * 39 | * @par Function Installation 40 | * CREATE FUNCTION preg_position RETURNS INTEGER SONAME 'lib_mysqludf_preg.so'; 41 | * 42 | * @par Synopsis 43 | * PREG_POSITION( pattern , subject [, group] [, occurence] ) 44 | * 45 | * @par 46 | * @param pattern - is a string that is a perl compatible regular 47 | * expression as documented at: http://us.php.net/manual/en/ref.pcre.php 48 | * This expression passed to this function should have delimiters and 49 | * can contain the standard perl modifiers after the ending delimiter. 50 | * 51 | * @param subject -is the data to perform the match & position capture on 52 | * 53 | * @param group - the capture group whose position that should be 54 | * returned. This can be a numeric capture group or a named capture group. 55 | * Numeric groups should be passed in as integers, while named groups should be 56 | * strings. 0 should be used to request to position of the entire matching 57 | * expression. This parameter defaults to 0. 58 | * 59 | * @param occurence - which match of the regex to perform capture on. 60 | * This is useful for subjects that have multiple matches of the pattern. This 61 | * parameter defaults to 1. 62 | * 63 | * @return - integer position of the string that was captured - 64 | * if there was a match and the desired capture group and occurence is valid 65 | * @return - NULL if pattern does not match the subject or group is not a 66 | * valid capture group or the occurence is larger than the number of 67 | * matches for the given pattern and subject. 68 | * 69 | * @details 70 | * preg_position is a udf that captures the position of matching 71 | * regular expression from a pcre pattern. It can be useful when strings 72 | * need to be split by a pcre pattern or if the location of the pattern 73 | * within the string is needed for some other reason. 74 | * 75 | * @par Examples: 76 | * 77 | * 78 | * SELECT PREG_POSITION('/(.*?)(fox)/' , 'the quick brown fox' ,2 ); 79 | * 80 | * @b Yields: 81 | * @verbatim 82 | +-----------------------------------------------------------+ 83 | | PREG_POSITION('/(.*?)(fox)/' , 'the quick brown fox' ,2 ) | 84 | +-----------------------------------------------------------+ 85 | | 17 | 86 | +-----------------------------------------------------------+ 87 | @endverbatim 88 | * 89 | * SELECT PREG_POSITION('/"[^"]+"/' , '"quick","brown","fox" "jumped"',0,4) 90 | * 91 | * @b Yields: 92 | * @verbatim 93 | +-------------------------------------------------------------------+ 94 | | PREG_POSITION('/"[^"]+"/' , '"quick","brown","fox" "jumped"',0,4) | 95 | +-------------------------------------------------------------------+ 96 | | 23 | 97 | +-------------------------------------------------------------------+ 98 | @endverbatim 99 | * 100 | * @note 101 | * Remember to add a backslash to escape patterns that use \ notation. 102 | * The returned position starts at 1 for the first character, as 103 | * is standard for MySQL string functions. 104 | */ 105 | 106 | #include "ghmysql.h" 107 | #include "preg.h" 108 | 109 | /* 110 | * Public function declarations: 111 | */ 112 | bool preg_position_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 113 | longlong preg_position(UDF_INIT *initid __attribute__((unused)), 114 | UDF_ARGS *args, 115 | char *is_null __attribute__((unused)), 116 | char *error __attribute__((unused))); 117 | void preg_position_deinit( UDF_INIT* initid ); 118 | 119 | 120 | /** 121 | * @fn bool preg_position_init(UDF_INIT *initid, UDF_ARGS *args, 122 | * char *message) 123 | * 124 | * @brief 125 | * Perform the per-query initializations for PREG_POSITION 126 | * 127 | * @param initid - various info supplied by mysql api - read mode at 128 | * http://dev.mysql.com/doc/refman/5.0/en/adding-udf.html 129 | * 130 | * @param args - array of information about arguments from the SQL call 131 | * See file documentation for the description of the SQL arguments 132 | * 133 | * @param message - for error messages. Should be <80 but can be 255. 134 | * 135 | * @return 0 - on success 136 | * @return 1 - on error 137 | * 138 | * @details This function calls pregInit to handle the common init taskes. 139 | * It also checks to make sure there are at least arguments, and checks 140 | * the type of the 'group' and 'occurence' arguments. 141 | */ 142 | bool preg_position_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 143 | { 144 | if (args->arg_count < 2) 145 | { 146 | strncpy(message,"PREG_POSITION: requires at least 2 arguments", MYSQL_ERRMSG_SIZE); 147 | return 1; 148 | } 149 | 150 | // If group isn't an int, then it is a named capture group 151 | if( args->arg_type[2] != INT_RESULT ) 152 | args->arg_type[2] != STRING_RESULT ; 153 | 154 | // occurence must be an int 155 | if( args->arg_count > 3 && args->arg_type[3] != INT_RESULT ) { 156 | strncpy(message,"PREG_POSITION: optional occurence argument must be an integer", MYSQL_ERRMSG_SIZE); 157 | return 1; 158 | } 159 | 160 | // preg_position can return NULL 161 | initid->maybe_null=1; 162 | 163 | return ( pregInit( initid , args , message ) ) ; 164 | } 165 | 166 | 167 | /** 168 | * @fn longlong preg_position( UDF_INIT *initid, UDF_ARGS *args, char *is_null, 169 | * char *error ) 170 | * 171 | * @brief 172 | * The main routine for the PREG_POSITION udf. 173 | * 174 | * @param initid - various info supplied by mysql api - read more at 175 | * http://dev.mysql.com/doc/refman/5.0/en/adding-udf.html 176 | * 177 | * @param args - array of information about arguments from the SQL call 178 | * See file documentation for the description of the SQL arguments 179 | * 180 | * @param is_null - set this if return value is null 181 | * @param error - to be set if an error occurs 182 | * 183 | * @return - the numeric position of the request capture group & occurence 184 | * @return - NULL - if no match or some other problem 185 | * 186 | * @details This function uses the pregSkipToOccurence function to call 187 | * pcre_ex repeatedly until the requested occurence is found. It then 188 | * extracts the string offset for the given capture-group from the 189 | * vector of returned strings and returns this as an sql string 190 | * position (ie. offset+1); 191 | */ 192 | longlong preg_position( UDF_INIT *initid, UDF_ARGS *args, char *is_null, 193 | char *error ) 194 | { 195 | char *ex_subject ; // part of subject after occurence 196 | int groupnum ; /* numeric group - found or from args */ 197 | char msg[255] ; /* to store errors from regex compile */ 198 | int occurence ; /* perform capture on this occurence of match */ 199 | int oveccount ; /* number of items captures */ 200 | int *ovector; /* for offsets of captures */ 201 | struct preg_s *ptr ; /* local holder of initid->ptr */ 202 | int rc ; /* number of regex's matched by pattern */ 203 | pcre *re ; /* the compiled pattern */ 204 | char *subject ; /* args[1] */ 205 | int ret = -1 ; /* position that will be returned */ 206 | 207 | ptr = (struct preg_s *) initid->ptr ; 208 | 209 | *is_null = 1 ; /* default to NULL return */ 210 | *error = 0 ; /* default to no error */ 211 | *ptr->return_buffer = '\0'; /* clear return value */ 212 | 213 | #ifndef GH_1_0_NULL_HANDLING 214 | if( ghargIsNullConstant( args , 0 ) || ghargIsNullConstant( args , 1 ) 215 | || ghargIsNullConstant( args , 2 ) ) 216 | { 217 | *is_null = 1 ; 218 | return NULL ; 219 | } 220 | #endif 221 | 222 | // compile the regex if necessary 223 | if( ptr->constant_pattern ) 224 | re = ptr->re ; 225 | else 226 | { 227 | re = pregCompileRegexArg( args , msg , sizeof(msg)) ; 228 | if( !re ) 229 | { 230 | ghlogprintf( "PREG_POSITION: compile failed: %s\n", msg ); 231 | *error = 1 ; 232 | return -1 ; 233 | } 234 | } 235 | 236 | // create vector to hold offsets for pcre 237 | ovector = pregCreateOffsetsVector( re,NULL, &oveccount ,msg,sizeof(msg)) ; 238 | if( !ovector ) 239 | { 240 | ghlogprintf( "PREG_POSITION: can't create offset vector :%s\n", msg ); 241 | *error = 1 ; 242 | if( !ptr->constant_pattern ) 243 | pcre_free( re ) ; 244 | return -1 ; 245 | } 246 | 247 | if( args->arg_count > 3 ) 248 | occurence = (int)(*(longlong *)args->args[3]) ; 249 | else 250 | occurence = 1 ; 251 | 252 | subject = ghargdup( args , 1 ) ; 253 | if( subject ) 254 | { 255 | ex_subject = pregSkipToOccurence( re , subject , args->lengths[1] , 256 | ovector , oveccount , occurence,&rc); 257 | 258 | groupnum = -1 ; 259 | if( rc > 0 ) 260 | groupnum = pregGetGroupNum( re , args , 2 ) ; 261 | 262 | // If groupnum found, get the offset 263 | if( groupnum >= 0 && groupnum < (oveccount/3) ) 264 | { 265 | // ovec is in pairs of starting and ending offsets. (ie. 266 | // ovec[0] is start of whole match, ovec[1] is end of whole 267 | // match. ovec[2] is start of 1st capture group 268 | groupnum *= 2; 269 | 270 | ret = (long long)ovector[ groupnum ] + (ex_subject - subject) ; 271 | ++ret ; // mysql strings indexes ala substr start at 1 not 0 272 | *is_null = 0 ; 273 | } 274 | } 275 | 276 | free( ovector ) ; 277 | 278 | if( !ptr->constant_pattern ) 279 | pcre_free( re ) ; 280 | 281 | return ret ; 282 | } 283 | 284 | /** 285 | * @fn void preg_position_deinit(UDF_INIT *initid) 286 | * 287 | * @brief cleanup after PREG_POSITION 288 | * 289 | * @param initid - pointer to struct to be cleaned. 290 | */ 291 | void preg_position_deinit(UDF_INIT *initid) 292 | { 293 | pregDeInit(initid); 294 | } 295 | -------------------------------------------------------------------------------- /lib_mysqludf_preg_replace.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2013 Rich Waters 3 | * 4 | * This file is part of lib_mysqludf_preg. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | 26 | /** 27 | * @file lib_mysqludf_preg_replace.c 28 | * 29 | * @brief Implements the PREG_REPLACE mysql udf 30 | * 31 | */ 32 | 33 | 34 | /** 35 | * @page PREG_REPLACE PREG_REPLACE 36 | * 37 | * @brief performs regular expression search & replace using PCRE. 38 | * 39 | * @par Function Installation 40 | * CREATE FUNCTION preg_replace RETURNS STRING SONAME 'lib_mysqludf_preg.so'; 41 | * 42 | * @par Synopsis 43 | * PREG_REPLACE( pattern , replacement , subject [ , limit ] ) 44 | * 45 | * @par 46 | * @param pattern - is a string that is a perl compatible regular 47 | * expression as documented at: 48 | * http://us.php.net/manual/en/ref.pcre.php This expression passed to 49 | * this function should have delimiters and can contain the standard 50 | * perl modifiers after the ending delimiter. 51 | * 52 | * @param replacement - is the string to use as the replacement. This 53 | * string may contain capture group references such as \\1. You can also use 54 | * $1 for these in a similar fashion as in PHP. 55 | * 56 | * @param subject -is the data to perform the match & replace on 57 | * 58 | * @param limit - optional number that is the maximum replacements to 59 | * perform. Use -1 (or leave empty) for no limit. 60 | 61 | * @return - string - 'subject' with the instances of pattern replaced 62 | * @return - string - the same as passed in if there were no matches 63 | * 64 | * @details 65 | * preg_replace is a udf that performs a regular expression search and 66 | * replace on a given piece of data using a PCRE as the replacement 67 | * pattern. If limit is not speficied or is -1, preg_replace works 68 | * on all of the ocurrences of the pattern in the subject data. Otherwise, 69 | * preg_replace will only replace the first occurences. 70 | * 71 | * @par Examples: 72 | * 73 | * SELECT PREG_REPLACE('/(.*?)(fox)/' , '$1dog' , 'the quick brown fox' ); 74 | * 75 | * @b Yields: 76 | * @verbatim 77 | +-----------------------------------------------------------------+ 78 | | PREG_REPLACE('/(.*?)(fox)/' , '$1dog' , 'the quick brown fox' ) | 79 | +-----------------------------------------------------------------+ 80 | | the quick brown dog | 81 | +-----------------------------------------------------------------+ 82 | @endverbatim 83 | * 84 | * 85 | * SELECT PREG_REPLACE('/\\s\\s/+', ' ' , products.title FROM products; 86 | * 87 | * Yields: The product names with all of the extra whitespace removed 88 | * 89 | * @note 90 | * Remember to add a backslash to escape patterns that use \ notation. 91 | * Also, using $ notation makes things a little clearer when using 92 | * backreferences in the replacement. 93 | */ 94 | 95 | 96 | #include "ghmysql.h" 97 | #include "preg.h" 98 | 99 | /* 100 | * Public function declarations: 101 | */ 102 | bool preg_replace_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 103 | char *preg_replace( UDF_INIT *initid __attribute__((unused)), 104 | UDF_ARGS *args, char *result, unsigned long *length, 105 | char *is_null __attribute__((unused)), 106 | char *error __attribute__((unused))); 107 | void preg_replace_deinit( UDF_INIT* initid ); 108 | 109 | 110 | /** 111 | * @fn bool preg_replace_init(UDF_INIT *initid, UDF_ARGS *args, 112 | * char *message) 113 | * 114 | * @brief 115 | * Perform the per-query initializations for PREG_REPLACE 116 | * 117 | * @param initid - various info supplied by mysql api - read mode at 118 | * http://dev.mysql.com/doc/refman/5.0/en/adding-udf.html 119 | * 120 | * @param args - array of information about arguments from the SQL call 121 | * See file documentation for the description of the SQL arguments 122 | * 123 | * @param message - for error messages. Should be <80 but can be up to 124 | * MYSQL_ERRMSG_SIZE. 125 | * 126 | * @return 0 - on success 127 | * @return 1 - on error 128 | * 129 | * @details This function calls pregInit to handle the common init taskes. 130 | * Then it checks to make sure there are 3 arguments. The 4th argument 131 | * must be a number. 132 | */ 133 | bool preg_replace_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 134 | { 135 | if (args->arg_count < 3) 136 | { 137 | strncpy(message,"PREG_REPLACE: requires at least 3 arguments", MYSQL_ERRMSG_SIZE); 138 | return 1; 139 | } 140 | 141 | // Require a numeric 4th argument. (This could possibly be enhanced 142 | // to allow for numeric strings. For now, require an int 143 | if( args->arg_count > 3 && args->arg_type[3] != INT_RESULT ) 144 | { 145 | strncpy(message,"PREG_REPLACE: 4th argument (limit) must be a number", MYSQL_ERRMSG_SIZE); 146 | return 1; 147 | } 148 | 149 | args->arg_type[2] = STRING_RESULT ; // other 2 are set in common init 150 | 151 | // preg_replace cannot return NULL 152 | initid->maybe_null=0; 153 | 154 | // max_length of -1 means no limit ; don't change if that. 155 | // replacement length might be 0 -- also don't change for that 156 | if( ((int)initid->max_length) > 0 && 157 | ((int)args->lengths[1]) > 0 && 158 | ((int)args->lengths[2]) > 0) 159 | { 160 | // it's difficult to know the max_length here due to back references 161 | // and repeating,... Set it to 162 | // subject * the length of the replacement * the length of the 163 | // subject 164 | initid->max_length=args->lengths[1]*args->lengths[2]*args->lengths[1] ; 165 | } 166 | 167 | // Keep this after setting of max_length 168 | if( pregInit( initid , args , message ) ) 169 | { 170 | return 1 ; 171 | } 172 | 173 | return 0; 174 | } 175 | 176 | /** 177 | * @fn char *preg_replace( UDF_INIT *initid , UDF_ARGS *args, char *result, 178 | * unsigned long *length, char *is_null, char *error ) 179 | * 180 | * @brief 181 | * The main routine that implements the PREG_REPLACE function. 182 | * 183 | * @param initid - various info supplied by mysql api - read more at 184 | * http://dev.mysql.com/doc/refman/5.0/en/adding-udf.html 185 | * 186 | * @param args - array of information about arguments from the SQL call 187 | * See file documentation for the description of the SQL arguments 188 | * 189 | * @param result - small place that the modified string can be placed (not used) 190 | * @param length - put the length of the modified string here. 191 | * @param is_null - set this if return value is null (not used) 192 | * @param error - set if an error occurs 193 | * 194 | * @return - string - with the replacements applied if there were any 195 | * 196 | * @details Most of the difficult work here is done by the pregReplace 197 | * functions, which was derived from the php extension and is in the 198 | * from_php.c file. The function below mostly prepares the arguments 199 | * for the call to the pregReplace function and it then calls 200 | * pregMoveToReturnValues to adapt the return from pregReplace to be 201 | * compatible with the MySQL UDF api. 202 | */ 203 | char *preg_replace( UDF_INIT *initid , UDF_ARGS *args, char *result, 204 | unsigned long *length, char *is_null, char *error ) 205 | { 206 | int count ; /* number of matches */ 207 | char msg[255] ; /* to store errors from regex compile */ 208 | struct preg_s *ptr ; /* local holder of initid->ptr */ 209 | pcre *re ; /* the compiled pattern */ 210 | char *subject ; /* args[1] */ 211 | unsigned long subject_len; /* length of subject */ 212 | char *replacement ; /* args[2] */ 213 | unsigned long repl_len ; /* length of replacement */ 214 | char *s ; /* string modified with replacements */ 215 | int s_len ; /* length of modified string */ 216 | int limit ; /* args[3] */ 217 | 218 | ptr = (struct preg_s *) initid->ptr ; 219 | 220 | *is_null = 0 ; 221 | *error = 0 ; /* default to no error */ 222 | 223 | #ifndef GH_1_0_NULL_HANDLING 224 | if( ghargIsNullConstant( args , 2 ) || ghargIsNullConstant( args , 0 ) ) 225 | { 226 | *is_null = 1 ; 227 | return NULL ; 228 | } 229 | #endif 230 | 231 | if( ptr->constant_pattern ) 232 | { 233 | re = ptr->re ; 234 | } 235 | else 236 | { 237 | re = pregCompileRegexArg( args , msg , sizeof(msg)) ; 238 | if( !re ) 239 | { 240 | ghlogprintf( "PREG_REPLACE: compile failed: %s\n", msg ); 241 | *error = 1 ; 242 | return NULL ; 243 | } 244 | } 245 | 246 | int nullReplacement ; 247 | nullReplacement = 0 ; 248 | if( ghargIsNullConstant( args , 1 ) ) 249 | { 250 | nullReplacement = 1 ; 251 | } 252 | 253 | replacement = ghargdups( args , 1 , &repl_len ) ; 254 | if( !replacement ) 255 | { 256 | ghlogprintf( "PREG_REPLACE: out of memory\n" ); 257 | *error = 1 ; 258 | if( !ptr->constant_pattern ) 259 | pcre_free( re ) ; 260 | 261 | return NULL ; 262 | } 263 | 264 | subject = ghargdups( args , 2 , &subject_len ) ; 265 | if( !subject ) 266 | { 267 | ghlogprintf( "PREG_REPLACE: can't allocate for subject\n", msg ); 268 | *error = 1 ; 269 | if( !ptr->constant_pattern ) 270 | pcre_free( re ) ; 271 | free( replacement ); 272 | return NULL ; 273 | } 274 | 275 | if( args->arg_count > 3 ) 276 | { 277 | limit = (int)( *(longlong *)args->args[3]) ; 278 | } 279 | else 280 | { 281 | limit = -1 ; 282 | } 283 | 284 | memset(&msg, 0, sizeof(msg)); 285 | 286 | s = pregReplace( re , NULL , subject, subject_len , replacement , 287 | repl_len , 0 , &s_len , limit , &count , 288 | msg , sizeof(msg) ) ; 289 | 290 | #ifndef GH_1_0_NULL_HANDLING 291 | if( nullReplacement && s && subject && strcmp( s , subject ) ) { 292 | result = NULL ; 293 | *is_null = 1 ; 294 | } 295 | else 296 | #endif 297 | { 298 | if (!s && msg[0] != NULL) { 299 | *error = 1; 300 | ghlogprintf( "PREG_REPLACE: %s\n", msg ); 301 | } 302 | 303 | result = pregMoveToReturnValues( initid ,length,is_null , error,s,s_len ); 304 | } 305 | 306 | free( subject ); 307 | free( replacement ) ; 308 | 309 | if( !ptr->constant_pattern ) 310 | pcre_free( re ) ; 311 | 312 | return result ; 313 | } 314 | 315 | /** 316 | * @fn void preg_replace_deinit(UDF_INIT *initid) 317 | * 318 | * @brief cleanup after PREG_REPLACE 319 | * 320 | * @param initid - pointer to struct to be cleaned. 321 | */ 322 | void preg_replace_deinit(UDF_INIT *initid) 323 | { 324 | pregDeInit(initid); 325 | } 326 | 327 | 328 | -------------------------------------------------------------------------------- /lib_mysqludf_preg_rlike.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2013 Rich Waters 3 | * 4 | * This file is part of lib_mysqludf_preg. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | 26 | /** 27 | * @file lib_mysqludf_preg_rlike.c 28 | * 29 | * @brief Implements the PREG_RLIKE mysql udf 30 | */ 31 | 32 | 33 | /** 34 | * @page PREG_RLIKE PREG_RLIKE 35 | * 36 | * @brief Test if a string matches a perl-compatible regular expression 37 | * 38 | * @par Function Installation 39 | * CREATE FUNCTION preg_rlike RETURNS INTEGER SONAME 'lib_mysqludf_preg.so'; 40 | * 41 | * @par Synopsis 42 | * PREG_RLIKE( pattern , subject ) 43 | * 44 | * @par 45 | * @param pattern - is a string that is a perl compatible regular 46 | * expression as documented at: 47 | * http://us.php.net/manual/en/ref.pcre.php This expression passed to 48 | * this function should have delimiters and can contain the standard 49 | * perl modifiers after the ending delimiter. 50 | * 51 | * @param subject - is the data to perform the test on. 52 | * 53 | * @return 1 - a match was found 54 | * @return 0 - no match 55 | * 56 | * @details 57 | * preg_rlike is a udf that tests if whether or not the given 58 | * perl compatible regular expression matches the given data. 59 | * 60 | * @par Examples: 61 | * 62 | * SELECT PREG_RLIKE('/The quick brown fox/i' , 'the quick brown fox' ); 63 | * 64 | * @b Yields: 65 | * @verbatim 66 | +---------------------------------------------------------------+ 67 | | PREG_RLIKE('/The quick brown fox/i' , 'the quick brown fox' ) | 68 | +---------------------------------------------------------------+ 69 | | 1 | 70 | +---------------------------------------------------------------+ 71 | @endverbatim 72 | * 73 | * SELECT * from products WHERE PREG_RLIKE( '/organic/i' , products.title ) 74 | * 75 | * Yields: all of the products with 'organic' in their titles 76 | */ 77 | 78 | 79 | #include "ghmysql.h" 80 | #include "preg.h" 81 | 82 | // Defines 83 | #define OVECCOUNT 30 // offsets vector size - can be constant since it 84 | // it is not used for capturing 85 | 86 | 87 | /** 88 | * Public function declarations: 89 | */ 90 | bool preg_rlike_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 91 | longlong preg_rlike(UDF_INIT *initid __attribute__((unused)), 92 | UDF_ARGS *args, 93 | char *is_null __attribute__((unused)), 94 | char *error __attribute__((unused))); 95 | void preg_rlike_deinit( UDF_INIT* initid ); 96 | 97 | 98 | /* 99 | * Public function definitions: 100 | */ 101 | 102 | /** 103 | * @fn bool preg_rlike_init(UDF_INIT *initid, UDF_ARGS *args, 104 | * char *message) 105 | * 106 | * @brief 107 | * Perform the per-query initializations 108 | * 109 | * @param initid - various info supplied by mysql api - read mode at 110 | * http://dev.mysql.com/doc/refman/5.0/en/adding-udf.html 111 | * 112 | * @param args - array of information about arguments from the SQL call 113 | * See file documentation for the description of the SQL arguments 114 | * 115 | * @param message - for error messages. Should be <80 but can be 255. 116 | * 117 | * @return 0 - on success 118 | * @return 1 - on error 119 | * 120 | * @details This function checks to make sure there are 2 arguments. It 121 | * then call pregInit to perform the common initializations. 122 | */ 123 | bool preg_rlike_init(UDF_INIT *initid, UDF_ARGS *args, char *message) 124 | { 125 | if (args->arg_count != 2) 126 | { 127 | strcpy(message,"preg_rlike: needs exactly two arguments"); 128 | return 1; 129 | } 130 | initid->maybe_null=0; 131 | 132 | if( pregInit( initid , args , message ) ) 133 | { 134 | return 1 ; 135 | } 136 | 137 | return 0; 138 | } 139 | 140 | 141 | /** 142 | * @fn longlong preg_rlike( UDF_INIT *initid , UDF_ARGS *args, char *is_null, 143 | * char *error ) 144 | * 145 | * @brief 146 | * The main routine for the PREG_RLIKE udf. 147 | * 148 | * @param initid - various info supplied by mysql api - read more at 149 | * http://dev.mysql.com/doc/refman/5.0/en/adding-udf.html 150 | * 151 | * @param args - array of information about arguments from the SQL call 152 | * See file documentation for the description of the SQL arguments 153 | * 154 | * @param is_null - set this is return value is null 155 | * @param error - to be set if an error occurs 156 | * 157 | * @return 0 - if the subject does not match the given pattern 158 | * @return 1 - if the subject matches the given pattern 159 | * 160 | * @details This function calls pcre_ex from the pcre library to execute 161 | * the compiled pattern (which is either precompiled by ..._init 162 | * or compiled here for non-constant pattern arguments). It then 163 | * does the appropriate thing with the returns :>) 164 | */ 165 | longlong preg_rlike( UDF_INIT *initid , UDF_ARGS *args, char *is_null, 166 | char *error ) 167 | { 168 | struct preg_s *ptr ; 169 | char msg [ 255 ] ; 170 | int ovector[OVECCOUNT]; /* for use by pcre_exex */ 171 | int rc ; 172 | pcre *re ; /* the compiled regex */ 173 | pcre_extra extra; 174 | 175 | #ifndef GH_1_0_NULL_HANDLING 176 | if( ghargIsNullConstant( args , 0 ) || ghargIsNullConstant( args , 1 ) ) 177 | { 178 | *is_null = 1 ; 179 | return NULL ; 180 | } 181 | #endif 182 | 183 | 184 | ptr = (struct preg_s *) initid->ptr ; 185 | // Need to leave out the length check here because some patterns can return true against an empty string 186 | if( args->args[1] /*&& args->lengths[1]*/ ) 187 | { 188 | if( ptr->constant_pattern ) 189 | { 190 | re = ptr->re ; 191 | } 192 | else 193 | { 194 | re = pregCompileRegexArg( args , msg , sizeof(msg)) ; 195 | if( !re ) 196 | { 197 | fprintf( stderr,"preg: compile failed: %s\n",msg); 198 | *error = 1 ; 199 | return 0; 200 | } 201 | } 202 | 203 | memset(&extra, 0, sizeof(extra)); 204 | pregSetLimits(&extra); 205 | 206 | rc = pcre_exec(re, &extra, args->args[1] , (int)args->lengths[1], 207 | 0,0,ovector, OVECCOUNT); 208 | 209 | if( !ptr->constant_pattern ) 210 | { 211 | pcre_free( re ) ; 212 | } 213 | 214 | if( rc > 0 ) 215 | { 216 | return 1 ; 217 | } 218 | } 219 | 220 | return 0 ; 221 | } 222 | 223 | 224 | /** 225 | * @fn void preg_rlike_deinit(UDF_INIT *initid) 226 | * 227 | * @brief cleanup after PREG_RLIKE 228 | * 229 | * @param initid - pointer to struct to be cleaned. 230 | */ 231 | void preg_rlike_deinit(UDF_INIT *initid) 232 | { 233 | pregDeInit( initid ) ; 234 | } 235 | 236 | 237 | 238 | -------------------------------------------------------------------------------- /preg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2013 Rich Waters 3 | * 4 | * This file is part of lib_mysqludf_preg. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #ifndef PREG_H 26 | #define PREG_H 27 | 28 | 29 | /** @file preg.h 30 | * 31 | * @brief headers for preg functions 32 | */ 33 | 34 | 35 | // Include the libpcre headers 36 | #include 37 | #include "from_php.h" 38 | 39 | /* 40 | * PCRE Structures: 41 | */ 42 | struct preg_s { 43 | pcre *re ; /* the compiled regex */ 44 | int constant_pattern ; /* is the pattern argument constant? */ 45 | char *return_buffer ; /* alloc'd memory for returning strings */ 46 | unsigned long return_buffer_size ; 47 | }; 48 | 49 | /* 50 | * lib_mysqludf_preg utility functions: 51 | */ 52 | 53 | // from_php.c 54 | //pcre *compileRegex( char *regex , int regex_len , char *msg , int msglen ) ; 55 | 56 | /* 57 | char *pregReplace(pcre *re , pcre_extra *extra , 58 | char *subject, int subject_len, char *replace, 59 | int replace_len , 60 | int is_callable_replace, int *result_len, int limit, 61 | int *replace_count, char *msg , int msglen ); 62 | */ 63 | // preg.c 64 | void destroyPtrInfo( struct preg_s *ghptr ); 65 | int initPtrInfo( struct preg_s *ghptr , UDF_ARGS *args,char*msg ); 66 | bool pregInit(UDF_INIT *initid, UDF_ARGS *args, char *message); 67 | pcre *pregCompileRegexArg( UDF_ARGS *args , char *msg , int msglen ) ; 68 | int pregCopyToReturnBuffer( struct preg_s *ptr , char *s , int l ); 69 | void pregDeInit(UDF_INIT *initid) ; 70 | 71 | int *pregCreateOffsetsVector( pcre *re , pcre_extra *extra , int *count , 72 | char *msg , int msglen ); 73 | 74 | char *pregMoveToReturnValues( UDF_INIT *initid , 75 | unsigned long *length , 76 | char *is_null , char *error , 77 | char *s , int s_len ) ; 78 | int pregGetGroupNum( pcre *re , UDF_ARGS *args , int argnum ); 79 | 80 | char *pregSkipToOccurence( pcre *re , char *subject , int subject_len , 81 | int *ovector , int oveccount , int occurence, 82 | int *rc); 83 | void pregSetLimits(pcre_extra *extra); 84 | const char *pregExecErrorString(int errno); 85 | 86 | 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /preg_utils.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2013 Rich Waters 3 | * 4 | * This file is part of lib_mysqludf_preg. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | 26 | /** @file pregUtils.c 27 | * 28 | * @brief Provides some functions for interfacing with pcre that are independent 29 | * of mysql. 30 | * 31 | * @notes Be sure to #define GH_PREG_NO_MYSQL if used 32 | * without mysql 33 | */ 34 | 35 | #include 36 | 37 | #include "preg_utils.h" 38 | #include "ghfcns.h" 39 | 40 | #ifndef GH_PREG_NO_MYSQL 41 | #include "config.h" 42 | #endif 43 | 44 | /** 45 | * @fn void pregSetLimits( pcre_extra *extra ) 46 | * 47 | * @brief 48 | * sets safe match/recursion limits in a pcre extra 49 | * that should be low enough to prevent stack overflow 50 | * crashes. 51 | * 52 | * @param extra - a pointer to the pcre_extra struct to set 53 | * 54 | * @details This function sets safe limits as determined by 55 | * calculating the currently available stack space for the 56 | * this thread, it will also set the flags required to make 57 | * pcre_exec honour the limits 58 | * 59 | */ 60 | void pregSetLimits(pcre_extra *extra) 61 | { 62 | /* 63 | * A match_limit_recursion of 100000 is way too high for this context 64 | * MySQL's default thread stack size is 256K on 64bit (192K on 32bit) 65 | * - https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_thread_stack 66 | * man pcrestack(3) suggests a rule of thumb of 500 bytes per recursion. Assuming _no_ other 67 | * stack usage that suggests a maximum safe limit of ~512 (64-bit) or ~384 (32-bit) 68 | * but better - get the stack size & usage and base the limit on the *available* stack space 69 | * if deeper recusrsion is needed then users can increase MySQL's thread_stack variable to 70 | * raise the limit 71 | * - Travers Carter 72 | */ 73 | 74 | size_t thread_stack_size=0; 75 | size_t thread_stack_avail=0; 76 | size_t pcre_frame_size=0; 77 | 78 | #ifdef HAVE_PTHREAD 79 | #ifdef HAVE_PTHREAD_GETATTR_NP 80 | 81 | pthread_attr_t thread_attr; 82 | void * thread_stack_addr=0; 83 | void * thread_stack_cur = alloca(1); // End of the stack (hopefully....) 84 | void * thread_stack_next = alloca(1); // For direction.... 85 | 86 | // Find the current thread's stack information 87 | if (pthread_getattr_np(pthread_self(), &thread_attr) == 0) { 88 | if (pthread_attr_getstack(&thread_attr, &thread_stack_addr, &thread_stack_size) == 0) { 89 | // NB: thread_stack_addr is always the _lowest_ addres redgardless of the direction of 90 | // of growth (man pthread_attr_getstackaddr(3)) 91 | if (thread_stack_cur > thread_stack_next) { 92 | // Stack grows downwards.... 93 | thread_stack_avail = thread_stack_cur - thread_stack_addr; 94 | } else { 95 | thread_stack_avail = thread_stack_size - (thread_stack_cur - thread_stack_addr); 96 | } 97 | } 98 | pthread_attr_destroy(&thread_attr); 99 | } 100 | 101 | #else 102 | #ifdef HAVE_PTHREAD_GET_STACKSIZE_NP 103 | // TODO: Figure this out and get thread_stack_avail properly set for OSX. 104 | #endif 105 | #endif 106 | 107 | 108 | #ifdef GH_PREG_NO_MYSQL 109 | if( !thread_stack_avail ) { 110 | // Cannot get information from current thread; Use default thread information, since compiling for use outside of mysqld 111 | 112 | pthread_attr_t thread_attr; 113 | 114 | // Not possible to get values from current thread. Instead, extract default stacksize 115 | if( !pthread_attr_init( &thread_attr ) ) { 116 | if( !pthread_attr_getstacksize(&thread_attr , &thread_stack_size ) ) { 117 | thread_stack_avail = thread_stack_size*0.75; // assume a current usage of 25% (_wild_ guess!) 118 | } 119 | } 120 | } 121 | #endif 122 | #endif 123 | 124 | 125 | if (thread_stack_avail == 0) 126 | { 127 | // Cannot get stacksize using normal means 128 | // Use information from mysqld global variable, if compiling for mysql 129 | // 130 | #ifndef GH_PREG_NO_MYSQL 131 | extern unsigned long my_thread_stack_size; 132 | thread_stack_size = my_thread_stack_size ; 133 | #endif 134 | 135 | if( !thread_stack_size ) { 136 | // Checks failed, assume the MySQL defaults (64/32 bit) 137 | // Shouldn't ever really get here, though. 138 | ghlogprintf( "Ignoring mysqld:thread_stack. Using mysql defaults.\n") ; 139 | #ifdef _LP64 140 | thread_stack_size = 256*1024; 141 | #else 142 | thread_stack_size = 192*1024; 143 | #endif 144 | } 145 | // And assume a current usage of 25% (_wild_ guess!) 146 | thread_stack_avail = thread_stack_size*0.75; 147 | } 148 | 149 | 150 | // PCRE >= 8.30 has a magic call preg_exec(NULL, NULL, NULL, -1, ....) to determine the stack requirements 151 | // (returned as a negative number), but errors are also negative (currently down to -25) 152 | if ((pcre_frame_size = pcre_exec(NULL, NULL, NULL, -1, 0, 0, NULL, 0)) < -50) { 153 | pcre_frame_size = -pcre_frame_size; 154 | } else { 155 | #ifdef _LP64 156 | // 500 bytes (from pcrestack(3)) is too low, at least on x86_64 157 | pcre_frame_size = 1000; 158 | #else 159 | pcre_frame_size = 500; 160 | #endif 161 | } 162 | 163 | // TODO: Fix (or justify?) the 100,000 magic number here (taken from "from_php.c" but pcre defaults to 10,000,000! 164 | extra->match_limit = 100000; 165 | extra->match_limit_recursion = (thread_stack_avail-4096)/pcre_frame_size; 166 | 167 | // Force the limits to be honoured.... 168 | extra->flags |= PCRE_EXTRA_MATCH_LIMIT | PCRE_EXTRA_MATCH_LIMIT_RECURSION; 169 | } 170 | 171 | static const char *_pregExecErrorString[] = { 172 | "NO_ERROR", 173 | "PCRE_ERROR_NOMATCH", 174 | "PCRE_ERROR_NULL", 175 | "PCRE_ERROR_BADOPTION", 176 | "PCRE_ERROR_BADMAGIC", 177 | "PCRE_ERROR_UNKNOWN_OPCODE", 178 | "PCRE_ERROR_NOMEMORY", 179 | "PCRE_ERROR_NOSUBSTRING", 180 | "PCRE_ERROR_MATCHLIMIT", 181 | "PCRE_ERROR_CALLOUT", 182 | "PCRE_ERROR_BADUTF8", 183 | "PCRE_ERROR_BADUTF8_OFFSET", 184 | "PCRE_ERROR_PARTIAL", 185 | "PCRE_ERROR_BADPARTIAL", 186 | "PCRE_ERROR_INTERNAL", 187 | "PCRE_ERROR_BADCOUNT", 188 | "PCRE_ERROR_DFA_UITEM", 189 | "PCRE_ERROR_DFA_UCOND", 190 | "PCRE_ERROR_DFA_UMLIMIT", 191 | "PCRE_ERROR_DFA_WSSIZE", 192 | "PCRE_ERROR_DFA_RECURSE", 193 | "PCRE_ERROR_RECURSIONLIMIT, try increasing mysqld:thread_stack", 194 | "PCRE_ERROR_NULLWSLIMIT", 195 | "PCRE_ERROR_BADNEWLINE", 196 | "PCRE_ERROR_BADOFFSET", 197 | "PCRE_ERROR_SHORTUTF8", 198 | "UNKOWN_ERROR", 199 | }; 200 | 201 | /** 202 | * @fn const char *pregExecErrorString( int pcre_errno ) 203 | * 204 | * @brief 205 | * returns a pointer to string containing the sylbolic 206 | * name of the pcre error specified by pcre_errno 207 | * 208 | * @param pcre_errno - an error number returned by pcre_exec() 209 | * 210 | * @details This function return a pointer to a NULL terminated 211 | * string containing the symbolic name of a give pcre error. 212 | * The returned strings are static and the caller should not 213 | * attempt to either manipulate or free them. 214 | * 215 | */ 216 | const char *pregExecErrorString(int pcre_errno) { 217 | if (pcre_errno >= 0) { 218 | return _pregExecErrorString[0]; 219 | } else if (pcre_errno >= -25) { 220 | return _pregExecErrorString[-pcre_errno]; 221 | } else { 222 | return _pregExecErrorString[26]; 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /preg_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2013 Rich Waters 3 | * 4 | * This file is part of lib_mysqludf_preg. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #ifndef PREGUTILS_H 26 | 27 | #define PREGUTILS_H 28 | 29 | // Include the libpcre headers 30 | #include "pcre.h" 31 | //#include "from_php.h" 32 | 33 | void pregSetLimits(pcre_extra *extra); 34 | const char *pregExecErrorString(int pcre_errno); 35 | 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /test/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Force test to be a target instead of shell-builtin 4 | .PHONY : test 5 | 6 | # clean up these files too during make clean 7 | CLEANFILES=*.log *.reject 8 | 9 | # Include these extensions in dist 10 | EXTRA_DIST = *.test *.result *.sql *.txt 11 | 12 | #Get filenames from OS 13 | PREG_TESTS=$(wildcard *.test) 14 | 15 | MYSQLTEST_ARGS= --include=create_testdb.sql --result-file=$*.result 16 | 17 | ############################ 18 | 19 | mysqltest: 20 | @if test -z "$(MYSQLTEST)" ; then echo "mysqltest not found"; exit 1; fi 21 | 22 | %.result : %.test 23 | $(MYSQLTEST) $(MYSQLTEST_ARGS) --record < $*.test 24 | 25 | %.run : %.test 26 | $(MYSQLTEST) $(MYSQLTEST_ARGS) < $*.test 27 | 28 | results : mysqltest $(PREG_TESTS:%.test=%.result) 29 | 30 | test: mysqltest $(PREG_TESTS:%.test=%.run) 31 | 32 | -------------------------------------------------------------------------------- /test/ManualTests.txt: -------------------------------------------------------------------------------- 1 | #### 2 | # This query can exceed the default stack limitations of the mysqld 3 | # and requires that the thread_stack variable be set to 1M. This is left 4 | # out of the automated tests so they don't fail when that variable is not 5 | # big enough, but this query should be run by hand both with and without that 6 | # variable set. 7 | # 8 | # When it is NOT set, the mysqld should NOT crash. It should, however, 9 | # log an error message informing the user of the 'thread_stack' variable. 10 | # It will return NULL in that case. When the variable is big enough, this 11 | # will return a blank space. 12 | # 13 | SELECT preg_replace('/ \(([A-Z]{2}(, )?)*\)$/',' ','Product (AE, AR, AU, BD, BE, BF, BH, BJ, BO, BR, CI, CL, CN, CO, CR, CY, DO, EC, EE, EG, ET, FI, GB, GH, GM, GN, GR, GT, HK, HN, ID, IE, IL, IQ, IR, JO, JP, KE, KP, KW, LB, LR, LY, MA, ML, MR, MU, MW, MX, MY, NE, NG, NI, NL, NO, NZ, OM, PA, PE, PH, PK, PR, QA, SA, SC, SD, SE)',1); 14 | 15 | -------------------------------------------------------------------------------- /test/create_testdb.sql: -------------------------------------------------------------------------------- 1 | 2 | Use mysql; 3 | 4 | 5 | ###################################################################### 6 | # Taken from libmysql_udf_xql 7 | ################################################################### 8 | 9 | --disable_warnings 10 | DROP DATABASE IF EXISTS `preg_test`; 11 | --enable_warnings 12 | 13 | CREATE DATABASE `preg_test`; 14 | USE `preg_test`; 15 | 16 | CREATE TABLE `state` ( 17 | `code` varchar(2) NOT NULL, 18 | `country_code` varchar(2) NOT NULL, 19 | `description` varchar(255) NOT NULL, 20 | `regex` varchar(255) , 21 | PRIMARY KEY (`code`) 22 | ) ENGINE=HEAP DEFAULT CHARSET=latin1; 23 | 24 | INSERT INTO `state`(code,country_code,description) VALUES ('al','us','Alabama'),('ak','us','Alaska'),('as','us','American Samoa'),('az','us','Arizona'),('ar','us','Arkansas'),('ca','us','California'),('co','us','Colorado'),('ct','us','Connecticut'),('de','us','Delaware'),('dc','us','District of Columbia'),('fm','us','Federated States of Micronesia'),('fl','us','Florida'),('ga','us','Georgia'),('gu','us','Guam'),('hi','us','Hawaii'),('id','us','Idaho'),('il','us','Illinois'),('in','us','Indiana'),('ia','us','Iowa'),('ks','us','Kansas'),('ky','us','Kentucky'),('la','us','Louisiana'),('me','us','Maine'),('mh','us','Marshall Islands'),('md','us','Maryland'),('ma','us','Massachusetts'),('mi','us','Michigan'),('mn','us','Minnesota'),('ms','us','Mississippi'),('mo','us','Missouri'),('mt','us','Montana'),('ne','us','Nebraska'),('nv','us','Nevada'),('nh','us','New Hampshire'),('nj','us','New Jersey'),('nm','us','New Mexico'),('ny','us','New York'),('nc','us','North Carolina'),('nd','us','North Dakota'),('mp','us','Northern Mariana Islands'),('oh','us','Ohio'),('ok','us','Oklahoma'),('or','us','Oregon'),('pw','us','Palau'),('pa','us','Pennsylvania'),('pr','us','Puerto Rico'),('ri','us','Rhode Island'),('sc','us','South Carolina'),('sd','us','South Dakota'),('tn','us','Tennessee'),('tx','us','Texas'),('ut','us','Utah'),('vt','us','Vermont'),('vi','us','Virgin Island'),('va','us','Virginia'),('wa','us','Washington'),('wv','us','West Virginia'),('wi','us','Wisconsin'),('wy','us','Wyoming'),('ab','ca','Alberta'),('bc','ca','British Columbia'),('mb','ca','Manitoba'),('nb','ca','New Brunswick'),('nf','ca','New Foundland'),('nt','ca','Northwest Territories'),('ns','ca','Nova Scotia'),('on','ca','Ontario'),('pe','ca','Prince Edward Island'),('pq','ca','Quebec'),('sk','ca','Saskatchewan'),('yt','ca','Yukon Territories'); 25 | 26 | UPDATE state SET regex=CONCAT('/(',code,')/i'); 27 | -------------------------------------------------------------------------------- /test/lib_mysqludf_preg_capture.result: -------------------------------------------------------------------------------- 1 | Use mysql; 2 | DROP DATABASE IF EXISTS `preg_test`; 3 | CREATE DATABASE `preg_test`; 4 | USE `preg_test`; 5 | CREATE TABLE `state` ( 6 | `code` varchar(2) NOT NULL, 7 | `country_code` varchar(2) NOT NULL, 8 | `description` varchar(255) NOT NULL, 9 | `regex` varchar(255) , 10 | PRIMARY KEY (`code`) 11 | ) ENGINE=HEAP DEFAULT CHARSET=latin1; 12 | INSERT INTO `state`(code,country_code,description) VALUES ('al','us','Alabama'),('ak','us','Alaska'),('as','us','American Samoa'),('az','us','Arizona'),('ar','us','Arkansas'),('ca','us','California'),('co','us','Colorado'),('ct','us','Connecticut'),('de','us','Delaware'),('dc','us','District of Columbia'),('fm','us','Federated States of Micronesia'),('fl','us','Florida'),('ga','us','Georgia'),('gu','us','Guam'),('hi','us','Hawaii'),('id','us','Idaho'),('il','us','Illinois'),('in','us','Indiana'),('ia','us','Iowa'),('ks','us','Kansas'),('ky','us','Kentucky'),('la','us','Louisiana'),('me','us','Maine'),('mh','us','Marshall Islands'),('md','us','Maryland'),('ma','us','Massachusetts'),('mi','us','Michigan'),('mn','us','Minnesota'),('ms','us','Mississippi'),('mo','us','Missouri'),('mt','us','Montana'),('ne','us','Nebraska'),('nv','us','Nevada'),('nh','us','New Hampshire'),('nj','us','New Jersey'),('nm','us','New Mexico'),('ny','us','New York'),('nc','us','North Carolina'),('nd','us','North Dakota'),('mp','us','Northern Mariana Islands'),('oh','us','Ohio'),('ok','us','Oklahoma'),('or','us','Oregon'),('pw','us','Palau'),('pa','us','Pennsylvania'),('pr','us','Puerto Rico'),('ri','us','Rhode Island'),('sc','us','South Carolina'),('sd','us','South Dakota'),('tn','us','Tennessee'),('tx','us','Texas'),('ut','us','Utah'),('vt','us','Vermont'),('vi','us','Virgin Island'),('va','us','Virginia'),('wa','us','Washington'),('wv','us','West Virginia'),('wi','us','Wisconsin'),('wy','us','Wyoming'),('ab','ca','Alberta'),('bc','ca','British Columbia'),('mb','ca','Manitoba'),('nb','ca','New Brunswick'),('nf','ca','New Foundland'),('nt','ca','Northwest Territories'),('ns','ca','Nova Scotia'),('on','ca','Ontario'),('pe','ca','Prince Edward Island'),('pq','ca','Quebec'),('sk','ca','Saskatchewan'),('yt','ca','Yukon Territories'); 13 | UPDATE state SET regex=CONCAT('/(',code,')/i'); 14 | SELECT PREG_CAPTURE( '/(x)(?:(abc)|(xyz))(x)/' , 'xabcx' , 2 ) ; 15 | PREG_CAPTURE( '/(x)(?:(abc)|(xyz))(x)/' , 'xabcx' , 2 ) 16 | abc 17 | SELECT PREG_CAPTURE('/(.*?)(fox)/' , 'the quick brown fox' ,2 ); 18 | PREG_CAPTURE('/(.*?)(fox)/' , 'the quick brown fox' ,2 ) 19 | fox 20 | SELECT PREG_CAPTURE( '/(new)\\s+([a-zA-Z]*)(.*)/i' , description, 2 ) FROM state WHERE description LIKE 'new%' ; 21 | PREG_CAPTURE( '/(new)\\s+([a-zA-Z]*)(.*)/i' , description, 2 ) 22 | Hampshire 23 | Jersey 24 | Mexico 25 | York 26 | Brunswick 27 | Foundland 28 | SELECT PREG_CAPTURE( '/(new)\\s+(?P[^\\s]*)(.*)/i' , description, 'word' ) FROM state WHERE PREG_RLIKE( '/new/i' , description ); 29 | PREG_CAPTURE( '/(new)\\s+(?P[^\\s]*)(.*)/i' , description, 'word' ) 30 | Hampshire 31 | Jersey 32 | Mexico 33 | York 34 | Brunswick 35 | Foundland 36 | SELECT PREG_CAPTURE( '/"([^"]+)"/' , 'the "quick" brown fox "jumped" over the "lazy" dog' , 1,2 ); 37 | PREG_CAPTURE( '/"([^"]+)"/' , 'the "quick" brown fox "jumped" over the "lazy" dog' , 1,2 ) 38 | jumped 39 | select preg_capture( '/./' , repeat( 'da' , 500000 ) , 0 ,210001 ); 40 | preg_capture( '/./' , repeat( 'da' , 500000 ) , 0 ,210001 ) 41 | d 42 | SELECT PREG_CAPTURE( '/b[^\\s]*/' , 'the quick brown fox jumped up & down' ); 43 | PREG_CAPTURE( '/b[^\\s]*/' , 'the quick brown fox jumped up & down' ) 44 | brown 45 | SELECT PREG_CAPTURE( '/b[^\\s]*/' , 'the quick brown fox jumped up & down',0,4); 46 | PREG_CAPTURE( '/b[^\\s]*/' , 'the quick brown fox jumped up & down',0,4) 47 | NULL 48 | SELECT PREG_CAPTURE( '/b[^\\s]*/' , 'the quick brown fox jumped up & down',4); 49 | PREG_CAPTURE( '/b[^\\s]*/' , 'the quick brown fox jumped up & down',4) 50 | NULL 51 | SELECT PREG_CAPTURE('/ ([A-Za-z]+) /', '13 robin road', 1, 1); 52 | PREG_CAPTURE('/ ([A-Za-z]+) /', '13 robin road', 1, 1) 53 | robin 54 | SELECT PREG_CAPTURE('/([A-Za-z]+)/', '13 robin road', 1, 2); 55 | PREG_CAPTURE('/([A-Za-z]+)/', '13 robin road', 1, 2) 56 | road 57 | SELECT PREG_CAPTURE('/([A-Za-z]+)/', '13 robin road', 1, 3); 58 | PREG_CAPTURE('/([A-Za-z]+)/', '13 robin road', 1, 3) 59 | NULL 60 | SELECT PREG_CAPTURE('/([A-Za-z]+)/', '13 robin road', 1, 4); 61 | PREG_CAPTURE('/([A-Za-z]+)/', '13 robin road', 1, 4) 62 | NULL 63 | DROP TABLE IF EXISTS `patterns`; 64 | CREATE TABLE `patterns` ( 65 | `pattern` varchar(255) NOT NULL, 66 | `groupnum` int NOT NULL , 67 | `groupname` varchar(255) NOT NULL, 68 | `occurence` int NOT NULL 69 | ) ENGINE=HEAP DEFAULT CHARSET=latin1; 70 | INSERT INTO `patterns` VALUES 71 | ('/new/i',0,'',1), 72 | ('/(new)(\\s)([a-zA-Z0-9]+)(.*)/i',3,'',1), 73 | ('/(new)(\\s)(?P[a-zA-Z0-9]+)(.*)/i',0,'thing',1) ; 74 | SELECT DISTINCT PREG_CAPTURE( pattern,description,groupnum,occurence) AS w FROM state, patterns WHERE PREG_RLIKE( pattern, description ) AND groupname='' HAVING w IS NOT NULL ORDER BY w; 75 | w 76 | Brunswick 77 | Foundland 78 | Hampshire 79 | Jersey 80 | Mexico 81 | New 82 | York 83 | DROP DATABASE IF EXISTS `preg_test`; 84 | -------------------------------------------------------------------------------- /test/lib_mysqludf_preg_capture.test: -------------------------------------------------------------------------------- 1 | ############################## 2 | # 3 | # @file lib_mysqludf_preg_capture.test 4 | # 5 | # This is a file that can be run through mysqltest in order to perform some 6 | # basic for the libmysql_udf_preg_capture UDF. This should 7 | # usually be invoked through the 'make test' command in ../Makefile. 8 | # To record new test results, use: make lib_mysqludf_preg_capture.result 9 | # 10 | ############################# 11 | 12 | #################################################### 13 | # From mysql function.tst & converted 14 | 15 | #****************** ****** 16 | # This one has some problems on debian sid -- Investigate 17 | #SELECT PREG_CAPTURE( '/(x)(?|(abc)|(xyz))(x)/' , 'xabcx' , 2 ) ; 18 | # 19 | SELECT PREG_CAPTURE( '/(x)(?:(abc)|(xyz))(x)/' , 'xabcx' , 2 ) ; 20 | #################################################### 21 | 22 | 23 | 24 | #################################################### 25 | #### Here are some others 26 | 27 | #capture the fox 28 | SELECT PREG_CAPTURE('/(.*?)(fox)/' , 'the quick brown fox' ,2 ); 29 | 30 | #### Capture word after new in state 31 | SELECT PREG_CAPTURE( '/(new)\\s+([a-zA-Z]*)(.*)/i' , description, 2 ) FROM state WHERE description LIKE 'new%' ; 32 | 33 | #### Same thing with a named group 34 | SELECT PREG_CAPTURE( '/(new)\\s+(?P[^\\s]*)(.*)/i' , description, 'word' ) FROM state WHERE PREG_RLIKE( '/new/i' , description ); 35 | 36 | 37 | #### Use occurence arg to get 2nd quoted word ######## 38 | SELECT PREG_CAPTURE( '/"([^"]+)"/' , 'the "quick" brown fox "jumped" over the "lazy" dog' , 1,2 ); 39 | 40 | #### test long strings and occurence 41 | select preg_capture( '/./' , repeat( 'da' , 500000 ) , 0 ,210001 ); 42 | 43 | #### simple case -- capture first word starting with b 44 | SELECT PREG_CAPTURE( '/b[^\\s]*/' , 'the quick brown fox jumped up & down' ); 45 | 46 | #### out of bounds 47 | SELECT PREG_CAPTURE( '/b[^\\s]*/' , 'the quick brown fox jumped up & down',0,4); 48 | SELECT PREG_CAPTURE( '/b[^\\s]*/' , 'the quick brown fox jumped up & down',4); 49 | 50 | #### Occurence out of boungs (Bug #12) 51 | SELECT PREG_CAPTURE('/ ([A-Za-z]+) /', '13 robin road', 1, 1); 52 | SELECT PREG_CAPTURE('/([A-Za-z]+)/', '13 robin road', 1, 2); 53 | SELECT PREG_CAPTURE('/([A-Za-z]+)/', '13 robin road', 1, 3); 54 | SELECT PREG_CAPTURE('/([A-Za-z]+)/', '13 robin road', 1, 4); 55 | 56 | 57 | ######### try some none-constant patterns & replacements 58 | # 59 | 60 | --disable_warnings 61 | DROP TABLE IF EXISTS `patterns`; 62 | --enable_warnings 63 | 64 | CREATE TABLE `patterns` ( 65 | `pattern` varchar(255) NOT NULL, 66 | `groupnum` int NOT NULL , 67 | `groupname` varchar(255) NOT NULL, 68 | `occurence` int NOT NULL 69 | ) ENGINE=HEAP DEFAULT CHARSET=latin1; 70 | INSERT INTO `patterns` VALUES 71 | ('/new/i',0,'',1), 72 | ('/(new)(\\s)([a-zA-Z0-9]+)(.*)/i',3,'',1), 73 | ('/(new)(\\s)(?P[a-zA-Z0-9]+)(.*)/i',0,'thing',1) ; 74 | 75 | SELECT DISTINCT PREG_CAPTURE( pattern,description,groupnum,occurence) AS w FROM state, patterns WHERE PREG_RLIKE( pattern, description ) AND groupname='' HAVING w IS NOT NULL ORDER BY w; 76 | 77 | DROP DATABASE IF EXISTS `preg_test`; 78 | 79 | -------------------------------------------------------------------------------- /test/lib_mysqludf_preg_check.result: -------------------------------------------------------------------------------- 1 | Use mysql; 2 | DROP DATABASE IF EXISTS `preg_test`; 3 | CREATE DATABASE `preg_test`; 4 | USE `preg_test`; 5 | CREATE TABLE `state` ( 6 | `code` varchar(2) NOT NULL, 7 | `country_code` varchar(2) NOT NULL, 8 | `description` varchar(255) NOT NULL, 9 | `regex` varchar(255) , 10 | PRIMARY KEY (`code`) 11 | ) ENGINE=HEAP DEFAULT CHARSET=latin1; 12 | INSERT INTO `state`(code,country_code,description) VALUES ('al','us','Alabama'),('ak','us','Alaska'),('as','us','American Samoa'),('az','us','Arizona'),('ar','us','Arkansas'),('ca','us','California'),('co','us','Colorado'),('ct','us','Connecticut'),('de','us','Delaware'),('dc','us','District of Columbia'),('fm','us','Federated States of Micronesia'),('fl','us','Florida'),('ga','us','Georgia'),('gu','us','Guam'),('hi','us','Hawaii'),('id','us','Idaho'),('il','us','Illinois'),('in','us','Indiana'),('ia','us','Iowa'),('ks','us','Kansas'),('ky','us','Kentucky'),('la','us','Louisiana'),('me','us','Maine'),('mh','us','Marshall Islands'),('md','us','Maryland'),('ma','us','Massachusetts'),('mi','us','Michigan'),('mn','us','Minnesota'),('ms','us','Mississippi'),('mo','us','Missouri'),('mt','us','Montana'),('ne','us','Nebraska'),('nv','us','Nevada'),('nh','us','New Hampshire'),('nj','us','New Jersey'),('nm','us','New Mexico'),('ny','us','New York'),('nc','us','North Carolina'),('nd','us','North Dakota'),('mp','us','Northern Mariana Islands'),('oh','us','Ohio'),('ok','us','Oklahoma'),('or','us','Oregon'),('pw','us','Palau'),('pa','us','Pennsylvania'),('pr','us','Puerto Rico'),('ri','us','Rhode Island'),('sc','us','South Carolina'),('sd','us','South Dakota'),('tn','us','Tennessee'),('tx','us','Texas'),('ut','us','Utah'),('vt','us','Vermont'),('vi','us','Virgin Island'),('va','us','Virginia'),('wa','us','Washington'),('wv','us','West Virginia'),('wi','us','Wisconsin'),('wy','us','Wyoming'),('ab','ca','Alberta'),('bc','ca','British Columbia'),('mb','ca','Manitoba'),('nb','ca','New Brunswick'),('nf','ca','New Foundland'),('nt','ca','Northwest Territories'),('ns','ca','Nova Scotia'),('on','ca','Ontario'),('pe','ca','Prince Edward Island'),('pq','ca','Quebec'),('sk','ca','Saskatchewan'),('yt','ca','Yukon Territories'); 13 | UPDATE state SET regex=CONCAT('/(',code,')/i'); 14 | select PREG_CHECK("/h[[:alpha:]]+r/") ; 15 | PREG_CHECK("/h[[:alpha:]]+r/") 16 | 1 17 | select PREG_CHECK("/^(a|b)*$/" ); 18 | PREG_CHECK("/^(a|b)*$/" ) 19 | 1 20 | select PREG_CHECK(NULL); 21 | PREG_CHECK(NULL) 22 | NULL 23 | select PREG_CHECK('/goobar'); 24 | PREG_CHECK('/goobar') 25 | 0 26 | select PREG_CHECK('/*.test3/'); 27 | PREG_CHECK('/*.test3/') 28 | 0 29 | select PREG_CHECK(''); 30 | PREG_CHECK('') 31 | 0 32 | DROP TABLE IF EXISTS `patterns`; 33 | CREATE TABLE `patterns` ( 34 | `pattern` varchar(255) 35 | ) ENGINE=HEAP DEFAULT CHARSET=latin1; 36 | INSERT INTO `patterns` VALUES 37 | ('/new/i'), 38 | ('/barFoo') , 39 | ('') , 40 | ('/*.test3/') , 41 | (NULL) , 42 | ('/(new)(\\s)([a-zA-Z0-9]+)(.*)/i'); 43 | SELECT PREG_CHECK( pattern ) FROM patterns; 44 | PREG_CHECK( pattern ) 45 | 1 46 | 0 47 | 0 48 | 0 49 | 0 50 | 1 51 | DROP DATABASE IF EXISTS `preg_test`; 52 | -------------------------------------------------------------------------------- /test/lib_mysqludf_preg_check.test: -------------------------------------------------------------------------------- 1 | ############################## 2 | # 3 | # @file lib_mysqludf_preg_check.test 4 | # This is a file that can be run through mysqltest in order to perform some 5 | # basic for the libmysql_udf_preg_rlike UDF. This should 6 | # usually be invoked through the 'make test' command. 7 | # To record new test results, use: make lib_mysqludf_preg_check.result 8 | # 9 | # 10 | ############################# 11 | 12 | #################################################### 13 | # From mysql function.tst & converted 14 | 15 | # Here are some valid ones 16 | # 17 | select PREG_CHECK("/h[[:alpha:]]+r/") ; 18 | select PREG_CHECK("/^(a|b)*$/" ); 19 | 20 | 21 | # Here are some invalid ones 22 | select PREG_CHECK(NULL); 23 | select PREG_CHECK('/goobar'); 24 | select PREG_CHECK('/*.test3/'); 25 | select PREG_CHECK(''); 26 | #################################################### 27 | 28 | ######### try some none-constant patterns 29 | # 30 | --disable_warnings 31 | DROP TABLE IF EXISTS `patterns`; 32 | --enable_warnings 33 | 34 | CREATE TABLE `patterns` ( 35 | `pattern` varchar(255) 36 | ) ENGINE=HEAP DEFAULT CHARSET=latin1; 37 | INSERT INTO `patterns` VALUES 38 | ('/new/i'), 39 | ('/barFoo') , 40 | ('') , 41 | ('/*.test3/') , 42 | (NULL) , 43 | ('/(new)(\\s)([a-zA-Z0-9]+)(.*)/i'); 44 | 45 | SELECT PREG_CHECK( pattern ) FROM patterns; 46 | 47 | DROP DATABASE IF EXISTS `preg_test`; 48 | -------------------------------------------------------------------------------- /test/lib_mysqludf_preg_info.result: -------------------------------------------------------------------------------- 1 | Use mysql; 2 | DROP DATABASE IF EXISTS `preg_test`; 3 | CREATE DATABASE `preg_test`; 4 | USE `preg_test`; 5 | CREATE TABLE `state` ( 6 | `code` varchar(2) NOT NULL, 7 | `country_code` varchar(2) NOT NULL, 8 | `description` varchar(255) NOT NULL, 9 | `regex` varchar(255) , 10 | PRIMARY KEY (`code`) 11 | ) ENGINE=HEAP DEFAULT CHARSET=latin1; 12 | INSERT INTO `state`(code,country_code,description) VALUES ('al','us','Alabama'),('ak','us','Alaska'),('as','us','American Samoa'),('az','us','Arizona'),('ar','us','Arkansas'),('ca','us','California'),('co','us','Colorado'),('ct','us','Connecticut'),('de','us','Delaware'),('dc','us','District of Columbia'),('fm','us','Federated States of Micronesia'),('fl','us','Florida'),('ga','us','Georgia'),('gu','us','Guam'),('hi','us','Hawaii'),('id','us','Idaho'),('il','us','Illinois'),('in','us','Indiana'),('ia','us','Iowa'),('ks','us','Kansas'),('ky','us','Kentucky'),('la','us','Louisiana'),('me','us','Maine'),('mh','us','Marshall Islands'),('md','us','Maryland'),('ma','us','Massachusetts'),('mi','us','Michigan'),('mn','us','Minnesota'),('ms','us','Mississippi'),('mo','us','Missouri'),('mt','us','Montana'),('ne','us','Nebraska'),('nv','us','Nevada'),('nh','us','New Hampshire'),('nj','us','New Jersey'),('nm','us','New Mexico'),('ny','us','New York'),('nc','us','North Carolina'),('nd','us','North Dakota'),('mp','us','Northern Mariana Islands'),('oh','us','Ohio'),('ok','us','Oklahoma'),('or','us','Oregon'),('pw','us','Palau'),('pa','us','Pennsylvania'),('pr','us','Puerto Rico'),('ri','us','Rhode Island'),('sc','us','South Carolina'),('sd','us','South Dakota'),('tn','us','Tennessee'),('tx','us','Texas'),('ut','us','Utah'),('vt','us','Vermont'),('vi','us','Virgin Island'),('va','us','Virginia'),('wa','us','Washington'),('wv','us','West Virginia'),('wi','us','Wisconsin'),('wy','us','Wyoming'),('ab','ca','Alberta'),('bc','ca','British Columbia'),('mb','ca','Manitoba'),('nb','ca','New Brunswick'),('nf','ca','New Foundland'),('nt','ca','Northwest Territories'),('ns','ca','Nova Scotia'),('on','ca','Ontario'),('pe','ca','Prince Edward Island'),('pq','ca','Quebec'),('sk','ca','Saskatchewan'),('yt','ca','Yukon Territories'); 13 | UPDATE state SET regex=CONCAT('/(',code,')/i'); 14 | SELECT SUBSTR( LIB_MYSQLUDF_PREG_INFO() , 1, 17 ) ; 15 | SUBSTR( LIB_MYSQLUDF_PREG_INFO() , 1, 17 ) 16 | lib_mysqludf_preg 17 | DROP DATABASE IF EXISTS `preg_test`; 18 | -------------------------------------------------------------------------------- /test/lib_mysqludf_preg_info.test: -------------------------------------------------------------------------------- 1 | ############################## 2 | # 3 | # @file lib_mysqludf_preg_info.test 4 | # This is a file that can be run through mysqltest in order to perform some 5 | # basic for the libmysql_udf_preg_rlike UDF. This should 6 | # usually be invoked through the 'make test' command. 7 | # To record new test results, use: make lib_mysqludf_preg_info.result 8 | # 9 | ############################## 10 | 11 | 12 | 13 | 14 | ####################################################### 15 | # Test the info - function - chop off version so result is not 16 | # version-dependant 17 | #### 18 | SELECT SUBSTR( LIB_MYSQLUDF_PREG_INFO() , 1, 17 ) ; 19 | 20 | 21 | DROP DATABASE IF EXISTS `preg_test`; 22 | 23 | -------------------------------------------------------------------------------- /test/lib_mysqludf_preg_position.result: -------------------------------------------------------------------------------- 1 | Use mysql; 2 | DROP DATABASE IF EXISTS `preg_test`; 3 | CREATE DATABASE `preg_test`; 4 | USE `preg_test`; 5 | CREATE TABLE `state` ( 6 | `code` varchar(2) NOT NULL, 7 | `country_code` varchar(2) NOT NULL, 8 | `description` varchar(255) NOT NULL, 9 | `regex` varchar(255) , 10 | PRIMARY KEY (`code`) 11 | ) ENGINE=HEAP DEFAULT CHARSET=latin1; 12 | INSERT INTO `state`(code,country_code,description) VALUES ('al','us','Alabama'),('ak','us','Alaska'),('as','us','American Samoa'),('az','us','Arizona'),('ar','us','Arkansas'),('ca','us','California'),('co','us','Colorado'),('ct','us','Connecticut'),('de','us','Delaware'),('dc','us','District of Columbia'),('fm','us','Federated States of Micronesia'),('fl','us','Florida'),('ga','us','Georgia'),('gu','us','Guam'),('hi','us','Hawaii'),('id','us','Idaho'),('il','us','Illinois'),('in','us','Indiana'),('ia','us','Iowa'),('ks','us','Kansas'),('ky','us','Kentucky'),('la','us','Louisiana'),('me','us','Maine'),('mh','us','Marshall Islands'),('md','us','Maryland'),('ma','us','Massachusetts'),('mi','us','Michigan'),('mn','us','Minnesota'),('ms','us','Mississippi'),('mo','us','Missouri'),('mt','us','Montana'),('ne','us','Nebraska'),('nv','us','Nevada'),('nh','us','New Hampshire'),('nj','us','New Jersey'),('nm','us','New Mexico'),('ny','us','New York'),('nc','us','North Carolina'),('nd','us','North Dakota'),('mp','us','Northern Mariana Islands'),('oh','us','Ohio'),('ok','us','Oklahoma'),('or','us','Oregon'),('pw','us','Palau'),('pa','us','Pennsylvania'),('pr','us','Puerto Rico'),('ri','us','Rhode Island'),('sc','us','South Carolina'),('sd','us','South Dakota'),('tn','us','Tennessee'),('tx','us','Texas'),('ut','us','Utah'),('vt','us','Vermont'),('vi','us','Virgin Island'),('va','us','Virginia'),('wa','us','Washington'),('wv','us','West Virginia'),('wi','us','Wisconsin'),('wy','us','Wyoming'),('ab','ca','Alberta'),('bc','ca','British Columbia'),('mb','ca','Manitoba'),('nb','ca','New Brunswick'),('nf','ca','New Foundland'),('nt','ca','Northwest Territories'),('ns','ca','Nova Scotia'),('on','ca','Ontario'),('pe','ca','Prince Edward Island'),('pq','ca','Quebec'),('sk','ca','Saskatchewan'),('yt','ca','Yukon Territories'); 13 | UPDATE state SET regex=CONCAT('/(',code,')/i'); 14 | SELECT PREG_POSITION( '/(x)(?:(abc)|(xyz))(x)/' , 'xabcx' , 2 ) ; 15 | PREG_POSITION( '/(x)(?:(abc)|(xyz))(x)/' , 'xabcx' , 2 ) 16 | 2 17 | SELECT PREG_POSITION('/(.*?)(fox)/' , 'the quick brown fox' ,2 ); 18 | PREG_POSITION('/(.*?)(fox)/' , 'the quick brown fox' ,2 ) 19 | 17 20 | SELECT PREG_POSITION( '/(new)\\s+([a-zA-Z]*)(.*)/i' , description, 2 ) FROM state WHERE description LIKE 'new%' ; 21 | PREG_POSITION( '/(new)\\s+([a-zA-Z]*)(.*)/i' , description, 2 ) 22 | 5 23 | 5 24 | 5 25 | 5 26 | 5 27 | 5 28 | SELECT PREG_POSITION( '/(new)\\s+(?P[^\\s]*)(.*)/i' , description, 'word' ) FROM state WHERE PREG_RLIKE( '/new/i' , description ); 29 | PREG_POSITION( '/(new)\\s+(?P[^\\s]*)(.*)/i' , description, 'word' ) 30 | 5 31 | 5 32 | 5 33 | 5 34 | 5 35 | 5 36 | SELECT PREG_POSITION( '/"([^"]+)"/' , 'the "quick" brown fox "jumped" over the "lazy" dog' , 1,2 ); 37 | PREG_POSITION( '/"([^"]+)"/' , 'the "quick" brown fox "jumped" over the "lazy" dog' , 1,2 ) 38 | 24 39 | SELECT PREG_POSITION( '/b[^\\s]*/' , 'the quick brown fox jumped up & down' ); 40 | PREG_POSITION( '/b[^\\s]*/' , 'the quick brown fox jumped up & down' ) 41 | 11 42 | SELECT PREG_POSITION( '/b[^\\s]*/' , 'the quick brown fox jumped up & down',0,4); 43 | PREG_POSITION( '/b[^\\s]*/' , 'the quick brown fox jumped up & down',0,4) 44 | NULL 45 | SELECT PREG_POSITION( '/b[^\\s]*/' , 'the quick brown fox jumped up & down',4); 46 | PREG_POSITION( '/b[^\\s]*/' , 'the quick brown fox jumped up & down',4) 47 | NULL 48 | DROP TABLE IF EXISTS `patterns`; 49 | CREATE TABLE `patterns` ( 50 | `pattern` varchar(255) NOT NULL, 51 | `groupnum` int NOT NULL , 52 | `groupname` varchar(255) NOT NULL, 53 | `occurence` int NOT NULL 54 | ) ENGINE=HEAP DEFAULT CHARSET=latin1; 55 | INSERT INTO `patterns` VALUES 56 | ('/new/i',0,'',1), 57 | ('/(new)(\\s)([a-zA-Z0-9]+)(.*)/i',3,'',1), 58 | ('/(new)(\\s)(?P[a-zA-Z0-9]+)(.*)/i',0,'thing',1) ; 59 | SELECT DISTINCT PREG_POSITION( pattern,description,groupnum,occurence) AS w FROM state, patterns WHERE PREG_RLIKE( pattern, description ) AND groupname='' HAVING w IS NOT NULL ORDER BY w; 60 | w 61 | 1 62 | 5 63 | DROP DATABASE IF EXISTS `preg_test`; 64 | -------------------------------------------------------------------------------- /test/lib_mysqludf_preg_position.test: -------------------------------------------------------------------------------- 1 | ############################## 2 | # 3 | # @file lib_mysqludf_preg_position.test 4 | # 5 | # This is a file that can be run through mysqltest in order to perform some 6 | # basic for the libmysql_udf_preg_position UDF. This should 7 | # usually be invoked through the 'make test' command in ../Makefile. 8 | # To record new test results, use: make lib_mysqludf_preg_position.result 9 | # 10 | ############################# 11 | 12 | #################################################### 13 | # From mysql function.tst & converted 14 | 15 | #****************** ****** 16 | # This one has some problems on debian sid -- Investigate 17 | #SELECT PREG_POSITION( '/(x)(?|(abc)|(xyz))(x)/' , 'xabcx' , 2 ) ; 18 | # 19 | SELECT PREG_POSITION( '/(x)(?:(abc)|(xyz))(x)/' , 'xabcx' , 2 ) ; 20 | #################################################### 21 | 22 | 23 | 24 | #################################################### 25 | #### Here are some others 26 | 27 | #position the fox 28 | SELECT PREG_POSITION('/(.*?)(fox)/' , 'the quick brown fox' ,2 ); 29 | 30 | #### Position of the word after new in state 31 | SELECT PREG_POSITION( '/(new)\\s+([a-zA-Z]*)(.*)/i' , description, 2 ) FROM state WHERE description LIKE 'new%' ; 32 | 33 | #### Same thing with a named group 34 | SELECT PREG_POSITION( '/(new)\\s+(?P[^\\s]*)(.*)/i' , description, 'word' ) FROM state WHERE PREG_RLIKE( '/new/i' , description ); 35 | 36 | 37 | #### Use occurence arg to get 2nd quoted word ######## 38 | SELECT PREG_POSITION( '/"([^"]+)"/' , 'the "quick" brown fox "jumped" over the "lazy" dog' , 1,2 ); 39 | 40 | #### simple case -- capture first word starting with b 41 | SELECT PREG_POSITION( '/b[^\\s]*/' , 'the quick brown fox jumped up & down' ); 42 | 43 | #### out of bounds 44 | SELECT PREG_POSITION( '/b[^\\s]*/' , 'the quick brown fox jumped up & down',0,4); 45 | SELECT PREG_POSITION( '/b[^\\s]*/' , 'the quick brown fox jumped up & down',4); 46 | 47 | 48 | ######### try some none-constant patterns & replacements 49 | # 50 | 51 | --disable_warnings 52 | DROP TABLE IF EXISTS `patterns`; 53 | --enable_warnings 54 | 55 | CREATE TABLE `patterns` ( 56 | `pattern` varchar(255) NOT NULL, 57 | `groupnum` int NOT NULL , 58 | `groupname` varchar(255) NOT NULL, 59 | `occurence` int NOT NULL 60 | ) ENGINE=HEAP DEFAULT CHARSET=latin1; 61 | INSERT INTO `patterns` VALUES 62 | ('/new/i',0,'',1), 63 | ('/(new)(\\s)([a-zA-Z0-9]+)(.*)/i',3,'',1), 64 | ('/(new)(\\s)(?P[a-zA-Z0-9]+)(.*)/i',0,'thing',1) ; 65 | 66 | SELECT DISTINCT PREG_POSITION( pattern,description,groupnum,occurence) AS w FROM state, patterns WHERE PREG_RLIKE( pattern, description ) AND groupname='' HAVING w IS NOT NULL ORDER BY w; 67 | 68 | DROP DATABASE IF EXISTS `preg_test`; 69 | 70 | -------------------------------------------------------------------------------- /test/lib_mysqludf_preg_replace.result: -------------------------------------------------------------------------------- 1 | Use mysql; 2 | DROP DATABASE IF EXISTS `preg_test`; 3 | CREATE DATABASE `preg_test`; 4 | USE `preg_test`; 5 | CREATE TABLE `state` ( 6 | `code` varchar(2) NOT NULL, 7 | `country_code` varchar(2) NOT NULL, 8 | `description` varchar(255) NOT NULL, 9 | `regex` varchar(255) , 10 | PRIMARY KEY (`code`) 11 | ) ENGINE=HEAP DEFAULT CHARSET=latin1; 12 | INSERT INTO `state`(code,country_code,description) VALUES ('al','us','Alabama'),('ak','us','Alaska'),('as','us','American Samoa'),('az','us','Arizona'),('ar','us','Arkansas'),('ca','us','California'),('co','us','Colorado'),('ct','us','Connecticut'),('de','us','Delaware'),('dc','us','District of Columbia'),('fm','us','Federated States of Micronesia'),('fl','us','Florida'),('ga','us','Georgia'),('gu','us','Guam'),('hi','us','Hawaii'),('id','us','Idaho'),('il','us','Illinois'),('in','us','Indiana'),('ia','us','Iowa'),('ks','us','Kansas'),('ky','us','Kentucky'),('la','us','Louisiana'),('me','us','Maine'),('mh','us','Marshall Islands'),('md','us','Maryland'),('ma','us','Massachusetts'),('mi','us','Michigan'),('mn','us','Minnesota'),('ms','us','Mississippi'),('mo','us','Missouri'),('mt','us','Montana'),('ne','us','Nebraska'),('nv','us','Nevada'),('nh','us','New Hampshire'),('nj','us','New Jersey'),('nm','us','New Mexico'),('ny','us','New York'),('nc','us','North Carolina'),('nd','us','North Dakota'),('mp','us','Northern Mariana Islands'),('oh','us','Ohio'),('ok','us','Oklahoma'),('or','us','Oregon'),('pw','us','Palau'),('pa','us','Pennsylvania'),('pr','us','Puerto Rico'),('ri','us','Rhode Island'),('sc','us','South Carolina'),('sd','us','South Dakota'),('tn','us','Tennessee'),('tx','us','Texas'),('ut','us','Utah'),('vt','us','Vermont'),('vi','us','Virgin Island'),('va','us','Virginia'),('wa','us','Washington'),('wv','us','West Virginia'),('wi','us','Wisconsin'),('wy','us','Wyoming'),('ab','ca','Alberta'),('bc','ca','British Columbia'),('mb','ca','Manitoba'),('nb','ca','New Brunswick'),('nf','ca','New Foundland'),('nt','ca','Northwest Territories'),('ns','ca','Nova Scotia'),('on','ca','Ontario'),('pe','ca','Prince Edward Island'),('pq','ca','Quebec'),('sk','ca','Saskatchewan'),('yt','ca','Yukon Territories'); 13 | UPDATE state SET regex=CONCAT('/(',code,')/i'); 14 | SELECT PREG_REPLACE('/fox/i' , '' , 'the quick brown fox' ,2 ); 15 | PREG_REPLACE('/fox/i' , '' , 'the quick brown fox' ,2 ) 16 | the quick brown 17 | SELECT PREG_REPLACE('/brown/i' , 'dark green' , 'the quick brown fox' ,2 ); 18 | PREG_REPLACE('/brown/i' , 'dark green' , 'the quick brown fox' ,2 ) 19 | the quick dark green fox 20 | SELECT PREG_REPLACE('/([^\\s]+)(\\s)([^\\s]+)(\\s+)([^\\s]+)(\\s)(.*)/' , '$7$6$5$4$3$2$1' , 'the quick brown fox' ); 21 | PREG_REPLACE('/([^\\s]+)(\\s)([^\\s]+)(\\s+)([^\\s]+)(\\s)(.*)/' , '$7$6$5$4$3$2$1' , 'the quick brown fox' ) 22 | fox brown quick the 23 | SELECT PREG_REPLACE( '//' , 'a' , 'bbb' ); 24 | PREG_REPLACE( '//' , 'a' , 'bbb' ) 25 | abababa 26 | SELECT PREG_REPLACE( '/(new)(\\s+)([a-zA-Z]*)(.*)/i' ,'$1$2 Old$4', description ) FROM state WHERE description LIKE 'new%' ; 27 | PREG_REPLACE( '/(new)(\\s+)([a-zA-Z]*)(.*)/i' ,'$1$2 Old$4', description ) 28 | New Old 29 | New Old 30 | New Old 31 | New Old 32 | New Old 33 | New Old 34 | SELECT PREG_REPLACE( '/([^\\s]*)(\\s+)([^\\s]*)/' ,'$3 $1', description ) FROM state WHERE PREG_RLIKE( '/^[a-z]+\\s+[a-z]+$/i',description); 35 | PREG_REPLACE( '/([^\\s]*)(\\s+)([^\\s]*)/' ,'$3 $1', description ) 36 | Samoa American 37 | Islands Marshall 38 | Hampshire New 39 | Jersey New 40 | Mexico New 41 | York New 42 | Carolina North 43 | Dakota North 44 | Rico Puerto 45 | Island Rhode 46 | Carolina South 47 | Dakota South 48 | Island Virgin 49 | Virginia West 50 | Columbia British 51 | Brunswick New 52 | Foundland New 53 | Territories Northwest 54 | Scotia Nova 55 | Territories Yukon 56 | SELECT PREG_REPLACE ('/a*/',NULL, 'America'); 57 | PREG_REPLACE ('/a*/',NULL, 'America') 58 | NULL 59 | SELECT PREG_REPLACE (NULL ,'foo', 'America'); 60 | PREG_REPLACE (NULL ,'foo', 'America') 61 | NULL 62 | SELECT PREG_REPLACE ('/a*/' ,'foo', NULL); 63 | PREG_REPLACE ('/a*/' ,'foo', NULL) 64 | NULL 65 | DROP TABLE IF EXISTS `patterns`; 66 | CREATE TABLE `patterns` ( 67 | `pattern` varchar(255) NOT NULL, 68 | `replacement` varchar(255) NOT NULL 69 | ) ENGINE=HEAP DEFAULT CHARSET=latin1; 70 | INSERT INTO `patterns` VALUES 71 | ('/new/i','old'), 72 | ('/(new)(\\s)([a-zA-Z0-9]+)(.*)/i','$3'); 73 | SELECT pattern,PREG_REPLACE( pattern, replacement , description ) FROM patterns,state WHERE PREG_RLIKE(pattern , description) ORDER by pattern; 74 | pattern PREG_REPLACE( pattern, replacement , description ) 75 | /(new)(\s)([a-zA-Z0-9]+)(.*)/i Hampshire 76 | /(new)(\s)([a-zA-Z0-9]+)(.*)/i Jersey 77 | /(new)(\s)([a-zA-Z0-9]+)(.*)/i Mexico 78 | /(new)(\s)([a-zA-Z0-9]+)(.*)/i York 79 | /(new)(\s)([a-zA-Z0-9]+)(.*)/i Brunswick 80 | /(new)(\s)([a-zA-Z0-9]+)(.*)/i Foundland 81 | /new/i old Hampshire 82 | /new/i old Jersey 83 | /new/i old Mexico 84 | /new/i old York 85 | /new/i old Brunswick 86 | /new/i old Foundland 87 | CREATE TABLE `subjects` ( 88 | `subject` LONGBLOB 89 | ) ; 90 | INSERT INTO `subjects` VALUES 91 | ('The newest version of the library is the best, maybe' ); 92 | SELECT pattern,PREG_REPLACE( pattern, replacement , subject ) FROM patterns,subjects WHERE PREG_RLIKE(pattern , subject) ORDER by pattern; 93 | pattern PREG_REPLACE( pattern, replacement , subject ) 94 | /new/i The oldest version of the library is the best, maybe 95 | DROP DATABASE IF EXISTS `preg_test`; 96 | -------------------------------------------------------------------------------- /test/lib_mysqludf_preg_replace.test: -------------------------------------------------------------------------------- 1 | ############################## 2 | # 3 | # @file lib_mysqludf_preg_replace.test 4 | # 5 | # This is a file that can be run through mysqltest in order to perform some 6 | # basic for the libmysql_udf_preg_replace UDF. This should 7 | # usually be invoked through the 'make test' command in ../Makefile. 8 | # To record new test results, use: make lib_mysqludf_preg_replace.result 9 | # 10 | # 11 | ############################# 12 | 13 | #################################################### 14 | 15 | # kill the fox 16 | SELECT PREG_REPLACE('/fox/i' , '' , 'the quick brown fox' ,2 ); 17 | 18 | # make the fox dark green 19 | SELECT PREG_REPLACE('/brown/i' , 'dark green' , 'the quick brown fox' ,2 ); 20 | 21 | # reverse the words 22 | SELECT PREG_REPLACE('/([^\\s]+)(\\s)([^\\s]+)(\\s+)([^\\s]+)(\\s)(.*)/' , '$7$6$5$4$3$2$1' , 'the quick brown fox' ); 23 | 24 | # Empty pattern 25 | SELECT PREG_REPLACE( '//' , 'a' , 'bbb' ); 26 | 27 | ##### Replace new with old #### 28 | #SELECT PREG_REPLACE( '/new/i' ,'old', description ) FROM state WHERE description LIKE 'new%' ; 29 | 30 | #### Replace word after new in state with Old 31 | SELECT PREG_REPLACE( '/(new)(\\s+)([a-zA-Z]*)(.*)/i' ,'$1$2 Old$4', description ) FROM state WHERE description LIKE 'new%' ; 32 | 33 | #### Reverse state 34 | SELECT PREG_REPLACE( '/([^\\s]*)(\\s+)([^\\s]*)/' ,'$3 $1', description ) FROM state WHERE PREG_RLIKE( '/^[a-z]+\\s+[a-z]+$/i',description); 35 | 36 | ###### Check NULL stufff (Bug #4) 37 | SELECT PREG_REPLACE ('/a*/',NULL, 'America'); 38 | SELECT PREG_REPLACE (NULL ,'foo', 'America'); 39 | SELECT PREG_REPLACE ('/a*/' ,'foo', NULL); 40 | 41 | 42 | ######### try some none-constant patterns & replacements 43 | # 44 | --disable_warnings 45 | DROP TABLE IF EXISTS `patterns`; 46 | --enable_warnings 47 | 48 | CREATE TABLE `patterns` ( 49 | `pattern` varchar(255) NOT NULL, 50 | `replacement` varchar(255) NOT NULL 51 | ) ENGINE=HEAP DEFAULT CHARSET=latin1; 52 | INSERT INTO `patterns` VALUES 53 | ('/new/i','old'), 54 | ('/(new)(\\s)([a-zA-Z0-9]+)(.*)/i','$3'); 55 | 56 | SELECT pattern,PREG_REPLACE( pattern, replacement , description ) FROM patterns,state WHERE PREG_RLIKE(pattern , description) ORDER by pattern; 57 | 58 | CREATE TABLE `subjects` ( 59 | `subject` LONGBLOB 60 | ) ; 61 | INSERT INTO `subjects` VALUES 62 | ('The newest version of the library is the best, maybe' ); 63 | 64 | 65 | SELECT pattern,PREG_REPLACE( pattern, replacement , subject ) FROM patterns,subjects WHERE PREG_RLIKE(pattern , subject) ORDER by pattern; 66 | 67 | DROP DATABASE IF EXISTS `preg_test`; 68 | 69 | -------------------------------------------------------------------------------- /test/lib_mysqludf_preg_rlike.result: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysqludf/lib_mysqludf_preg/6395901adaf987a9f9e4e1b859daad4f2d665eff/test/lib_mysqludf_preg_rlike.result -------------------------------------------------------------------------------- /test/lib_mysqludf_preg_rlike.test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mysqludf/lib_mysqludf_preg/6395901adaf987a9f9e4e1b859daad4f2d665eff/test/lib_mysqludf_preg_rlike.test -------------------------------------------------------------------------------- /uninstalldb.sql: -------------------------------------------------------------------------------- 1 | 2 | USE mysql; 3 | 4 | # deprecated functions 5 | DROP FUNCTION IF EXISTS ghpcre_capture ; 6 | DROP FUNCTION IF EXISTS ghpcre_rlike ; 7 | DROP FUNCTION IF EXISTS preg_offset ; 8 | 9 | # current function 10 | DROP FUNCTION IF EXISTS lib_mysqludf_preg_info ; 11 | DROP FUNCTION IF EXISTS preg_capture ; 12 | DROP FUNCTION IF EXISTS preg_check ; 13 | DROP FUNCTION IF EXISTS preg_position ; 14 | DROP FUNCTION IF EXISTS preg_rlike ; 15 | DROP FUNCTION IF EXISTS preg_replace ; --------------------------------------------------------------------------------