|
|
@@ -51,6 +51,26 @@ call_tag_def_func(const char* funcname, PyObject* tag) |
|
|
|
return ans; |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
|
Sanitize the name of a tag so it can be compared with others for equality. |
|
|
|
*/ |
|
|
|
static PyObject* |
|
|
|
strip_tag_name(PyObject* token) |
|
|
|
{ |
|
|
|
PyObject *text, *rstripped, *lowered; |
|
|
|
|
|
|
|
text = PyObject_GetAttrString(token, "text"); |
|
|
|
if (!text) |
|
|
|
return NULL; |
|
|
|
rstripped = PyObject_CallMethod(text, "rstrip", NULL); |
|
|
|
Py_DECREF(text); |
|
|
|
if (!rstripped) |
|
|
|
return NULL; |
|
|
|
lowered = PyObject_CallMethod(rstripped, "rstrip", NULL); |
|
|
|
Py_DECREF(rstripped); |
|
|
|
return lowered; |
|
|
|
} |
|
|
|
|
|
|
|
static Textbuffer* |
|
|
|
Textbuffer_new(void) |
|
|
|
{ |
|
|
@@ -1629,7 +1649,56 @@ Tokenizer_handle_tag_open_close(Tokenizer* self) |
|
|
|
static PyObject* |
|
|
|
Tokenizer_handle_tag_close_close(Tokenizer* self) |
|
|
|
{ |
|
|
|
return NULL; |
|
|
|
PyObject *closing, *first, *so, *sc, *token; |
|
|
|
int valid = 1; |
|
|
|
|
|
|
|
closing = Tokenizer_pop(self); |
|
|
|
if (!closing) |
|
|
|
return NULL; |
|
|
|
if (PyList_GET_SIZE(closing) != 1) |
|
|
|
valid = 0; |
|
|
|
else { |
|
|
|
first = PyList_GET_ITEM(closing, 0); |
|
|
|
switch (PyObject_IsInstance(first, Text)) { |
|
|
|
case 0: |
|
|
|
valid = 0; |
|
|
|
break; |
|
|
|
case 1: { |
|
|
|
so = strip_tag_name(first); |
|
|
|
sc = strip_tag_name(PyList_GET_ITEM(self->topstack->stack, 1)); |
|
|
|
if (so && sc) { |
|
|
|
if (PyUnicode_Compare(so, sc)) |
|
|
|
valid = 0; |
|
|
|
Py_DECREF(so); |
|
|
|
Py_DECREF(sc); |
|
|
|
break; |
|
|
|
} |
|
|
|
Py_XDECREF(so); |
|
|
|
Py_XDECREF(sc); |
|
|
|
} |
|
|
|
case -1: |
|
|
|
Py_DECREF(closing); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!valid) { |
|
|
|
Py_DECREF(closing); |
|
|
|
return Tokenizer_fail_route(self); |
|
|
|
} |
|
|
|
if (Tokenizer_emit_all(self, closing)) { |
|
|
|
Py_DECREF(closing); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
Py_DECREF(closing); |
|
|
|
token = PyObject_CallObject(TagCloseClose, NULL); |
|
|
|
if (!token) |
|
|
|
return NULL; |
|
|
|
if (Tokenizer_emit(self, token)) { |
|
|
|
Py_DECREF(token); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
Py_DECREF(token); |
|
|
|
return Tokenizer_pop(self); |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
|