├── mrbgem.rake ├── README.md ├── test └── mruby_pcre_regexp.rb ├── mrblib └── pcre_regexp.rb └── src ├── mruby_pcre_regexp.c └── pcre.h /mrbgem.rake: -------------------------------------------------------------------------------- 1 | MRuby::Gem::Specification.new('mruby-pcre-regexp') do |spec| 2 | spec.license = 'MIT' 3 | spec.authors = 'mattn' 4 | 5 | spec.linker.libraries << ['pcre'] 6 | end 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Note on Windows build 2 | ===================== 3 | 4 | Current version builds on Windows 7, provided that the files pcre.h and pcre3.lib are available under C:/Windows/system. 5 | 6 | Look on [http://www.airesoft.co.uk/pcre](www.airesoft.co.uk) for a prebuilt version of PCRE. 7 | 8 | Check and edit the mrbgem.rake accordingly. 9 | -------------------------------------------------------------------------------- /test/mruby_pcre_regexp.rb: -------------------------------------------------------------------------------- 1 | 2 | # Constant 3 | assert("PcreRegexp::CONSTANT") do 4 | PcreRegexp::IGNORECASE == 1 and PcreRegexp::EXTENDED == 2 and PcreRegexp::MULTILINE == 4 5 | end 6 | 7 | 8 | # Class method 9 | assert("PcreRegexp.new") do 10 | PcreRegexp.new(".*") and PcreRegexp.new(".*", PcreRegexp::MULTILINE) 11 | end 12 | 13 | # Instance method 14 | assert("PcreRegexp#==") do 15 | reg1 = reg2 = PcreRegexp.new("(https?://[^/]+)[-a-zA-Z0-9./]+") 16 | reg3 = PcreRegexp.new("(https?://[^/]+)[-a-zA-Z0-9./]+") 17 | reg4 = PcreRegexp.new("(https://[^/]+)[-a-zA-Z0-9./]+") 18 | 19 | reg1 == reg2 and reg1 == reg3 and !(reg1 == reg4) 20 | end 21 | 22 | assert("PcreRegexp#===") do 23 | reg = PcreRegexp.new("(https?://[^/]+)[-a-zA-Z0-9./]+") 24 | (reg === "http://example.com") == true and (reg === "htt://example.com") == false 25 | end 26 | 27 | # TODO =~ 28 | 29 | assert("PcreRegexp#casefold?") do 30 | reg1 = PcreRegexp.new("(https?://[^/]+)[-a-zA-Z0-9./]+", PcreRegexp::MULTILINE) 31 | reg2 = PcreRegexp.new("(https?://[^/]+)[-a-zA-Z0-9./]+", PcreRegexp::IGNORECASE | PcreRegexp::EXTENDED) 32 | reg3 = PcreRegexp.new("(https?://[^/]+)[-a-zA-Z0-9./]+", PcreRegexp::MULTILINE | PcreRegexp::IGNORECASE) 33 | reg4 = PcreRegexp.new("(https?://[^/]+)[-a-zA-Z0-9./]+") 34 | reg5 = PcreRegexp.new("(https?://[^/]+)[-a-zA-Z0-9./]+", true) 35 | 36 | reg1.casefold? == false and reg2.casefold? == true and reg3.casefold? == true and 37 | reg4.casefold? == false and reg5.casefold? == true 38 | end 39 | 40 | assert("PcreRegexp#match") do 41 | reg = PcreRegexp.new("(https?://[^/]+)[-a-zA-Z0-9./]+") 42 | reg.match("http://masamitsu-murase.12345/hoge.html") and 43 | reg.match("http:///masamitsu-murase.12345/hoge.html").nil? 44 | end 45 | 46 | assert("PcreRegexp#source") do 47 | str = "(https?://[^/]+)[-a-zA-Z0-9./]+" 48 | reg = PcreRegexp.new(str) 49 | 50 | reg.source == str 51 | end 52 | 53 | # Extended patterns. 54 | assert("PcreRegexp#match (no flags)") do 55 | patterns = [ 56 | [ PcreRegexp.new(".*"), "abcd\nefg", "abcd" ], 57 | [ PcreRegexp.new("^a."), "abcd\naefg", "ab" ], 58 | [ PcreRegexp.new("^b."), "bacd\naefg", "ba" ], 59 | [ PcreRegexp.new(".$"), "bacd\naefg", "g" ] 60 | ] 61 | 62 | patterns.all?{ |reg, str, result| reg.match(str)[0] == result } 63 | end 64 | 65 | assert("PcreRegexp#match (multiline)") do 66 | patterns = [ 67 | [ PcreRegexp.new(".*", PcreRegexp::MULTILINE), "abc\ndef", "abc\ndef" ], 68 | [ PcreRegexp.new(".*"), "abc\ndef", "abc" ], 69 | [ PcreRegexp.new(".c$", PcreRegexp::MULTILINE), "abc\nefc", "bc" ], 70 | [ PcreRegexp.new(".c$"), "abc\nefc", "fc" ] 71 | ] 72 | 73 | patterns.all?{ |reg, str, result| reg.match(str)[0] == result} 74 | end 75 | 76 | assert("PcreRegexp#match (ignorecase)") do 77 | patterns = [ 78 | [ PcreRegexp.new("aBcD", PcreRegexp::IGNORECASE|PcreRegexp::EXTENDED), "00AbcDef", "AbcD" ], 79 | [ PcreRegexp.new("0x[a-f]+", PcreRegexp::IGNORECASE|PcreRegexp::EXTENDED), "00XaBCdefG", "0XaBCdef" ], 80 | [ PcreRegexp.new("0x[^c-f]+", PcreRegexp::IGNORECASE|PcreRegexp::EXTENDED), "00XaBCdefG", "0XaB" ] 81 | ] 82 | 83 | patterns.all?{ |reg, str, result| reg.match(str)[0] == result } 84 | end 85 | 86 | -------------------------------------------------------------------------------- /mrblib/pcre_regexp.rb: -------------------------------------------------------------------------------- 1 | class PcreRegexp 2 | @memo = {} 3 | 4 | def self.compile(*args) 5 | as = args.to_s 6 | unless @memo.key? as 7 | @memo[as] = self.new(*args) 8 | end 9 | @memo[as] 10 | end 11 | 12 | # ISO 15.2.15.7.8 13 | attr_reader :source 14 | 15 | def self.last_match 16 | return @last_match 17 | end 18 | 19 | def ===(str) 20 | return self.match(str) ? true : false 21 | end 22 | 23 | def =~(str) 24 | m = self.match(str) 25 | return m ? m.begin(0) : nil 26 | end 27 | end 28 | 29 | class PcreMatchData 30 | # ISO 15.2.16.3.11 31 | attr_reader :string 32 | 33 | def initialize 34 | @data = [] 35 | @string = "" 36 | end 37 | 38 | def push(beg = nil, len = nil) 39 | if (beg && len) 40 | @data.push(beg: beg, len: len) 41 | else 42 | @data.push(nil) 43 | end 44 | end 45 | 46 | # ISO 15.2.16.3.2 47 | def begin(index) 48 | d = @data[index] 49 | return (d && d[:beg]) 50 | end 51 | 52 | # ISO 15.2.16.3.4 53 | def end(index = 0) 54 | d = @data[index] 55 | return (d && (d[:beg] + d[:len])) 56 | end 57 | 58 | # ISO 15.2.16.3.1 59 | def [](index) 60 | d = @data[index] 61 | return (d && @string.slice(d[:beg], d[:len])) 62 | end 63 | 64 | # ISO 15.2.16.3.8 65 | def post_match 66 | d = @data[0] 67 | return @string.slice(d[:beg] + d[:len] .. -1) 68 | end 69 | 70 | # ISO 15.2.16.3.9 71 | def pre_match 72 | return @string.slice(0, @data[0][:beg]) 73 | end 74 | 75 | # ISO 15.2.16.3.7 76 | def offset(index) 77 | d = @data[index] 78 | return (d && [ d[:beg], d[:beg] + d[:len] ]) 79 | end 80 | 81 | # ISO 15.2.16.3.13 82 | def to_s 83 | return self[0] 84 | end 85 | 86 | def length 87 | return @data.length 88 | end 89 | 90 | def size 91 | return @data.size 92 | end 93 | end 94 | 95 | class String 96 | def =~(a) 97 | begin 98 | (a.class.to_s == 'String' ? Regexp.new(a.to_s) : a) =~ self 99 | rescue 100 | false 101 | end 102 | end 103 | alias_method :old_sub, :sub 104 | def sub(*args, &blk) 105 | if args[0].class.to_s == 'String' 106 | return blk ? old_sub(*args) {|x| blk.call(x)} : old_sub(*args) 107 | end 108 | begin 109 | m = args[0].match(self) 110 | rescue 111 | return self 112 | end 113 | return self if m.size == 0 114 | r = '' 115 | r += m.pre_match 116 | r += blk ? blk.call(m[0]) : args[1] 117 | r += m.post_match 118 | r 119 | end 120 | alias_method :old_gsub, :gsub 121 | def gsub(*args, &blk) 122 | if args[0].class.to_s == 'String' 123 | return blk ? old_gsub(*args) {|x| blk.call(x)} : old_gsub(*args) 124 | end 125 | ss = self 126 | r = '' 127 | while true 128 | begin 129 | m = args[0].match(ss) 130 | rescue 131 | break 132 | end 133 | break if !m || m.size == 0 134 | return r if m.end(0) == 0 135 | r += m.pre_match 136 | r += blk ? blk.call(m[0]) : args[1] 137 | ss = m.post_match 138 | end 139 | r += ss 140 | r 141 | end 142 | alias_method :old_split, :split 143 | def split(*args) 144 | return old_split(' ') if args[0] == nil 145 | return old_split(*args) if args[0].class.to_s == 'String' 146 | ss = self 147 | r = [] 148 | l = args.size == 2 ? args[1].to_i : 0 149 | while true 150 | begin 151 | m = args[0].match(ss) 152 | rescue 153 | break 154 | end 155 | break if !m || m.size == 0 156 | return r if m.end(0) == 0 157 | r << m.pre_match 158 | (1..m.size-1).each do |x| 159 | r << m[x] unless m[x].empty? 160 | end 161 | ss = m.post_match 162 | l -= 1 163 | break unless l 164 | end 165 | r << ss 166 | r 167 | end 168 | alias_method :old_scan, :scan 169 | def scan(*args, &blk) 170 | return old_scan(*args) if args[0].class.to_s == 'String' 171 | ss = self 172 | r = [] 173 | while true 174 | begin 175 | m = args[0].match(ss) 176 | rescue 177 | return [] 178 | end 179 | break if !m || m.size == 0 180 | return r if m.end(0) == 0 181 | r << m[0] 182 | ss = m.post_match 183 | end 184 | if blk 185 | r.each do |x| 186 | blk.call(x) 187 | end 188 | return self 189 | end 190 | r 191 | end 192 | end 193 | 194 | Regexp = PcreRegexp unless Object.const_defined?(:Regexp) 195 | 196 | # This is based on https://github.com/masamitsu-murase/mruby-hs-regexp 197 | -------------------------------------------------------------------------------- /src/mruby_pcre_regexp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #if defined(_WIN32) || defined(_WIN64) 11 | #include 12 | #define STRCHR StrChr 13 | #else 14 | #define STRCHR strchr 15 | #endif 16 | #include "pcre.h" 17 | 18 | struct mrb_pcre_regexp { 19 | pcre* re; 20 | int flag; 21 | }; 22 | 23 | static void 24 | pcre_regexp_free(mrb_state *mrb, void *p) { 25 | struct mrb_pcre_regexp *pre = (struct mrb_pcre_regexp *) p; 26 | pcre_free(pre->re); 27 | mrb_free(mrb, pre); 28 | } 29 | 30 | static struct mrb_data_type mrb_pcre_regexp_type = { 31 | "PosixRegexp", pcre_regexp_free 32 | }; 33 | 34 | static void 35 | pcre_regexp_init(mrb_state *mrb, mrb_value self, mrb_value str, mrb_value flag) { 36 | mrb_value regexp; 37 | struct mrb_pcre_regexp *reg; 38 | int cflag = 0; 39 | int erroff = 0; 40 | const char *errstr = NULL; 41 | 42 | regexp = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@regexp")); 43 | if (mrb_nil_p(regexp)) { 44 | reg = malloc(sizeof(struct mrb_pcre_regexp)); 45 | memset(reg, 0, sizeof(struct mrb_pcre_regexp)); 46 | mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "@regexp"), mrb_obj_value( 47 | Data_Wrap_Struct(mrb, mrb->object_class, 48 | &mrb_pcre_regexp_type, (void*) reg))); 49 | }else{ 50 | Data_Get_Struct(mrb, regexp, &mrb_pcre_regexp_type, reg); 51 | pcre_free(reg->re); 52 | } 53 | 54 | if (mrb_nil_p(flag)) 55 | cflag = 0; 56 | else if (mrb_fixnum_p(flag)) { 57 | int nflag = mrb_fixnum(flag); 58 | if (nflag & 1) cflag |= PCRE_CASELESS; 59 | if (nflag & 2) cflag |= PCRE_EXTENDED; 60 | if (nflag & 4) cflag |= PCRE_MULTILINE | PCRE_DOTALL; 61 | } else if (mrb_type(flag) == MRB_TT_TRUE) 62 | cflag |= PCRE_CASELESS; 63 | else if (mrb_string_p(flag)) { 64 | if (STRCHR(RSTRING_PTR(flag), 'i')) cflag |= PCRE_CASELESS; 65 | if (STRCHR(RSTRING_PTR(flag), 'x')) cflag |= PCRE_EXTENDED; 66 | if (STRCHR(RSTRING_PTR(flag), 'm')) cflag |= PCRE_MULTILINE | PCRE_DOTALL; 67 | } 68 | reg->flag = cflag; 69 | reg->re = pcre_compile(RSTRING_PTR(str), cflag, &errstr, &erroff, NULL); 70 | if (!reg->re) { 71 | mrb_raisef(mrb, E_ARGUMENT_ERROR, "'%S' is an invalid regular expression because %S.", 72 | mrb_str_new_cstr(mrb, RSTRING_PTR(str) + erroff), mrb_str_new_cstr(mrb, errstr)); 73 | } 74 | mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "@source"), str); 75 | } 76 | 77 | static mrb_value 78 | pcre_regexp_initialize(mrb_state *mrb, mrb_value self) { 79 | mrb_value source, flag = mrb_nil_value(); 80 | 81 | mrb_get_args(mrb, "S|o", &source, &flag); 82 | pcre_regexp_init(mrb, self, source, flag); 83 | return mrb_nil_value(); 84 | } 85 | 86 | static mrb_value 87 | pcre_regexp_initialize_copy(mrb_state *mrb, mrb_value copy) { 88 | mrb_value regexp; 89 | struct mrb_pcre_regexp *reg; 90 | 91 | mrb_get_args(mrb, "o", ®exp); 92 | if (mrb_obj_equal(mrb, copy, regexp)){ 93 | return copy; 94 | } 95 | if (!mrb_obj_is_instance_of(mrb, regexp, mrb_obj_class(mrb, copy))){ 96 | mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class"); 97 | } 98 | 99 | Data_Get_Struct(mrb, regexp, &mrb_pcre_regexp_type, reg); 100 | pcre_regexp_init(mrb, copy, mrb_funcall_argv(mrb, regexp, mrb_intern_lit(mrb, "source"), 0, NULL), mrb_fixnum_value(reg->flag)); 101 | return copy; 102 | } 103 | static mrb_value 104 | pcre_regexp_match(mrb_state *mrb, mrb_value self) { 105 | const char *str; 106 | char global_match[3]; 107 | mrb_value regexp; 108 | struct mrb_pcre_regexp *reg; 109 | int i; 110 | mrb_value mrb_i, mrb_match; 111 | size_t nmatch = 999; 112 | int match[999]; 113 | int regno; 114 | int ai; 115 | struct RClass* clazz; 116 | mrb_value c; 117 | mrb_value args[2]; 118 | 119 | mrb_get_args(mrb, "z", &str); 120 | 121 | regexp = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@regexp")); 122 | Data_Get_Struct(mrb, regexp, &mrb_pcre_regexp_type, reg); 123 | 124 | regno = pcre_exec(reg->re, NULL, str, strlen(str), 0, 0, match, nmatch); 125 | if (regno < 0) 126 | return mrb_nil_value(); 127 | 128 | mrb_obj_iv_set(mrb, (struct RObject *)mrb_class_real(RDATA(self)->c), mrb_intern_lit(mrb, "@last_match"), mrb_nil_value()); 129 | 130 | ai = mrb_gc_arena_save(mrb); 131 | clazz = mrb_class_get(mrb, "PcreMatchData"); 132 | c = mrb_obj_new(mrb, clazz, 0, NULL); 133 | mrb_iv_set(mrb, c,mrb_intern_lit(mrb, "@string"), mrb_str_new_cstr(mrb, str)); 134 | 135 | for (i = 0; i < regno; i++) { 136 | args[0] = mrb_fixnum_value(match[i * 2]); 137 | args[1] = mrb_fixnum_value(match[i * 2 + 1] - match[i * 2]); 138 | mrb_funcall_argv(mrb, c, mrb_intern_lit(mrb, "push"), sizeof(args)/sizeof(args[0]), &args[0]); 139 | if (i > 0 && i < 10) { 140 | sprintf(global_match, "$%i", i); 141 | mrb_i = mrb_fixnum_value(i); 142 | mrb_match = mrb_funcall_argv(mrb, c, mrb_intern_lit(mrb, "[]"), 1, &mrb_i); 143 | mrb_gv_set(mrb, mrb_intern_cstr(mrb, global_match), mrb_match); 144 | } 145 | mrb_gc_arena_restore(mrb, ai); 146 | } 147 | 148 | mrb_obj_iv_set(mrb, (struct RObject *)mrb_class_real(RDATA(self)->c), mrb_intern_lit(mrb, "@last_match"), c); 149 | return c; 150 | } 151 | 152 | static mrb_value 153 | pcre_regexp_equal(mrb_state *mrb, mrb_value self) { 154 | mrb_value other, regexp_self, regexp_other; 155 | struct mrb_pcre_regexp *self_reg, *other_reg; 156 | 157 | mrb_get_args(mrb, "o", &other); 158 | if (mrb_obj_equal(mrb, self, other)){ 159 | return mrb_true_value(); 160 | } 161 | if (mrb_nil_p(other)) { 162 | return mrb_false_value(); 163 | } 164 | regexp_self = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@regexp")); 165 | regexp_other = mrb_iv_get(mrb, other, mrb_intern_lit(mrb, "@regexp")); 166 | Data_Get_Struct(mrb, regexp_self, &mrb_pcre_regexp_type, self_reg); 167 | Data_Get_Struct(mrb, regexp_other, &mrb_pcre_regexp_type, other_reg); 168 | 169 | if (!self_reg || !other_reg){ 170 | mrb_raise(mrb, E_RUNTIME_ERROR, "Invalid PcreRegexp"); 171 | } 172 | if (self_reg->flag != other_reg->flag){ 173 | return mrb_false_value(); 174 | } 175 | return mrb_str_equal(mrb, mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@source")), mrb_iv_get(mrb, other, mrb_intern_lit(mrb, "@source"))) ? 176 | mrb_true_value() : mrb_false_value(); 177 | } 178 | 179 | static mrb_value 180 | pcre_regexp_casefold_p(mrb_state *mrb, mrb_value self) { 181 | mrb_value regexp; 182 | struct mrb_pcre_regexp *reg; 183 | 184 | regexp = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@regexp")); 185 | Data_Get_Struct(mrb, regexp, &mrb_pcre_regexp_type, reg); 186 | return (reg->flag & PCRE_CASELESS) ? mrb_true_value() : mrb_false_value(); 187 | } 188 | 189 | void 190 | mrb_mruby_pcre_regexp_gem_init(mrb_state* mrb) { 191 | struct RClass *clazz; 192 | 193 | clazz = mrb_define_class(mrb, "PcreRegexp", mrb->object_class); 194 | 195 | mrb_define_const(mrb, clazz, "IGNORECASE", mrb_fixnum_value(1)); 196 | mrb_define_const(mrb, clazz, "EXTENDED", mrb_fixnum_value(2)); 197 | mrb_define_const(mrb, clazz, "MULTILINE", mrb_fixnum_value(4)); 198 | 199 | mrb_define_method(mrb, clazz, "initialize", pcre_regexp_initialize, MRB_ARGS_REQ(1) | MRB_ARGS_OPT(2)); 200 | mrb_define_method(mrb, clazz, "initialize_copy", pcre_regexp_initialize_copy, MRB_ARGS_REQ(1)); 201 | mrb_define_method(mrb, clazz, "==", pcre_regexp_equal, MRB_ARGS_REQ(1)); 202 | mrb_define_method(mrb, clazz, "match", pcre_regexp_match, MRB_ARGS_REQ(1)); 203 | mrb_define_method(mrb, clazz, "casefold?", pcre_regexp_casefold_p, MRB_ARGS_NONE()); 204 | } 205 | 206 | void 207 | mrb_mruby_pcre_regexp_gem_final(mrb_state* mrb) { 208 | } 209 | 210 | // vim:set et: 211 | -------------------------------------------------------------------------------- /src/pcre.h: -------------------------------------------------------------------------------- 1 | /************************************************* 2 | * Perl-Compatible Regular Expressions * 3 | *************************************************/ 4 | 5 | /* This is the public header file for the PCRE library, to be #included by 6 | applications that call the PCRE functions. 7 | 8 | Copyright (c) 1997-2012 University of Cambridge 9 | 10 | ----------------------------------------------------------------------------- 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | 14 | * Redistributions of source code must retain the above copyright notice, 15 | this list of conditions and the following disclaimer. 16 | 17 | * Redistributions in binary form must reproduce the above copyright 18 | notice, this list of conditions and the following disclaimer in the 19 | documentation and/or other materials provided with the distribution. 20 | 21 | * Neither the name of the University of Cambridge nor the names of its 22 | contributors may be used to endorse or promote products derived from 23 | this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 29 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 | POSSIBILITY OF SUCH DAMAGE. 36 | ----------------------------------------------------------------------------- 37 | */ 38 | 39 | #ifndef _PCRE_H 40 | #define _PCRE_H 41 | 42 | /* The current PCRE version information. */ 43 | 44 | #define PCRE_MAJOR 8 45 | #define PCRE_MINOR 31 46 | #define PCRE_PRERELEASE 47 | #define PCRE_DATE 2012-07-06 48 | 49 | /* When an application links to a PCRE DLL in Windows, the symbols that are 50 | imported have to be identified as such. When building PCRE, the appropriate 51 | export setting is defined in pcre_internal.h, which includes this file. So we 52 | don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */ 53 | 54 | #if defined(_WIN32) && !defined(PCRE_STATIC) 55 | # ifndef PCRE_EXP_DECL 56 | # define PCRE_EXP_DECL extern __declspec(dllimport) 57 | # endif 58 | # ifdef __cplusplus 59 | # ifndef PCRECPP_EXP_DECL 60 | # define PCRECPP_EXP_DECL extern __declspec(dllimport) 61 | # endif 62 | # ifndef PCRECPP_EXP_DEFN 63 | # define PCRECPP_EXP_DEFN __declspec(dllimport) 64 | # endif 65 | # endif 66 | #endif 67 | 68 | /* By default, we use the standard "extern" declarations. */ 69 | 70 | #ifndef PCRE_EXP_DECL 71 | # ifdef __cplusplus 72 | # define PCRE_EXP_DECL extern "C" 73 | # else 74 | # define PCRE_EXP_DECL extern 75 | # endif 76 | #endif 77 | 78 | #ifdef __cplusplus 79 | # ifndef PCRECPP_EXP_DECL 80 | # define PCRECPP_EXP_DECL extern 81 | # endif 82 | # ifndef PCRECPP_EXP_DEFN 83 | # define PCRECPP_EXP_DEFN 84 | # endif 85 | #endif 86 | 87 | /* Have to include stdlib.h in order to ensure that size_t is defined; 88 | it is needed here for malloc. */ 89 | 90 | #include 91 | 92 | /* Allow for C++ users */ 93 | 94 | #ifdef __cplusplus 95 | extern "C" { 96 | #endif 97 | 98 | /* Options. Some are compile-time only, some are run-time only, and some are 99 | both, so we keep them all distinct. However, almost all the bits in the options 100 | word are now used. In the long run, we may have to re-use some of the 101 | compile-time only bits for runtime options, or vice versa. In the comments 102 | below, "compile", "exec", and "DFA exec" mean that the option is permitted to 103 | be set for those functions; "used in" means that an option may be set only for 104 | compile, but is subsequently referenced in exec and/or DFA exec. Any of the 105 | compile-time options may be inspected during studying (and therefore JIT 106 | compiling). */ 107 | 108 | #define PCRE_CASELESS 0x00000001 /* Compile */ 109 | #define PCRE_MULTILINE 0x00000002 /* Compile */ 110 | #define PCRE_DOTALL 0x00000004 /* Compile */ 111 | #define PCRE_EXTENDED 0x00000008 /* Compile */ 112 | #define PCRE_ANCHORED 0x00000010 /* Compile, exec, DFA exec */ 113 | #define PCRE_DOLLAR_ENDONLY 0x00000020 /* Compile, used in exec, DFA exec */ 114 | #define PCRE_EXTRA 0x00000040 /* Compile */ 115 | #define PCRE_NOTBOL 0x00000080 /* Exec, DFA exec */ 116 | #define PCRE_NOTEOL 0x00000100 /* Exec, DFA exec */ 117 | #define PCRE_UNGREEDY 0x00000200 /* Compile */ 118 | #define PCRE_NOTEMPTY 0x00000400 /* Exec, DFA exec */ 119 | /* The next two are also used in exec and DFA exec */ 120 | #define PCRE_UTF8 0x00000800 /* Compile (same as PCRE_UTF16) */ 121 | #define PCRE_UTF16 0x00000800 /* Compile (same as PCRE_UTF8) */ 122 | #define PCRE_NO_AUTO_CAPTURE 0x00001000 /* Compile */ 123 | /* The next two are also used in exec and DFA exec */ 124 | #define PCRE_NO_UTF8_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF16_CHECK) */ 125 | #define PCRE_NO_UTF16_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF8_CHECK) */ 126 | #define PCRE_AUTO_CALLOUT 0x00004000 /* Compile */ 127 | #define PCRE_PARTIAL_SOFT 0x00008000 /* Exec, DFA exec */ 128 | #define PCRE_PARTIAL 0x00008000 /* Backwards compatible synonym */ 129 | #define PCRE_DFA_SHORTEST 0x00010000 /* DFA exec */ 130 | #define PCRE_DFA_RESTART 0x00020000 /* DFA exec */ 131 | #define PCRE_FIRSTLINE 0x00040000 /* Compile, used in exec, DFA exec */ 132 | #define PCRE_DUPNAMES 0x00080000 /* Compile */ 133 | #define PCRE_NEWLINE_CR 0x00100000 /* Compile, exec, DFA exec */ 134 | #define PCRE_NEWLINE_LF 0x00200000 /* Compile, exec, DFA exec */ 135 | #define PCRE_NEWLINE_CRLF 0x00300000 /* Compile, exec, DFA exec */ 136 | #define PCRE_NEWLINE_ANY 0x00400000 /* Compile, exec, DFA exec */ 137 | #define PCRE_NEWLINE_ANYCRLF 0x00500000 /* Compile, exec, DFA exec */ 138 | #define PCRE_BSR_ANYCRLF 0x00800000 /* Compile, exec, DFA exec */ 139 | #define PCRE_BSR_UNICODE 0x01000000 /* Compile, exec, DFA exec */ 140 | #define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* Compile, used in exec */ 141 | #define PCRE_NO_START_OPTIMIZE 0x04000000 /* Compile, exec, DFA exec */ 142 | #define PCRE_NO_START_OPTIMISE 0x04000000 /* Synonym */ 143 | #define PCRE_PARTIAL_HARD 0x08000000 /* Exec, DFA exec */ 144 | #define PCRE_NOTEMPTY_ATSTART 0x10000000 /* Exec, DFA exec */ 145 | #define PCRE_UCP 0x20000000 /* Compile, used in exec, DFA exec */ 146 | 147 | /* Exec-time and get/set-time error codes */ 148 | 149 | #define PCRE_ERROR_NOMATCH (-1) 150 | #define PCRE_ERROR_NULL (-2) 151 | #define PCRE_ERROR_BADOPTION (-3) 152 | #define PCRE_ERROR_BADMAGIC (-4) 153 | #define PCRE_ERROR_UNKNOWN_OPCODE (-5) 154 | #define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */ 155 | #define PCRE_ERROR_NOMEMORY (-6) 156 | #define PCRE_ERROR_NOSUBSTRING (-7) 157 | #define PCRE_ERROR_MATCHLIMIT (-8) 158 | #define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */ 159 | #define PCRE_ERROR_BADUTF8 (-10) /* Same for 8/16 */ 160 | #define PCRE_ERROR_BADUTF16 (-10) /* Same for 8/16 */ 161 | #define PCRE_ERROR_BADUTF8_OFFSET (-11) /* Same for 8/16 */ 162 | #define PCRE_ERROR_BADUTF16_OFFSET (-11) /* Same for 8/16 */ 163 | #define PCRE_ERROR_PARTIAL (-12) 164 | #define PCRE_ERROR_BADPARTIAL (-13) 165 | #define PCRE_ERROR_INTERNAL (-14) 166 | #define PCRE_ERROR_BADCOUNT (-15) 167 | #define PCRE_ERROR_DFA_UITEM (-16) 168 | #define PCRE_ERROR_DFA_UCOND (-17) 169 | #define PCRE_ERROR_DFA_UMLIMIT (-18) 170 | #define PCRE_ERROR_DFA_WSSIZE (-19) 171 | #define PCRE_ERROR_DFA_RECURSE (-20) 172 | #define PCRE_ERROR_RECURSIONLIMIT (-21) 173 | #define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */ 174 | #define PCRE_ERROR_BADNEWLINE (-23) 175 | #define PCRE_ERROR_BADOFFSET (-24) 176 | #define PCRE_ERROR_SHORTUTF8 (-25) 177 | #define PCRE_ERROR_SHORTUTF16 (-25) /* Same for 8/16 */ 178 | #define PCRE_ERROR_RECURSELOOP (-26) 179 | #define PCRE_ERROR_JIT_STACKLIMIT (-27) 180 | #define PCRE_ERROR_BADMODE (-28) 181 | #define PCRE_ERROR_BADENDIANNESS (-29) 182 | #define PCRE_ERROR_DFA_BADRESTART (-30) 183 | 184 | /* Specific error codes for UTF-8 validity checks */ 185 | 186 | #define PCRE_UTF8_ERR0 0 187 | #define PCRE_UTF8_ERR1 1 188 | #define PCRE_UTF8_ERR2 2 189 | #define PCRE_UTF8_ERR3 3 190 | #define PCRE_UTF8_ERR4 4 191 | #define PCRE_UTF8_ERR5 5 192 | #define PCRE_UTF8_ERR6 6 193 | #define PCRE_UTF8_ERR7 7 194 | #define PCRE_UTF8_ERR8 8 195 | #define PCRE_UTF8_ERR9 9 196 | #define PCRE_UTF8_ERR10 10 197 | #define PCRE_UTF8_ERR11 11 198 | #define PCRE_UTF8_ERR12 12 199 | #define PCRE_UTF8_ERR13 13 200 | #define PCRE_UTF8_ERR14 14 201 | #define PCRE_UTF8_ERR15 15 202 | #define PCRE_UTF8_ERR16 16 203 | #define PCRE_UTF8_ERR17 17 204 | #define PCRE_UTF8_ERR18 18 205 | #define PCRE_UTF8_ERR19 19 206 | #define PCRE_UTF8_ERR20 20 207 | #define PCRE_UTF8_ERR21 21 208 | 209 | /* Specific error codes for UTF-16 validity checks */ 210 | 211 | #define PCRE_UTF16_ERR0 0 212 | #define PCRE_UTF16_ERR1 1 213 | #define PCRE_UTF16_ERR2 2 214 | #define PCRE_UTF16_ERR3 3 215 | #define PCRE_UTF16_ERR4 4 216 | 217 | /* Request types for pcre_fullinfo() */ 218 | 219 | #define PCRE_INFO_OPTIONS 0 220 | #define PCRE_INFO_SIZE 1 221 | #define PCRE_INFO_CAPTURECOUNT 2 222 | #define PCRE_INFO_BACKREFMAX 3 223 | #define PCRE_INFO_FIRSTBYTE 4 224 | #define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */ 225 | #define PCRE_INFO_FIRSTTABLE 5 226 | #define PCRE_INFO_LASTLITERAL 6 227 | #define PCRE_INFO_NAMEENTRYSIZE 7 228 | #define PCRE_INFO_NAMECOUNT 8 229 | #define PCRE_INFO_NAMETABLE 9 230 | #define PCRE_INFO_STUDYSIZE 10 231 | #define PCRE_INFO_DEFAULT_TABLES 11 232 | #define PCRE_INFO_OKPARTIAL 12 233 | #define PCRE_INFO_JCHANGED 13 234 | #define PCRE_INFO_HASCRORLF 14 235 | #define PCRE_INFO_MINLENGTH 15 236 | #define PCRE_INFO_JIT 16 237 | #define PCRE_INFO_JITSIZE 17 238 | #define PCRE_INFO_MAXLOOKBEHIND 18 239 | 240 | /* Request types for pcre_config(). Do not re-arrange, in order to remain 241 | compatible. */ 242 | 243 | #define PCRE_CONFIG_UTF8 0 244 | #define PCRE_CONFIG_NEWLINE 1 245 | #define PCRE_CONFIG_LINK_SIZE 2 246 | #define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3 247 | #define PCRE_CONFIG_MATCH_LIMIT 4 248 | #define PCRE_CONFIG_STACKRECURSE 5 249 | #define PCRE_CONFIG_UNICODE_PROPERTIES 6 250 | #define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7 251 | #define PCRE_CONFIG_BSR 8 252 | #define PCRE_CONFIG_JIT 9 253 | #define PCRE_CONFIG_UTF16 10 254 | #define PCRE_CONFIG_JITTARGET 11 255 | 256 | /* Request types for pcre_study(). Do not re-arrange, in order to remain 257 | compatible. */ 258 | 259 | #define PCRE_STUDY_JIT_COMPILE 0x0001 260 | #define PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE 0x0002 261 | #define PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE 0x0004 262 | 263 | /* Bit flags for the pcre[16]_extra structure. Do not re-arrange or redefine 264 | these bits, just add new ones on the end, in order to remain compatible. */ 265 | 266 | #define PCRE_EXTRA_STUDY_DATA 0x0001 267 | #define PCRE_EXTRA_MATCH_LIMIT 0x0002 268 | #define PCRE_EXTRA_CALLOUT_DATA 0x0004 269 | #define PCRE_EXTRA_TABLES 0x0008 270 | #define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010 271 | #define PCRE_EXTRA_MARK 0x0020 272 | #define PCRE_EXTRA_EXECUTABLE_JIT 0x0040 273 | 274 | /* Types */ 275 | 276 | struct real_pcre; /* declaration; the definition is private */ 277 | typedef struct real_pcre pcre; 278 | 279 | struct real_pcre16; /* declaration; the definition is private */ 280 | typedef struct real_pcre16 pcre16; 281 | 282 | struct real_pcre_jit_stack; /* declaration; the definition is private */ 283 | typedef struct real_pcre_jit_stack pcre_jit_stack; 284 | 285 | struct real_pcre16_jit_stack; /* declaration; the definition is private */ 286 | typedef struct real_pcre16_jit_stack pcre16_jit_stack; 287 | 288 | /* If PCRE is compiled with 16 bit character support, PCRE_UCHAR16 must contain 289 | a 16 bit wide signed data type. Otherwise it can be a dummy data type since 290 | pcre16 functions are not implemented. There is a check for this in pcre_internal.h. */ 291 | #ifndef PCRE_UCHAR16 292 | #define PCRE_UCHAR16 unsigned short 293 | #endif 294 | 295 | #ifndef PCRE_SPTR16 296 | #define PCRE_SPTR16 const PCRE_UCHAR16 * 297 | #endif 298 | 299 | /* When PCRE is compiled as a C++ library, the subject pointer type can be 300 | replaced with a custom type. For conventional use, the public interface is a 301 | const char *. */ 302 | 303 | #ifndef PCRE_SPTR 304 | #define PCRE_SPTR const char * 305 | #endif 306 | 307 | /* The structure for passing additional data to pcre_exec(). This is defined in 308 | such as way as to be extensible. Always add new fields at the end, in order to 309 | remain compatible. */ 310 | 311 | typedef struct pcre_extra { 312 | unsigned long int flags; /* Bits for which fields are set */ 313 | void *study_data; /* Opaque data from pcre_study() */ 314 | unsigned long int match_limit; /* Maximum number of calls to match() */ 315 | void *callout_data; /* Data passed back in callouts */ 316 | const unsigned char *tables; /* Pointer to character tables */ 317 | unsigned long int match_limit_recursion; /* Max recursive calls to match() */ 318 | unsigned char **mark; /* For passing back a mark pointer */ 319 | void *executable_jit; /* Contains a pointer to a compiled jit code */ 320 | } pcre_extra; 321 | 322 | /* Same structure as above, but with 16 bit char pointers. */ 323 | 324 | typedef struct pcre16_extra { 325 | unsigned long int flags; /* Bits for which fields are set */ 326 | void *study_data; /* Opaque data from pcre_study() */ 327 | unsigned long int match_limit; /* Maximum number of calls to match() */ 328 | void *callout_data; /* Data passed back in callouts */ 329 | const unsigned char *tables; /* Pointer to character tables */ 330 | unsigned long int match_limit_recursion; /* Max recursive calls to match() */ 331 | PCRE_UCHAR16 **mark; /* For passing back a mark pointer */ 332 | void *executable_jit; /* Contains a pointer to a compiled jit code */ 333 | } pcre16_extra; 334 | 335 | /* The structure for passing out data via the pcre_callout_function. We use a 336 | structure so that new fields can be added on the end in future versions, 337 | without changing the API of the function, thereby allowing old clients to work 338 | without modification. */ 339 | 340 | typedef struct pcre_callout_block { 341 | int version; /* Identifies version of block */ 342 | /* ------------------------ Version 0 ------------------------------- */ 343 | int callout_number; /* Number compiled into pattern */ 344 | int *offset_vector; /* The offset vector */ 345 | PCRE_SPTR subject; /* The subject being matched */ 346 | int subject_length; /* The length of the subject */ 347 | int start_match; /* Offset to start of this match attempt */ 348 | int current_position; /* Where we currently are in the subject */ 349 | int capture_top; /* Max current capture */ 350 | int capture_last; /* Most recently closed capture */ 351 | void *callout_data; /* Data passed in with the call */ 352 | /* ------------------- Added for Version 1 -------------------------- */ 353 | int pattern_position; /* Offset to next item in the pattern */ 354 | int next_item_length; /* Length of next item in the pattern */ 355 | /* ------------------- Added for Version 2 -------------------------- */ 356 | const unsigned char *mark; /* Pointer to current mark or NULL */ 357 | /* ------------------------------------------------------------------ */ 358 | } pcre_callout_block; 359 | 360 | /* Same structure as above, but with 16 bit char pointers. */ 361 | 362 | typedef struct pcre16_callout_block { 363 | int version; /* Identifies version of block */ 364 | /* ------------------------ Version 0 ------------------------------- */ 365 | int callout_number; /* Number compiled into pattern */ 366 | int *offset_vector; /* The offset vector */ 367 | PCRE_SPTR16 subject; /* The subject being matched */ 368 | int subject_length; /* The length of the subject */ 369 | int start_match; /* Offset to start of this match attempt */ 370 | int current_position; /* Where we currently are in the subject */ 371 | int capture_top; /* Max current capture */ 372 | int capture_last; /* Most recently closed capture */ 373 | void *callout_data; /* Data passed in with the call */ 374 | /* ------------------- Added for Version 1 -------------------------- */ 375 | int pattern_position; /* Offset to next item in the pattern */ 376 | int next_item_length; /* Length of next item in the pattern */ 377 | /* ------------------- Added for Version 2 -------------------------- */ 378 | const PCRE_UCHAR16 *mark; /* Pointer to current mark or NULL */ 379 | /* ------------------------------------------------------------------ */ 380 | } pcre16_callout_block; 381 | 382 | /* Indirection for store get and free functions. These can be set to 383 | alternative malloc/free functions if required. Special ones are used in the 384 | non-recursive case for "frames". There is also an optional callout function 385 | that is triggered by the (?) regex item. For Virtual Pascal, these definitions 386 | have to take another form. */ 387 | 388 | #ifndef VPCOMPAT 389 | PCRE_EXP_DECL void *(*pcre_malloc)(size_t); 390 | PCRE_EXP_DECL void (*pcre_free)(void *); 391 | PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t); 392 | PCRE_EXP_DECL void (*pcre_stack_free)(void *); 393 | PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *); 394 | 395 | PCRE_EXP_DECL void *(*pcre16_malloc)(size_t); 396 | PCRE_EXP_DECL void (*pcre16_free)(void *); 397 | PCRE_EXP_DECL void *(*pcre16_stack_malloc)(size_t); 398 | PCRE_EXP_DECL void (*pcre16_stack_free)(void *); 399 | PCRE_EXP_DECL int (*pcre16_callout)(pcre16_callout_block *); 400 | #else /* VPCOMPAT */ 401 | PCRE_EXP_DECL void *pcre_malloc(size_t); 402 | PCRE_EXP_DECL void pcre_free(void *); 403 | PCRE_EXP_DECL void *pcre_stack_malloc(size_t); 404 | PCRE_EXP_DECL void pcre_stack_free(void *); 405 | PCRE_EXP_DECL int pcre_callout(pcre_callout_block *); 406 | 407 | PCRE_EXP_DECL void *pcre16_malloc(size_t); 408 | PCRE_EXP_DECL void pcre16_free(void *); 409 | PCRE_EXP_DECL void *pcre16_stack_malloc(size_t); 410 | PCRE_EXP_DECL void pcre16_stack_free(void *); 411 | PCRE_EXP_DECL int pcre16_callout(pcre16_callout_block *); 412 | #endif /* VPCOMPAT */ 413 | 414 | /* User defined callback which provides a stack just before the match starts. */ 415 | 416 | typedef pcre_jit_stack *(*pcre_jit_callback)(void *); 417 | typedef pcre16_jit_stack *(*pcre16_jit_callback)(void *); 418 | 419 | /* Exported PCRE functions */ 420 | 421 | PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *, 422 | const unsigned char *); 423 | PCRE_EXP_DECL pcre16 *pcre16_compile(PCRE_SPTR16, int, const char **, int *, 424 | const unsigned char *); 425 | PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **, 426 | int *, const unsigned char *); 427 | PCRE_EXP_DECL pcre16 *pcre16_compile2(PCRE_SPTR16, int, int *, const char **, 428 | int *, const unsigned char *); 429 | PCRE_EXP_DECL int pcre_config(int, void *); 430 | PCRE_EXP_DECL int pcre16_config(int, void *); 431 | PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *, 432 | int *, int, const char *, char *, int); 433 | PCRE_EXP_DECL int pcre16_copy_named_substring(const pcre16 *, PCRE_SPTR16, 434 | int *, int, PCRE_SPTR16, PCRE_UCHAR16 *, int); 435 | PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int, 436 | char *, int); 437 | PCRE_EXP_DECL int pcre16_copy_substring(PCRE_SPTR16, int *, int, int, 438 | PCRE_UCHAR16 *, int); 439 | PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *, 440 | const char *, int, int, int, int *, int , int *, int); 441 | PCRE_EXP_DECL int pcre16_dfa_exec(const pcre16 *, const pcre16_extra *, 442 | PCRE_SPTR16, int, int, int, int *, int , int *, int); 443 | PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR, 444 | int, int, int, int *, int); 445 | PCRE_EXP_DECL int pcre16_exec(const pcre16 *, const pcre16_extra *, 446 | PCRE_SPTR16, int, int, int, int *, int); 447 | PCRE_EXP_DECL void pcre_free_substring(const char *); 448 | PCRE_EXP_DECL void pcre16_free_substring(PCRE_SPTR16); 449 | PCRE_EXP_DECL void pcre_free_substring_list(const char **); 450 | PCRE_EXP_DECL void pcre16_free_substring_list(PCRE_SPTR16 *); 451 | PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int, 452 | void *); 453 | PCRE_EXP_DECL int pcre16_fullinfo(const pcre16 *, const pcre16_extra *, int, 454 | void *); 455 | PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *, 456 | int *, int, const char *, const char **); 457 | PCRE_EXP_DECL int pcre16_get_named_substring(const pcre16 *, PCRE_SPTR16, 458 | int *, int, PCRE_SPTR16, PCRE_SPTR16 *); 459 | PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *); 460 | PCRE_EXP_DECL int pcre16_get_stringnumber(const pcre16 *, PCRE_SPTR16); 461 | PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *, 462 | char **, char **); 463 | PCRE_EXP_DECL int pcre16_get_stringtable_entries(const pcre16 *, PCRE_SPTR16, 464 | PCRE_UCHAR16 **, PCRE_UCHAR16 **); 465 | PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int, 466 | const char **); 467 | PCRE_EXP_DECL int pcre16_get_substring(PCRE_SPTR16, int *, int, int, 468 | PCRE_SPTR16 *); 469 | PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int, 470 | const char ***); 471 | PCRE_EXP_DECL int pcre16_get_substring_list(PCRE_SPTR16, int *, int, 472 | PCRE_SPTR16 **); 473 | PCRE_EXP_DECL const unsigned char *pcre_maketables(void); 474 | PCRE_EXP_DECL const unsigned char *pcre16_maketables(void); 475 | PCRE_EXP_DECL int pcre_refcount(pcre *, int); 476 | PCRE_EXP_DECL int pcre16_refcount(pcre16 *, int); 477 | PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **); 478 | PCRE_EXP_DECL pcre16_extra *pcre16_study(const pcre16 *, int, const char **); 479 | PCRE_EXP_DECL void pcre_free_study(pcre_extra *); 480 | PCRE_EXP_DECL void pcre16_free_study(pcre16_extra *); 481 | PCRE_EXP_DECL const char *pcre_version(void); 482 | PCRE_EXP_DECL const char *pcre16_version(void); 483 | 484 | /* Utility functions for byte order swaps. */ 485 | PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *, pcre_extra *, 486 | const unsigned char *); 487 | PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *, pcre16_extra *, 488 | const unsigned char *); 489 | PCRE_EXP_DECL int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *, 490 | PCRE_SPTR16, int, int *, int); 491 | 492 | /* JIT compiler related functions. */ 493 | 494 | PCRE_EXP_DECL pcre_jit_stack *pcre_jit_stack_alloc(int, int); 495 | PCRE_EXP_DECL pcre16_jit_stack *pcre16_jit_stack_alloc(int, int); 496 | PCRE_EXP_DECL void pcre_jit_stack_free(pcre_jit_stack *); 497 | PCRE_EXP_DECL void pcre16_jit_stack_free(pcre16_jit_stack *); 498 | PCRE_EXP_DECL void pcre_assign_jit_stack(pcre_extra *, 499 | pcre_jit_callback, void *); 500 | PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *, 501 | pcre16_jit_callback, void *); 502 | 503 | #ifdef __cplusplus 504 | } /* extern "C" */ 505 | #endif 506 | 507 | #endif /* End of pcre.h */ 508 | --------------------------------------------------------------------------------