Mercurial > hgrepos > Python > libs > ConfigMix
diff configmix/_speedups.c @ 656:2b1c7a68f913
Enable indexed access to lists in the configuration using an access path string representation like "~NNN~"
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 30 May 2022 09:31:29 +0200 |
| parents | 999cfca55d25 |
| children | 193a616e0b3c |
line wrap: on
line diff
--- a/configmix/_speedups.c Sun May 29 15:32:54 2022 +0200 +++ b/configmix/_speedups.c Mon May 30 09:31:29 2022 +0200 @@ -75,6 +75,54 @@ } +static +int +_dec2num(PyObject *s, Py_ssize_t start, Py_ssize_t end, Py_ssize_t *result) +{ + Py_ssize_t i; + Py_UCS4 c; + Py_ssize_t r = 0; + int sign = 0; + + for (i=start; i<=end; i++) { + /* Overflow error check */ + if (r > 3275) { + PyErr_SetString(PyExc_OverflowError, "index too large"); + return -1; + } + r *= 10; + c = PyUnicode_ReadChar(s, i); + if ((c >= 48) && (c <= 57)) { /* 0 - 9 */ + r += (c - 48); + } + else { + if (i == start) { + /* check for number sign (but only at the first index) */ + if (c == 0x2d) { + sign = -1; + continue; + } + else { + if (c == 0x2b) { + sign = 1; + continue; + } + } + } + PyErr_Format(PyExc_ValueError, "invalid base-10 literal: %c", (int)c); + return -1; + } + } + if (sign >= 0) { + *result = r; + } + else { + *result = -r; + } + return 0; /* success */ +} + + #if defined(Py_LIMITED_API) static @@ -292,6 +340,19 @@ if (s_len == 0) { return Py_NewRef(s); } + if (s_len > 2) { + /* Check for ~NNN~ syntax */ + c = PyUnicode_ReadChar(s, 0); + if (c == 0x7e) { + c = PyUnicode_ReadChar(s, s_len - 1); + if (c == 0x7e) { + if (_dec2num(s, 1, s_len - 2, &i) == 0) { + return PyLong_FromSsize_t(i); + } + PyErr_Clear(); + } + } + } find = PyUnicode_FindChar(s, '%', 0, s_len, 1); if (find == -2) { return NULL; @@ -429,6 +490,11 @@ s_len = PyUnicode_GetLength(s); if (s_len < 0) { + if (PyObject_IsInstance(s, (PyObject *)&PyLong_Type)) { + PyErr_Clear(); + return PyUnicode_FromFormat("~%S~", s); + } + PyErr_SetString(PyExc_TypeError, "given object has no len()"); return NULL; } if (s_len == 0) { @@ -449,6 +515,7 @@ case 0x7d: case 0x5b: case 0x5d: + case 0x7e: need_quoting = 1; i = s_len; /* break the for-loop */ break; @@ -1638,7 +1705,7 @@ PyUnicode_InternInPlace(&(sstate->EMPTY_STR)); sstate->QUOTE_MAP = Py_BuildValue( - "{IsIsIsIsIsIsIsIsIsIsIs}", + "{IsIsIsIsIsIsIsIsIsIsIsIs}", 0x25, "%x25", /* QUOTE: % */ 0x2e, "%x2e", /* DOT: . */ 0x3a, "%x3a", /* NS_SEPARATOR: : */ @@ -1649,7 +1716,8 @@ 0x7b, "%x7b", 0x7d, "%x7d", 0x5b, "%x5b", - 0x5d, "%x5d"); + 0x5d, "%x5d", + 0x7e, "%x7e"); /* tilde ~ */ if (sstate->QUOTE_MAP == NULL) { return -1; }
