Mercurial > hgrepos > Python > libs > ConfigMix
comparison configmix/_speedups.c @ 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 |
comparison
equal
deleted
inserted
replaced
| 703:193a616e0b3c | 704:457ef358c1a0 |
|---|---|
| 38 PyObject *DEL_VALUE; | 38 PyObject *DEL_VALUE; |
| 39 }; | 39 }; |
| 40 | 40 |
| 41 | 41 |
| 42 static PyObject * _fast_getvar_s(PyObject *config, PyObject *varname, PyObject *default_, struct speedups_state *sstate, int *cacheable); | 42 static PyObject * _fast_getvar_s(PyObject *config, PyObject *varname, PyObject *default_, struct speedups_state *sstate, int *cacheable); |
| 43 static PyObject * _fast_interpolate_variables(PyObject *self, PyObject *config, PyObject *s, PyObject *cache); | |
| 43 | 44 |
| 44 | 45 |
| 45 static | 46 static |
| 46 int | 47 int |
| 47 _hex2ucs4(PyObject *s, Py_ssize_t end, Py_UCS4 *result) | 48 _hex2ucs4(PyObject *s, Py_ssize_t end, Py_UCS4 *result) |
| 1033 { | 1034 { |
| 1034 PyObject *config; | 1035 PyObject *config; |
| 1035 PyObject *s; | 1036 PyObject *s; |
| 1036 PyObject *cache = NULL; | 1037 PyObject *cache = NULL; |
| 1037 | 1038 |
| 1039 if (!PyArg_UnpackTuple(args, "s", 2, 3, &config, &s, &cache)) { | |
| 1040 return NULL; | |
| 1041 } | |
| 1042 return _fast_interpolate_variables(self, config, s, cache); | |
| 1043 } | |
| 1044 | |
| 1045 | |
| 1046 static | |
| 1047 PyObject * | |
| 1048 _fast_interpolate_variables(PyObject *self, PyObject *config, PyObject *s, PyObject *cache) | |
| 1049 { | |
| 1038 int cmp; | 1050 int cmp; |
| 1039 Py_ssize_t s_len; | 1051 Py_ssize_t s_len; |
| 1040 Py_ssize_t start, rest, end; | 1052 Py_ssize_t start, rest, end; |
| 1041 PyObject *tmp; | 1053 PyObject *tmp; |
| 1042 PyObject *result = NULL; | 1054 PyObject *result = NULL; |
| 1047 PyObject *err_value; | 1059 PyObject *err_value; |
| 1048 PyObject *err_tb; | 1060 PyObject *err_tb; |
| 1049 int use_cache, cacheable; | 1061 int use_cache, cacheable; |
| 1050 struct speedups_state *sstate; | 1062 struct speedups_state *sstate; |
| 1051 | 1063 |
| 1052 if (!PyArg_UnpackTuple(args, "s", 2, 3, &config, &s, &cache)) { | |
| 1053 return NULL; | |
| 1054 } | |
| 1055 /* Disable caching if the cache param is given as None */ | 1064 /* Disable caching if the cache param is given as None */ |
| 1056 if ((cache != NULL) && py_object_is(cache, Py_None)) { | 1065 if ((cache != NULL) && py_object_is(cache, Py_None)) { |
| 1057 cache = NULL; | 1066 cache = NULL; |
| 1058 } | 1067 } |
| 1059 s_len = PyUnicode_GetLength(s); /* also an implicit type check */ | 1068 s_len = PyUnicode_GetLength(s); /* also an implicit type check */ |
| 1099 return Py_NewRef(result); | 1108 return Py_NewRef(result); |
| 1100 } | 1109 } |
| 1101 } | 1110 } |
| 1102 } | 1111 } |
| 1103 | 1112 |
| 1113 /* Check for {{| ... |}} */ | |
| 1104 if ((s_len >= 6) | 1114 if ((s_len >= 6) |
| 1105 && (start == 0) | 1115 && (start == 0) |
| 1106 && (PyUnicode_ReadChar(s, 2) == 0x7c /* | */)) { | 1116 && (PyUnicode_ReadChar(s, 2) == 0x7c /* `|' */)) { |
| 1107 end = PyUnicode_Find(s, sstate->ENDTOK_FILTER, start+3, s_len, 1); | 1117 end = PyUnicode_Find(s, sstate->ENDTOK_FILTER, start+3, s_len, 1); |
| 1108 if (end == -2) { | 1118 if (end == -2) { |
| 1109 return NULL; | 1119 return NULL; |
| 1110 } | 1120 } |
| 1111 if (end != (s_len - 3)) { | 1121 if (end != (s_len - 3)) { |
| 1112 PyErr_SetString(PyExc_ValueError, "XXX") ; /*`{{|' global filter interpolation must end with `|}}'"); */ | 1122 PyErr_SetString(PyExc_ValueError, "`{{|' global filter interpolation must end with `|}}'"); |
| 1113 return NULL; | 1123 return NULL; |
| 1114 } | 1124 } |
| 1125 /* | |
| 1126 * Handle {{| ... |filters, ... |}} : | |
| 1127 * split and recurse and apply filters | |
| 1128 */ | |
| 1115 tmp = PyUnicode_Substring(s, 3, s_len-3); | 1129 tmp = PyUnicode_Substring(s, 3, s_len-3); |
| 1116 if (tmp == NULL) { | 1130 if (tmp == NULL) { |
| 1117 return NULL; | 1131 return NULL; |
| 1118 } | 1132 } |
| 1119 filters = _fast_split_filters(tmp, NULL, sstate); | 1133 filters = _fast_split_filters(tmp, NULL, sstate); |
| 1125 py_clear_ref(&tmp); | 1139 py_clear_ref(&tmp); |
| 1126 PyErr_SetString(PyExc_TypeError, "tuple of size 2 expected"); | 1140 PyErr_SetString(PyExc_TypeError, "tuple of size 2 expected"); |
| 1127 goto error; | 1141 goto error; |
| 1128 } | 1142 } |
| 1129 py_transfer_owned(&tmp, &filters); | 1143 py_transfer_owned(&tmp, &filters); |
| 1130 | 1144 /* Unpack the result tuple */ |
| 1131 /* XXX TBD */ | 1145 /* borrowed -- cannot fail -- need ownership */ |
| 1146 varname = Py_NewRef(PyTuple_GetItem(tmp, 0)); | |
| 1147 /* borrowed -- cannot fail -- need ownership */ | |
| 1148 filters = Py_NewRef(PyTuple_GetItem(tmp, 1)); | |
| 1132 py_clear_ref(&tmp); | 1149 py_clear_ref(&tmp); |
| 1133 PyErr_SetString(PyExc_KeyError, "ERRRRRRR in C"); | 1150 |
| 1134 return NULL; | 1151 varvalue = _fast_interpolate_variables(self, config, varname, cache); |
| 1152 if (varvalue == NULL) { | |
| 1153 if (PyErr_ExceptionMatches(PyExc_KeyError)) { | |
| 1154 if (PySequence_Contains(filters, sstate->NONE_FILTER) == 1) { | |
| 1155 PyErr_Clear(); | |
| 1156 varvalue = Py_NewRef(Py_None); | |
| 1157 } | |
| 1158 else { | |
| 1159 if (PySequence_Contains(filters, sstate->EMPTY_FILTER) == 1) { | |
| 1160 PyErr_Clear(); | |
| 1161 varvalue = Py_NewRef(sstate->EMPTY_STR); | |
| 1162 } | |
| 1163 else { | |
| 1164 goto error; | |
| 1165 } | |
| 1166 } | |
| 1167 } | |
| 1168 else { | |
| 1169 /* other exception/error than KeyError */ | |
| 1170 goto error; | |
| 1171 } | |
| 1172 } | |
| 1173 py_clear_ref(&varname); | |
| 1174 result = PyObject_CallMethod( | |
| 1175 config, "_apply_filters", "OO", filters, varvalue); | |
| 1176 if (result == NULL) { | |
| 1177 goto error; | |
| 1178 } | |
| 1179 py_clear_ref(&varvalue); | |
| 1180 py_clear_ref(&filters); | |
| 1181 return result; | |
| 1135 } | 1182 } |
| 1136 | 1183 |
| 1137 result = PyList_New(0); | 1184 result = PyList_New(0); |
| 1138 if (result == NULL) { | 1185 if (result == NULL) { |
| 1139 return NULL; | 1186 return NULL; |
