STATIC mp_obj_t re_exec(bool is_anchored, uint n_args, const mp_obj_t *args) { mp_obj_re_t *self = args[0]; Subject subj; mp_uint_t len; subj.begin = mp_obj_str_get_data(args[1], &len); subj.end = subj.begin + len; int caps_num = (self->re.sub + 1) * 2; mp_obj_match_t *match = m_new_obj_var(mp_obj_match_t, char*, caps_num); int res = re1_5_recursiveloopprog(&self->re, &subj, match->caps, caps_num, is_anchored); if (res == 0) { m_del_var(mp_obj_match_t, char*, caps_num, match); return mp_const_none; } match->base.type = &match_type; match->num_matches = caps_num; match->str = args[1]; return match; }
STATIC mp_obj_t re_split(mp_uint_t n_args, const mp_obj_t *args) { mp_obj_re_t *self = MP_OBJ_TO_PTR(args[0]); Subject subj; mp_uint_t len; subj.begin = mp_obj_str_get_data(args[1], &len); subj.end = subj.begin + len; int caps_num = (self->re.sub + 1) * 2; int maxsplit = 0; if (n_args > 2) { maxsplit = mp_obj_get_int(args[2]); } mp_obj_t retval = mp_obj_new_list(0, NULL); const char **caps = alloca(caps_num * sizeof(char*)); while (true) { // cast is a workaround for a bug in msvc: it treats const char** as a const pointer instead of a pointer to pointer to const char memset((char**)caps, 0, caps_num * sizeof(char*)); int res = re1_5_recursiveloopprog(&self->re, &subj, caps, caps_num, false); // if we didn't have a match, or had an empty match, it's time to stop if (!res || caps[0] == caps[1]) { break; } mp_obj_t s = mp_obj_new_str(subj.begin, caps[0] - subj.begin, false); mp_obj_list_append(retval, s); if (self->re.sub > 0) { mp_not_implemented("Splitting with sub-captures"); } subj.begin = caps[1]; if (maxsplit > 0 && --maxsplit == 0) { break; } } mp_obj_t s = mp_obj_new_str(subj.begin, subj.end - subj.begin, false); mp_obj_list_append(retval, s); return retval; }
STATIC mp_obj_t re_exec(bool is_anchored, uint n_args, const mp_obj_t *args) { (void)n_args; mp_obj_re_t *self = MP_OBJ_TO_PTR(args[0]); Subject subj; mp_uint_t len; subj.begin = mp_obj_str_get_data(args[1], &len); subj.end = subj.begin + len; int caps_num = (self->re.sub + 1) * 2; mp_obj_match_t *match = m_new_obj_var(mp_obj_match_t, char*, caps_num); // cast is a workaround for a bug in msvc: it treats const char** as a const pointer instead of a pointer to pointer to const char memset((char*)match->caps, 0, caps_num * sizeof(char*)); int res = re1_5_recursiveloopprog(&self->re, &subj, match->caps, caps_num, is_anchored); if (res == 0) { m_del_var(mp_obj_match_t, char*, caps_num, match); return mp_const_none; } match->base.type = &match_type; match->num_matches = caps_num / 2; // caps_num counts start and end pointers match->str = args[1]; return MP_OBJ_FROM_PTR(match); }
STATIC mp_obj_t re_split(uint n_args, const mp_obj_t *args) { mp_obj_re_t *self = args[0]; Subject subj; mp_uint_t len; subj.begin = mp_obj_str_get_data(args[1], &len); subj.end = subj.begin + len; int caps_num = (self->re.sub + 1) * 2; int maxsplit = 0; if (n_args > 2) { maxsplit = mp_obj_int_get_truncated(args[2]); } mp_obj_t retval = mp_obj_new_list(0, NULL); const char **caps = alloca(caps_num * sizeof(char*)); while (true) { int res = re1_5_recursiveloopprog(&self->re, &subj, caps, caps_num, false); // if we didn't have a match, or had an empty match, it's time to stop if (!res || caps[0] == caps[1]) { break; } mp_obj_t s = mp_obj_new_str(subj.begin, caps[0] - subj.begin, false); mp_obj_list_append(retval, s); if (self->re.sub > 0) { mp_not_implemented("Splitting with sub-captures"); } subj.begin = caps[1]; if (maxsplit > 0 && --maxsplit == 0) { break; } } mp_obj_t s = mp_obj_new_str(subj.begin, subj.end - subj.begin, false); mp_obj_list_append(retval, s); return retval; }