| @@ -259,6 +259,39 @@ Tokenizer_write_text(Tokenizer* self, PyObject* text) | |||||
| static int | static int | ||||
| Tokenizer_write_all(Tokenizer* self, PyObject* tokenlist) | Tokenizer_write_all(Tokenizer* self, PyObject* tokenlist) | ||||
| { | { | ||||
| if (PySequence_Fast_GET_SIZE(tokenlist) > 0) { | |||||
| PyObject* token = PySequence_Fast_GET_ITEM(tokenlist, 0); | |||||
| PyObject* class = PyObject_GetAttrString(tokens, "Text"); | |||||
| if (!class) return -1; | |||||
| switch (PyObject_IsInstance(token, class)) { | |||||
| case 0: | |||||
| break; | |||||
| case 1: | |||||
| PyObject* text = PyObject_GetAttrString(token, "text"); | |||||
| if (!text) { | |||||
| Py_DECREF(class); | |||||
| return -1; | |||||
| } | |||||
| if (PySequence_DelItem(tokenlist, 0)) { | |||||
| Py_DECREF(text); | |||||
| Py_DECREF(class); | |||||
| return -1; | |||||
| } | |||||
| if (Tokenizer_write_text(self, text)) { | |||||
| Py_DECREF(text); | |||||
| Py_DECREF(class); | |||||
| return -1; | |||||
| } | |||||
| Py_DECREF(text); | |||||
| break | |||||
| case -1: | |||||
| Py_DECREF(class); | |||||
| return -1; | |||||
| } | |||||
| Py_DECREF(class); | |||||
| } | |||||
| if (Tokenizer_push_textbuffer(self)) | if (Tokenizer_push_textbuffer(self)) | ||||
| return -1; | return -1; | ||||
| @@ -711,6 +744,7 @@ Tokenizer_handle_template_param_value(Tokenizer* self) | |||||
| return -1; | return -1; | ||||
| } | } | ||||
| Py_DECREF(token); | Py_DECREF(token); | ||||
| return 0; | |||||
| } | } | ||||
| /* | /* | ||||
| @@ -719,7 +753,27 @@ Tokenizer_handle_template_param_value(Tokenizer* self) | |||||
| static PyObject* | static PyObject* | ||||
| Tokenizer_handle_template_end(Tokenizer* self) | Tokenizer_handle_template_end(Tokenizer* self) | ||||
| { | { | ||||
| PyObject* stack; | |||||
| Py_ssize_t context = Tokenizer_CONTEXT_VAL(self); | |||||
| if (context & LC_TEMPLATE_NAME) { | |||||
| const char* unsafes[] = {"\n", "{", "}", "[", "]"}; | |||||
| if (Tokenizer_verify_safe(self, unsafes)) | |||||
| return NULL; | |||||
| } | |||||
| else if (context & LC_TEMPLATE_PARAM_KEY) { | |||||
| stack = Tokenizer_pop_keeping_context(self); | |||||
| if (!stack) return NULL; | |||||
| if (Tokenizer_write_all(self, stack)) { | |||||
| Py_DECREF(stack); | |||||
| return NULL; | |||||
| } | |||||
| Py_DECREF(stack); | |||||
| } | |||||
| self->head++; | |||||
| stack = Tokenizer_pop(self); | |||||
| return stack; | |||||
| } | } | ||||
| /* | /* | ||||
| @@ -728,7 +782,28 @@ Tokenizer_handle_template_end(Tokenizer* self) | |||||
| static int | static int | ||||
| Tokenizer_handle_argument_separator(Tokenizer* self) | Tokenizer_handle_argument_separator(Tokenizer* self) | ||||
| { | { | ||||
| const char* unsafes[] = {"\n", "{{", "}}"}; | |||||
| if (Tokenizer_verify_safe(self, unsafes)) | |||||
| return -1; | |||||
| Py_ssize_t context = Tokenizer_CONTEXT_VAL(self); | |||||
| context ^= LC_ARGUMENT_NAME; | |||||
| context |= LC_ARGUMENT_DEFAULT; | |||||
| if (Tokenizer_set_context(self, context)) | |||||
| return -1; | |||||
| PyObject* class = PyObject_GetAttrString(tokens, "ArgumentSeparator"); | |||||
| if (!class) return -1; | |||||
| PyObject* token = PyInstance_New(class, NOARGS, NOKWARGS); | |||||
| Py_DECREF(class); | |||||
| if (!token) return -1; | |||||
| if (Tokenizer_write(self, token)) { | |||||
| Py_DECREF(token); | |||||
| return -1; | |||||
| } | |||||
| Py_DECREF(token); | |||||
| return 0; | |||||
| } | } | ||||
| /* | /* | ||||
| @@ -737,7 +812,16 @@ Tokenizer_handle_argument_separator(Tokenizer* self) | |||||
| static PyObject* | static PyObject* | ||||
| Tokenizer_handle_argument_end(Tokenizer* self) | Tokenizer_handle_argument_end(Tokenizer* self) | ||||
| { | { | ||||
| Py_ssize_t context = Tokenizer_CONTEXT_VAL(self); | |||||
| if (context & LC_ARGUMENT_NAME) { | |||||
| const char* unsafes[] = {"\n", "{{", "}}"}; | |||||
| if (Tokenizer_verify_safe(self, unsafes)) | |||||
| return NULL; | |||||
| } | |||||
| self->head += 2; | |||||
| PyObject* stack = Tokenizer_pop(self); | |||||
| return stack; | |||||
| } | } | ||||
| /* | /* | ||||