| 213 | } |
| 214 | |
| 215 | Ref<RegExMatch> RegEx::search(const String &p_subject, int p_offset, int p_end) const { |
| 216 | ERR_FAIL_COND_V(!is_valid(), nullptr); |
| 217 | ERR_FAIL_COND_V_MSG(p_offset < 0, nullptr, "RegEx search offset must be >= 0"); |
| 218 | |
| 219 | Ref<RegExMatch> result = memnew(RegExMatch); |
| 220 | |
| 221 | int length = p_subject.length(); |
| 222 | if (p_end >= 0 && p_end < length) { |
| 223 | length = p_end; |
| 224 | } |
| 225 | |
| 226 | pcre2_code_32 *c = (pcre2_code_32 *)code; |
| 227 | pcre2_general_context_32 *gctx = (pcre2_general_context_32 *)general_ctx; |
| 228 | pcre2_match_context_32 *mctx = pcre2_match_context_create_32(gctx); |
| 229 | PCRE2_SPTR32 s = (PCRE2_SPTR32)p_subject.get_data(); |
| 230 | |
| 231 | pcre2_match_data_32 *match = pcre2_match_data_create_from_pattern_32(c, gctx); |
| 232 | |
| 233 | int res = pcre2_match_32(c, s, length, p_offset, 0, match, mctx); |
| 234 | |
| 235 | if (res < 0) { |
| 236 | pcre2_match_data_free_32(match); |
| 237 | pcre2_match_context_free_32(mctx); |
| 238 | |
| 239 | return nullptr; |
| 240 | } |
| 241 | |
| 242 | uint32_t size = pcre2_get_ovector_count_32(match); |
| 243 | PCRE2_SIZE *ovector = pcre2_get_ovector_pointer_32(match); |
| 244 | |
| 245 | result->data.resize(size); |
| 246 | |
| 247 | for (uint32_t i = 0; i < size; i++) { |
| 248 | result->data.write[i].start = ovector[i * 2]; |
| 249 | result->data.write[i].end = ovector[i * 2 + 1]; |
| 250 | } |
| 251 | |
| 252 | pcre2_match_data_free_32(match); |
| 253 | pcre2_match_context_free_32(mctx); |
| 254 | |
| 255 | result->subject = p_subject; |
| 256 | |
| 257 | uint32_t count; |
| 258 | const char32_t *table; |
| 259 | uint32_t entry_size; |
| 260 | |
| 261 | _pattern_info(PCRE2_INFO_NAMECOUNT, &count); |
| 262 | _pattern_info(PCRE2_INFO_NAMETABLE, &table); |
| 263 | _pattern_info(PCRE2_INFO_NAMEENTRYSIZE, &entry_size); |
| 264 | |
| 265 | for (uint32_t i = 0; i < count; i++) { |
| 266 | char32_t id = table[i * entry_size]; |
| 267 | if (result->data[id].start == -1) { |
| 268 | continue; |
| 269 | } |
| 270 | String name = &table[i * entry_size + 1]; |
| 271 | if (result->names.has(name)) { |
| 272 | continue; |