mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Edit Book: Fix groups in replace template being interpreted backwards when search direction is up
This commit is contained in:
parent
b51b73b530
commit
7d172200b3
@ -225,7 +225,7 @@ __all__ = ["compile", "escape", "findall", "finditer", "fullmatch", "match",
|
|||||||
"V0", "VERSION0", "V1", "VERSION1", "X", "VERBOSE", "W", "WORD", "error",
|
"V0", "VERSION0", "V1", "VERSION1", "X", "VERBOSE", "W", "WORD", "error",
|
||||||
"Regex"]
|
"Regex"]
|
||||||
|
|
||||||
__version__ = "2.4.64"
|
__version__ = "2.4.66"
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
# Public interface.
|
# Public interface.
|
||||||
|
@ -11577,6 +11577,8 @@ advance:
|
|||||||
if (try_body) {
|
if (try_body) {
|
||||||
body_status = try_match(state, &node->next_1, state->text_pos,
|
body_status = try_match(state, &node->next_1, state->text_pos,
|
||||||
&next_body_position);
|
&next_body_position);
|
||||||
|
if (body_status < 0)
|
||||||
|
return body_status;
|
||||||
|
|
||||||
if (body_status == RE_ERROR_FAILURE)
|
if (body_status == RE_ERROR_FAILURE)
|
||||||
try_body = FALSE;
|
try_body = FALSE;
|
||||||
@ -11589,6 +11591,8 @@ advance:
|
|||||||
if(try_tail) {
|
if(try_tail) {
|
||||||
tail_status = try_match(state, &node->nonstring.next_2,
|
tail_status = try_match(state, &node->nonstring.next_2,
|
||||||
state->text_pos, &next_tail_position);
|
state->text_pos, &next_tail_position);
|
||||||
|
if (tail_status < 0)
|
||||||
|
return tail_status;
|
||||||
|
|
||||||
if (tail_status == RE_ERROR_FAILURE)
|
if (tail_status == RE_ERROR_FAILURE)
|
||||||
try_tail = FALSE;
|
try_tail = FALSE;
|
||||||
@ -11738,6 +11742,8 @@ advance:
|
|||||||
if (try_body) {
|
if (try_body) {
|
||||||
body_status = try_match(state, &node->next_1, state->text_pos,
|
body_status = try_match(state, &node->next_1, state->text_pos,
|
||||||
&next_body_position);
|
&next_body_position);
|
||||||
|
if (body_status < 0)
|
||||||
|
return body_status;
|
||||||
|
|
||||||
if (body_status == RE_ERROR_FAILURE)
|
if (body_status == RE_ERROR_FAILURE)
|
||||||
try_body = FALSE;
|
try_body = FALSE;
|
||||||
@ -11748,6 +11754,8 @@ advance:
|
|||||||
if (try_tail) {
|
if (try_tail) {
|
||||||
tail_status = try_match(state, &node->nonstring.next_2,
|
tail_status = try_match(state, &node->nonstring.next_2,
|
||||||
state->text_pos, &next_tail_position);
|
state->text_pos, &next_tail_position);
|
||||||
|
if (tail_status < 0)
|
||||||
|
return tail_status;
|
||||||
|
|
||||||
if (tail_status == RE_ERROR_FAILURE)
|
if (tail_status == RE_ERROR_FAILURE)
|
||||||
try_tail = FALSE;
|
try_tail = FALSE;
|
||||||
@ -12029,6 +12037,8 @@ advance:
|
|||||||
if (try_body) {
|
if (try_body) {
|
||||||
body_status = try_match(state, &node->next_1, state->text_pos,
|
body_status = try_match(state, &node->next_1, state->text_pos,
|
||||||
&next_body_position);
|
&next_body_position);
|
||||||
|
if (body_status < 0)
|
||||||
|
return body_status;
|
||||||
|
|
||||||
if (body_status == RE_ERROR_FAILURE)
|
if (body_status == RE_ERROR_FAILURE)
|
||||||
try_body = FALSE;
|
try_body = FALSE;
|
||||||
@ -12039,6 +12049,8 @@ advance:
|
|||||||
if (try_tail) {
|
if (try_tail) {
|
||||||
tail_status = try_match(state, &node->nonstring.next_2,
|
tail_status = try_match(state, &node->nonstring.next_2,
|
||||||
state->text_pos, &next_tail_position);
|
state->text_pos, &next_tail_position);
|
||||||
|
if (tail_status < 0)
|
||||||
|
return tail_status;
|
||||||
|
|
||||||
if (tail_status == RE_ERROR_FAILURE)
|
if (tail_status == RE_ERROR_FAILURE)
|
||||||
try_tail = FALSE;
|
try_tail = FALSE;
|
||||||
@ -12289,6 +12301,8 @@ advance:
|
|||||||
if (try_body) {
|
if (try_body) {
|
||||||
body_status = try_match(state, &node->next_1, state->text_pos,
|
body_status = try_match(state, &node->next_1, state->text_pos,
|
||||||
&next_body_position);
|
&next_body_position);
|
||||||
|
if (body_status < 0)
|
||||||
|
return body_status;
|
||||||
|
|
||||||
if (body_status == RE_ERROR_FAILURE)
|
if (body_status == RE_ERROR_FAILURE)
|
||||||
try_body = FALSE;
|
try_body = FALSE;
|
||||||
@ -12299,6 +12313,8 @@ advance:
|
|||||||
if(try_tail) {
|
if(try_tail) {
|
||||||
tail_status = try_match(state, &node->nonstring.next_2,
|
tail_status = try_match(state, &node->nonstring.next_2,
|
||||||
state->text_pos, &next_tail_position);
|
state->text_pos, &next_tail_position);
|
||||||
|
if (tail_status < 0)
|
||||||
|
return tail_status;
|
||||||
|
|
||||||
if (tail_status == RE_ERROR_FAILURE)
|
if (tail_status == RE_ERROR_FAILURE)
|
||||||
try_tail = FALSE;
|
try_tail = FALSE;
|
||||||
@ -14200,11 +14216,17 @@ backtrack:
|
|||||||
|
|
||||||
if (test->status & RE_STATUS_FUZZY) {
|
if (test->status & RE_STATUS_FUZZY) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
int status;
|
||||||
RE_Position next_position;
|
RE_Position next_position;
|
||||||
|
|
||||||
pos -= step;
|
pos -= step;
|
||||||
|
|
||||||
if (try_match(state, &node->next_1, pos, &next_position) &&
|
status = try_match(state, &node->next_1, pos,
|
||||||
|
&next_position);
|
||||||
|
if (status < 0)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
if (status != RE_ERROR_FAILURE &&
|
||||||
!is_repeat_guarded(safe_state, index, pos,
|
!is_repeat_guarded(safe_state, index, pos,
|
||||||
RE_STATUS_TAIL)) {
|
RE_STATUS_TAIL)) {
|
||||||
match = TRUE;
|
match = TRUE;
|
||||||
@ -15742,6 +15764,14 @@ Py_LOCAL_INLINE(int) do_match(RE_SafeState* safe_state, BOOL search) {
|
|||||||
state->lastgroup = -1;
|
state->lastgroup = -1;
|
||||||
max_end_index = -1;
|
max_end_index = -1;
|
||||||
|
|
||||||
|
if (status == RE_ERROR_PARTIAL) {
|
||||||
|
/* We've matched up to the limit of the slice. */
|
||||||
|
if (state->reverse)
|
||||||
|
state->text_pos = state->slice_start;
|
||||||
|
else
|
||||||
|
state->text_pos = state->slice_end;
|
||||||
|
}
|
||||||
|
|
||||||
/* Store the capture groups. */
|
/* Store the capture groups. */
|
||||||
group_info = pattern->group_info;
|
group_info = pattern->group_info;
|
||||||
|
|
||||||
@ -19332,17 +19362,32 @@ Py_LOCAL_INLINE(PyObject*) pattern_subx(PatternObject* self, PyObject*
|
|||||||
#endif
|
#endif
|
||||||
} else if (is_template) {
|
} else if (is_template) {
|
||||||
/* The replacement is a list template. */
|
/* The replacement is a list template. */
|
||||||
Py_ssize_t size;
|
Py_ssize_t count;
|
||||||
Py_ssize_t i;
|
Py_ssize_t index;
|
||||||
|
Py_ssize_t step;
|
||||||
|
|
||||||
/* Add each part of the template to the list. */
|
/* Add each part of the template to the list. */
|
||||||
size = PyList_GET_SIZE(replacement);
|
count = PyList_GET_SIZE(replacement);
|
||||||
for (i = 0; i < size; i++) {
|
if (join_info.reversed) {
|
||||||
|
/* We're searching backwards, so we'll be reversing the list
|
||||||
|
* when it's complete. Therefore, we need to add the items of
|
||||||
|
* the template in reverse order for them to be in the correct
|
||||||
|
* order after the reversal.
|
||||||
|
*/
|
||||||
|
index = count - 1;
|
||||||
|
step = -1;
|
||||||
|
} else {
|
||||||
|
/* We're searching forwards. */
|
||||||
|
index = 0;
|
||||||
|
step = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (count > 0) {
|
||||||
PyObject* item;
|
PyObject* item;
|
||||||
PyObject* str_item;
|
PyObject* str_item;
|
||||||
|
|
||||||
/* PyList_GET_ITEM borrows a reference. */
|
/* PyList_GET_ITEM borrows a reference. */
|
||||||
item = PyList_GET_ITEM(replacement, i);
|
item = PyList_GET_ITEM(replacement, index);
|
||||||
str_item = get_sub_replacement(item, string, &state,
|
str_item = get_sub_replacement(item, string, &state,
|
||||||
self->public_group_count);
|
self->public_group_count);
|
||||||
if (!str_item)
|
if (!str_item)
|
||||||
@ -19358,6 +19403,9 @@ Py_LOCAL_INLINE(PyObject*) pattern_subx(PatternObject* self, PyObject*
|
|||||||
if (status < 0)
|
if (status < 0)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--count;
|
||||||
|
index += step;
|
||||||
}
|
}
|
||||||
} else if (is_callable) {
|
} else if (is_callable) {
|
||||||
/* Pass a MatchObject to the replacement function. */
|
/* Pass a MatchObject to the replacement function. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user