Refactored the PCRE2 extension plus adding some regex examples using this extension. (0.41.7)
This commit is contained in:
parent
4825007b97
commit
be590414af
17 changed files with 637 additions and 404 deletions
|
|
@ -60,68 +60,7 @@ case OP_PCRE2_FINDALL: {
|
|||
push_value(vm, make_array_from_values(NULL, 0));
|
||||
break;
|
||||
}
|
||||
#ifndef PCRE2_CODE_UNIT_WIDTH
|
||||
#define PCRE2_CODE_UNIT_WIDTH 8
|
||||
#endif
|
||||
#include <pcre2.h>
|
||||
int errorcode;
|
||||
PCRE2_SIZE erroff;
|
||||
uint32_t opt = 0;
|
||||
if (flags & 1) opt |= PCRE2_CASELESS; /* I */
|
||||
if (flags & 2) opt |= PCRE2_MULTILINE; /* M */
|
||||
if (flags & 4) opt |= PCRE2_DOTALL; /* S */
|
||||
if (flags & 8) opt |= PCRE2_UTF; /* U */
|
||||
if (flags & 16) opt |= PCRE2_EXTENDED; /* X */
|
||||
pcre2_code *re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, opt, &errorcode, &erroff, NULL);
|
||||
if (!re) {
|
||||
free(pattern);
|
||||
free(subject);
|
||||
push_value(vm, make_array_from_values(NULL, 0));
|
||||
break;
|
||||
}
|
||||
pcre2_match_data *mdata = pcre2_match_data_create_from_pattern(re, NULL);
|
||||
Value out = make_array_from_values(NULL, 0);
|
||||
size_t subj_len = strlen(subject);
|
||||
size_t start_off = 0;
|
||||
int gcount = 0;
|
||||
while (1) {
|
||||
int rc = pcre2_match(re, (PCRE2_SPTR)subject, (PCRE2_SIZE)subj_len, start_off, 0, mdata, NULL);
|
||||
if (rc <= 0) break;
|
||||
PCRE2_SIZE *ov = pcre2_get_ovector_pointer(mdata);
|
||||
int s0 = (int)ov[0];
|
||||
int e0 = (int)ov[1];
|
||||
/* result map for this match */
|
||||
Value res = make_map_empty();
|
||||
char *full = string_substr(subject, s0, e0 - s0);
|
||||
(void)map_set(&res, "full", make_string(full ? full : ""));
|
||||
if (full) free(full);
|
||||
(void)map_set(&res, "start", make_int(s0));
|
||||
(void)map_set(&res, "end", make_int(e0));
|
||||
Value groups = make_array_from_values(NULL, 0);
|
||||
for (int i = 1; i < rc; ++i) {
|
||||
int s = (int)ov[2 * i];
|
||||
int e = (int)ov[2 * i + 1];
|
||||
char *gstr = (s >= 0 && e >= s) ? string_substr(subject, s, e - s) : NULL;
|
||||
Value gv = make_string(gstr ? gstr : "");
|
||||
if (gstr) free(gstr);
|
||||
(void)array_push(&groups, gv);
|
||||
}
|
||||
(void)map_set(&res, "groups", groups);
|
||||
(void)array_push(&out, res);
|
||||
/* advance start offset; guard against empty match */
|
||||
if (e0 == s0) {
|
||||
if ((size_t)e0 < subj_len) {
|
||||
start_off = e0 + 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
start_off = e0;
|
||||
}
|
||||
gcount = rc;
|
||||
}
|
||||
pcre2_match_data_free(mdata);
|
||||
pcre2_code_free(re);
|
||||
Value out = fun_pcre2_findall(pattern, subject, flags);
|
||||
free(pattern);
|
||||
free(subject);
|
||||
push_value(vm, out);
|
||||
|
|
|
|||
|
|
@ -58,58 +58,7 @@ case OP_PCRE2_MATCH: {
|
|||
push_value(vm, make_nil());
|
||||
break;
|
||||
}
|
||||
#ifndef PCRE2_CODE_UNIT_WIDTH
|
||||
#define PCRE2_CODE_UNIT_WIDTH 8
|
||||
#endif
|
||||
#include <pcre2.h>
|
||||
int errorcode;
|
||||
PCRE2_SIZE erroff;
|
||||
uint32_t opt = 0;
|
||||
if (flags & 1) opt |= PCRE2_CASELESS; /* I */
|
||||
if (flags & 2) opt |= PCRE2_MULTILINE; /* M */
|
||||
if (flags & 4) opt |= PCRE2_DOTALL; /* S */
|
||||
if (flags & 8) opt |= PCRE2_UTF; /* U */
|
||||
if (flags & 16) opt |= PCRE2_EXTENDED; /* X */
|
||||
pcre2_code *re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, opt, &errorcode, &erroff, NULL);
|
||||
if (!re) {
|
||||
free(pattern);
|
||||
free(subject);
|
||||
push_value(vm, make_nil());
|
||||
break;
|
||||
}
|
||||
pcre2_match_data *mdata = pcre2_match_data_create_from_pattern(re, NULL);
|
||||
int rc = pcre2_match(re, (PCRE2_SPTR)subject, (PCRE2_SIZE)strlen(subject), 0, 0, mdata, NULL);
|
||||
if (rc <= 0) {
|
||||
pcre2_match_data_free(mdata);
|
||||
pcre2_code_free(re);
|
||||
free(pattern);
|
||||
free(subject);
|
||||
push_value(vm, make_nil());
|
||||
break;
|
||||
}
|
||||
PCRE2_SIZE *ov = pcre2_get_ovector_pointer(mdata);
|
||||
/* Build result map */
|
||||
Value res = make_map_empty();
|
||||
int start0 = (int)ov[0];
|
||||
int end0 = (int)ov[1];
|
||||
char *full = string_substr(subject, start0, end0 - start0);
|
||||
(void)map_set(&res, "full", make_string(full ? full : ""));
|
||||
if (full) free(full);
|
||||
(void)map_set(&res, "start", make_int(start0));
|
||||
(void)map_set(&res, "end", make_int(end0));
|
||||
/* groups array (excluding group 0) */
|
||||
Value groups = make_array_from_values(NULL, 0);
|
||||
for (int i = 1; i < rc; ++i) {
|
||||
int s = (int)ov[2 * i];
|
||||
int e = (int)ov[2 * i + 1];
|
||||
char *gstr = (s >= 0 && e >= s) ? string_substr(subject, s, e - s) : NULL;
|
||||
Value gv = make_string(gstr ? gstr : "");
|
||||
if (gstr) free(gstr);
|
||||
(void)array_push(&groups, gv);
|
||||
}
|
||||
(void)map_set(&res, "groups", groups);
|
||||
pcre2_match_data_free(mdata);
|
||||
pcre2_code_free(re);
|
||||
Value res = fun_pcre2_match(pattern, subject, flags);
|
||||
free(pattern);
|
||||
free(subject);
|
||||
push_value(vm, res);
|
||||
|
|
|
|||
|
|
@ -53,32 +53,10 @@ case OP_PCRE2_TEST: {
|
|||
push_value(vm, make_int(0));
|
||||
break;
|
||||
}
|
||||
#ifndef PCRE2_CODE_UNIT_WIDTH
|
||||
#define PCRE2_CODE_UNIT_WIDTH 8
|
||||
#endif
|
||||
#include <pcre2.h>
|
||||
int errorcode;
|
||||
PCRE2_SIZE erroff;
|
||||
uint32_t opt = 0;
|
||||
if (flags & 1) opt |= PCRE2_CASELESS; /* I */
|
||||
if (flags & 2) opt |= PCRE2_MULTILINE; /* M */
|
||||
if (flags & 4) opt |= PCRE2_DOTALL; /* S */
|
||||
if (flags & 8) opt |= PCRE2_UTF; /* U */
|
||||
if (flags & 16) opt |= PCRE2_EXTENDED; /* X */
|
||||
pcre2_code *re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, opt, &errorcode, &erroff, NULL);
|
||||
if (!re) {
|
||||
free(pattern);
|
||||
free(subject);
|
||||
push_value(vm, make_int(0));
|
||||
break;
|
||||
}
|
||||
pcre2_match_data *mdata = pcre2_match_data_create_from_pattern(re, NULL);
|
||||
int rc = pcre2_match(re, (PCRE2_SPTR)subject, (PCRE2_SIZE)strlen(subject), 0, 0, mdata, NULL);
|
||||
pcre2_match_data_free(mdata);
|
||||
pcre2_code_free(re);
|
||||
int rc = fun_pcre2_test(pattern, subject, flags);
|
||||
free(pattern);
|
||||
free(subject);
|
||||
push_value(vm, make_int(rc >= 0 ? 1 : 0));
|
||||
push_value(vm, make_int(rc));
|
||||
#else
|
||||
/* pop args and return 0 when PCRE2 disabled */
|
||||
Value a = pop_value(vm);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue