Mercurial > hgrepos > Python > libs > ConfigMix
changeset 704:457ef358c1a0
filter-only expansions also implemented in the C extension.
BUGS: No caching yet (pure Python and C extension).
| author | Franz Glasner <f.glasner@feldmann-mg.com> |
|---|---|
| date | Mon, 14 Aug 2023 13:00:19 +0200 |
| parents | 193a616e0b3c |
| children | 0485a033c95d |
| files | configmix/_speedups.c |
| diffstat | 1 files changed, 56 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/configmix/_speedups.c Mon Aug 14 09:31:27 2023 +0200 +++ b/configmix/_speedups.c Mon Aug 14 13:00:19 2023 +0200 @@ -40,6 +40,7 @@ static PyObject * _fast_getvar_s(PyObject *config, PyObject *varname, PyObject *default_, struct speedups_state *sstate, int *cacheable); +static PyObject * _fast_interpolate_variables(PyObject *self, PyObject *config, PyObject *s, PyObject *cache); static @@ -1035,6 +1036,17 @@ PyObject *s; PyObject *cache = NULL; + if (!PyArg_UnpackTuple(args, "s", 2, 3, &config, &s, &cache)) { + return NULL; + } + return _fast_interpolate_variables(self, config, s, cache); +} + + +static +PyObject * +_fast_interpolate_variables(PyObject *self, PyObject *config, PyObject *s, PyObject *cache) +{ int cmp; Py_ssize_t s_len; Py_ssize_t start, rest, end; @@ -1049,9 +1061,6 @@ int use_cache, cacheable; struct speedups_state *sstate; - if (!PyArg_UnpackTuple(args, "s", 2, 3, &config, &s, &cache)) { - return NULL; - } /* Disable caching if the cache param is given as None */ if ((cache != NULL) && py_object_is(cache, Py_None)) { cache = NULL; @@ -1101,17 +1110,22 @@ } } + /* Check for {{| ... |}} */ if ((s_len >= 6) && (start == 0) - && (PyUnicode_ReadChar(s, 2) == 0x7c /* | */)) { + && (PyUnicode_ReadChar(s, 2) == 0x7c /* `|' */)) { end = PyUnicode_Find(s, sstate->ENDTOK_FILTER, start+3, s_len, 1); if (end == -2) { return NULL; } if (end != (s_len - 3)) { - PyErr_SetString(PyExc_ValueError, "XXX") ; /*`{{|' global filter interpolation must end with `|}}'"); */ + PyErr_SetString(PyExc_ValueError, "`{{|' global filter interpolation must end with `|}}'"); return NULL; } + /* + * Handle {{| ... |filters, ... |}} : + * split and recurse and apply filters + */ tmp = PyUnicode_Substring(s, 3, s_len-3); if (tmp == NULL) { return NULL; @@ -1127,11 +1141,44 @@ goto error; } py_transfer_owned(&tmp, &filters); - - /* XXX TBD */ + /* Unpack the result tuple */ + /* borrowed -- cannot fail -- need ownership */ + varname = Py_NewRef(PyTuple_GetItem(tmp, 0)); + /* borrowed -- cannot fail -- need ownership */ + filters = Py_NewRef(PyTuple_GetItem(tmp, 1)); py_clear_ref(&tmp); - PyErr_SetString(PyExc_KeyError, "ERRRRRRR in C"); - return NULL; + + varvalue = _fast_interpolate_variables(self, config, varname, cache); + if (varvalue == NULL) { + if (PyErr_ExceptionMatches(PyExc_KeyError)) { + if (PySequence_Contains(filters, sstate->NONE_FILTER) == 1) { + PyErr_Clear(); + varvalue = Py_NewRef(Py_None); + } + else { + if (PySequence_Contains(filters, sstate->EMPTY_FILTER) == 1) { + PyErr_Clear(); + varvalue = Py_NewRef(sstate->EMPTY_STR); + } + else { + goto error; + } + } + } + else { + /* other exception/error than KeyError */ + goto error; + } + } + py_clear_ref(&varname); + result = PyObject_CallMethod( + config, "_apply_filters", "OO", filters, varvalue); + if (result == NULL) { + goto error; + } + py_clear_ref(&varvalue); + py_clear_ref(&filters); + return result; } result = PyList_New(0);
