From c0f83fc80359bba55fda4416f02d1aae99191ee9 Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Sun, 21 Jul 2013 09:48:33 -0400 Subject: [PATCH] Implement Tokenizer_handle_tag_close_close() --- mwparserfromhell/parser/tokenizer.c | 71 ++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/mwparserfromhell/parser/tokenizer.c b/mwparserfromhell/parser/tokenizer.c index cb2ecc1..062d05b 100644 --- a/mwparserfromhell/parser/tokenizer.c +++ b/mwparserfromhell/parser/tokenizer.c @@ -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); } /*