|
@@ -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; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
|