|
@@ -100,6 +100,66 @@ static PyObject* strip_tag_name(PyObject* token, int take_attr) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
|
|
|
|
Check if the given character is a non-word character. |
|
|
|
|
|
|
|
|
|
|
|
Equivalent to this Python code: |
|
|
|
|
|
|
|
|
|
|
|
def is_non_word_character(ch): |
|
|
|
|
|
if re.fullmatch(r"\W", chunk): |
|
|
|
|
|
return True |
|
|
|
|
|
return False |
|
|
|
|
|
*/ |
|
|
|
|
|
static int is_non_word_character(Py_UCS4 ch) |
|
|
|
|
|
{ |
|
|
|
|
|
int ret = 0; |
|
|
|
|
|
PyObject* modname = NULL; |
|
|
|
|
|
PyObject* module = NULL; |
|
|
|
|
|
PyObject* fmatch = NULL; |
|
|
|
|
|
PyObject* pattern = NULL; |
|
|
|
|
|
PyObject* str = NULL; |
|
|
|
|
|
PyObject* posArgs = NULL; |
|
|
|
|
|
PyObject* match = NULL; |
|
|
|
|
|
|
|
|
|
|
|
modname = PyUnicode_FromString("re"); |
|
|
|
|
|
if (modname == NULL) |
|
|
|
|
|
goto error; |
|
|
|
|
|
module = PyImport_Import(modname); |
|
|
|
|
|
if (module == NULL) |
|
|
|
|
|
goto error; |
|
|
|
|
|
fmatch = PyObject_GetAttrString(module, "fullmatch"); |
|
|
|
|
|
if (fmatch == NULL) |
|
|
|
|
|
goto error; |
|
|
|
|
|
pattern = PyUnicode_FromString("\\W"); |
|
|
|
|
|
if (pattern == NULL) |
|
|
|
|
|
goto error; |
|
|
|
|
|
str = PyUnicode_FROM_SINGLE(ch); |
|
|
|
|
|
if (str == NULL) |
|
|
|
|
|
goto error; |
|
|
|
|
|
posArgs = PyTuple_Pack(2, pattern, str); |
|
|
|
|
|
if (posArgs == NULL) |
|
|
|
|
|
goto error; |
|
|
|
|
|
match = PyObject_Call(fmatch, posArgs, NULL); |
|
|
|
|
|
if (match == NULL) |
|
|
|
|
|
goto error; |
|
|
|
|
|
|
|
|
|
|
|
if (match != Py_None) |
|
|
|
|
|
ret = 1; |
|
|
|
|
|
goto end; |
|
|
|
|
|
|
|
|
|
|
|
error: |
|
|
|
|
|
ret = -1; |
|
|
|
|
|
end: |
|
|
|
|
|
Py_XDECREF(match); |
|
|
|
|
|
Py_XDECREF(posArgs); |
|
|
|
|
|
Py_XDECREF(str); |
|
|
|
|
|
Py_XDECREF(pattern); |
|
|
|
|
|
Py_XDECREF(fmatch); |
|
|
|
|
|
Py_XDECREF(module); |
|
|
|
|
|
Py_XDECREF(modname); |
|
|
|
|
|
return ret; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
Parse a template at the head of the wikicode string. |
|
|
Parse a template at the head of the wikicode string. |
|
|
*/ |
|
|
*/ |
|
|
static int Tokenizer_parse_template(Tokenizer* self, int has_content) |
|
|
static int Tokenizer_parse_template(Tokenizer* self, int has_content) |
|
@@ -527,7 +587,13 @@ static int Tokenizer_parse_free_uri_scheme(Tokenizer* self) |
|
|
// it was just parsed as text: |
|
|
// it was just parsed as text: |
|
|
for (i = self->topstack->textbuffer->length - 1; i >= 0; i--) { |
|
|
for (i = self->topstack->textbuffer->length - 1; i >= 0; i--) { |
|
|
chunk = Textbuffer_read(self->topstack->textbuffer, i); |
|
|
chunk = Textbuffer_read(self->topstack->textbuffer, i); |
|
|
if (Py_UNICODE_ISSPACE(chunk) || is_marker(chunk)) |
|
|
|
|
|
|
|
|
// stop at the first non-word character |
|
|
|
|
|
int is_non_word = is_non_word_character(chunk); |
|
|
|
|
|
if (is_non_word < 0) { |
|
|
|
|
|
Textbuffer_dealloc(scheme_buffer); |
|
|
|
|
|
return -1; |
|
|
|
|
|
} |
|
|
|
|
|
else if (is_non_word == 1) |
|
|
goto end_of_loop; |
|
|
goto end_of_loop; |
|
|
j = 0; |
|
|
j = 0; |
|
|
do { |
|
|
do { |
|
|