Mercurial > hgrepos > Python > libs > ConfigMix
comparison configmix/_speedups.c @ 561:c51f484387ee
FIX: Remove bogus comment
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Thu, 06 Jan 2022 20:03:01 +0100 |
| parents | 81238ea2dbe3 |
| children | f75c5b13a1d7 |
comparison
equal
deleted
inserted
replaced
| 560:81238ea2dbe3 | 561:c51f484387ee |
|---|---|
| 820 } | 820 } |
| 821 /* Unpack the result tuple */ | 821 /* Unpack the result tuple */ |
| 822 /* borrowed -- cannot fail -- need ownership */ | 822 /* borrowed -- cannot fail -- need ownership */ |
| 823 varname = Py_NewRef(PyTuple_GetItem(tmp, 0)); | 823 varname = Py_NewRef(PyTuple_GetItem(tmp, 0)); |
| 824 /* borrowed -- cannot fail -- want ownership */ | 824 /* borrowed -- cannot fail -- want ownership */ |
| 825 filters = Py_NewRef(PyTuple_GetItem(tmp, 1)); | |
| 826 py_clear_ref(&tmp); | |
| 827 | |
| 828 tmp = PyObject_CallMethod( | |
| 829 config, "_getvar_s_with_cache_info", "O", varname); | |
| 830 if (tmp == NULL) { | |
| 831 if (PyErr_ExceptionMatches(PyExc_KeyError)) { | |
| 832 /* XXX TBD handle KeyError (None and Empty-filter) */ | |
| 833 cacheable = 1; | |
| 834 if (PySequence_Contains(filters, sstate->NONE_FILTER) == 1) { | |
| 835 PyErr_Clear(); | |
| 836 varvalue = Py_NewRef(Py_None); | |
| 837 } | |
| 838 else { | |
| 839 if (PySequence_Contains(filters, sstate->EMPTY_FILTER) == 1) { | |
| 840 PyErr_Clear(); | |
| 841 varvalue = Py_NewRef(sstate->EMPTY_STR); | |
| 842 } | |
| 843 else { | |
| 844 PyErr_Fetch(&err_type, &err_value, &err_tb); | |
| 845 /* this does NOT steal */ | |
| 846 PyDict_SetItem(cache, s, sstate->MISSING); | |
| 847 PyErr_Restore(err_type, err_value, err_tb); | |
| 848 goto error; | |
| 849 } | |
| 850 } | |
| 851 } | |
| 852 else { | |
| 853 /* other exception/error than KeyError */ | |
| 854 goto error; | |
| 855 } | |
| 856 } | |
| 857 else { | |
| 858 if (PyTuple_Size(tmp) != 2) { | |
| 859 py_clear_ref(&tmp); | |
| 860 PyErr_SetString(PyExc_TypeError, "tuple of size 2 expected"); | |
| 861 goto error; | |
| 862 } | |
| 863 /* unpack the result */ | |
| 864 /* borrowed -- cannot fail -- but want ownership */ | |
| 865 varvalue = Py_NewRef(PyTuple_GetItem(tmp, 0)); | |
| 866 cacheable = PyObject_IsTrue(PyTuple_GetItem(tmp, 1)); | |
| 867 py_clear_ref(&tmp); | |
| 868 } | |
| 869 | |
| 870 if (!cacheable) { | |
| 871 use_cache = 0; | |
| 872 } | |
| 873 | |
| 874 py_clear_ref(&varname); | |
| 875 | |
| 876 tmp = PyObject_CallMethod( | |
| 877 config, "_apply_filters", "OO", filters, varvalue); | |
| 878 if (tmp == NULL) { | |
| 879 goto error; | |
| 880 } | |
| 881 py_clear_ref(&varvalue); | |
| 882 | |
| 883 py_clear_ref(&filters); | |
| 884 | |
| 885 /* | |
| 886 * Dont apply and type conversions to the variable value if | |
| 887 * the whole `s` is just one expansion | |
| 888 */ | |
| 889 if (first_part_is_empty && (i == 1) && (pb_len == s_len - 2) && (idx == pb_len - 2)) { | |
| 890 res = varvalue; varvalue = NULL; | |
| 891 goto success; /* break out early */ | |
| 892 } | |
| 893 if (py_object_isnot(varvalue, Py_None)) { | |
| 894 tmp = PyObject_Str(varvalue); | |
| 895 if (tmp == NULL) { | |
| 896 goto error; | |
| 897 } | |
| 898 if (PyList_Append(res_parts, tmp) < 0) { | |
| 899 py_clear_ref(&tmp); | |
| 900 goto error; | |
| 901 } | |
| 902 py_clear_ref(&tmp); | |
| 903 } | |
| 904 py_clear_ref(&varvalue); | |
| 905 /* append the rest of the string */ | |
| 906 tmp = PyUnicode_Substring(pb, idx+2, pb_len); | |
| 907 if (tmp == NULL) { | |
| 908 goto error; | |
| 909 } | |
| 910 if (PyList_Append(res_parts, tmp) < 0) { | |
| 911 py_clear_ref(&tmp); | |
| 912 goto error; | |
| 913 } | |
| 914 py_clear_ref(&tmp); | |
| 915 } | |
| 916 | |
| 917 res = PyUnicode_Join(sstate->EMPTY_STR, res_parts); | |
| 918 if (res == NULL) { | |
| 919 goto error; | |
| 920 } | |
| 921 | |
| 922 success: | |
| 923 Py_DECREF(parts); | |
| 924 Py_DECREF(res_parts); | |
| 925 | |
| 926 if (use_cache) { | |
| 927 PyDict_SetItem(cache, s, res); | |
| 928 PyErr_Clear(); /* clear any possible cache-related error */ | |
| 929 } | |
| 930 return res; | |
| 931 | |
| 932 error: | |
| 933 Py_XDECREF(varname); | |
| 934 Py_XDECREF(varvalue); | |
| 935 Py_XDECREF(filters); | |
| 936 Py_XDECREF(parts); | |
| 937 Py_XDECREF(res_parts); | |
| 938 Py_XDECREF(res); | |
| 939 return NULL; | |
| 940 } | |
| 941 | |
| 942 | |
| 943 static | |
| 944 PyObject * | |
| 945 fast_interpolate_variables(PyObject *self, PyObject *args) | |
| 946 { | |
| 947 PyObject *config; | |
| 948 PyObject *s; | |
| 949 PyObject *cache; | |
| 950 | |
| 951 Py_ssize_t s_len; | |
| 952 Py_ssize_t start, rest, end; | |
| 953 PyObject *tmp; | |
| 954 PyObject *result = NULL; | |
| 955 PyObject *varname = NULL; | |
| 956 PyObject *varvalue = NULL; | |
| 957 PyObject *filters = NULL; | |
| 958 PyObject *err_type; | |
| 959 PyObject *err_value; | |
| 960 PyObject *err_tb; | |
| 961 int use_cache, cacheable; | |
| 962 struct speedups_state *sstate; | |
| 963 | |
| 964 if (!PyArg_UnpackTuple(args, "s", 3, 3, &config, &s, &cache)) { | |
| 965 return NULL; | |
| 966 } | |
| 967 s_len = PyUnicode_GetLength(s); /* also an implicit type check */ | |
| 968 if (s_len < 0) { | |
| 969 return NULL; | |
| 970 } | |
| 971 if (s_len < 4) { | |
| 972 return Py_NewRef(s); | |
| 973 } | |
| 974 | |
| 975 sstate = PyModule_GetState(self); | |
| 976 if (sstate == NULL) { | |
| 977 PyErr_SetString(PyExc_RuntimeError, "no module state available"); | |
| 978 return NULL; | |
| 979 } | |
| 980 | |
| 981 start = PyUnicode_Find(s, sstate->STARTTOK, 0, s_len, 1); | |
| 982 if (start == -2) { | |
| 983 return NULL; | |
| 984 } | |
| 985 if (start == -1) { | |
| 986 return Py_NewRef(s); | |
| 987 } | |
| 988 | |
| 989 result = PyDict_GetItem(cache, s); /* borrowed */ | |
| 990 if (result != NULL) { | |
| 991 if (result == sstate->MISSING) { | |
| 992 return PyErr_Format( | |
| 993 PyExc_KeyError, | |
| 994 "Cannot interpolate variables in string %R (cached)", | |
| 995 s); | |
| 996 } | |
| 997 else { | |
| 998 return Py_NewRef(result); | |
| 999 } | |
| 1000 } | |
| 1001 | |
| 1002 result = PyList_New(0); | |
| 1003 if (result == 0) { | |
| 1004 return NULL; | |
| 1005 } | |
| 1006 | |
| 1007 rest = 0; | |
| 1008 use_cache = 1; | |
| 1009 | |
| 1010 while (start != -1) { | |
| 1011 if (rest < start) { | |
| 1012 tmp = PyUnicode_Substring(s, rest, start); | |
| 1013 if (tmp == NULL) { | |
| 1014 goto error; | |
| 1015 } | |
| 1016 if (PyList_Append(result, tmp) < 0) { | |
| 1017 py_clear_ref(&tmp); | |
| 1018 goto error; | |
| 1019 } | |
| 1020 py_clear_ref(&tmp); | |
| 1021 } | |
| 1022 end = PyUnicode_Find(s, sstate->ENDTOK, start+2, s_len, 1); | |
| 1023 if (end == -2) { | |
| 1024 goto error; | |
| 1025 } | |
| 1026 if (end == -1) { | |
| 1027 rest = start; | |
| 1028 break; | |
| 1029 } | |
| 1030 | |
| 1031 varname = PyUnicode_Substring(s, start+2, end); /* 2 == len(STARTTOK) */ | |
| 1032 if (varname == NULL) { | |
| 1033 goto error; | |
| 1034 } | |
| 1035 | |
| 1036 tmp = _fast_split_filters(varname, NULL, sstate); | |
| 1037 if (tmp == NULL) { | |
| 1038 goto error; | |
| 1039 } | |
| 1040 if (PyTuple_Size(tmp) != 2) { | |
| 1041 PyErr_SetString(PyExc_TypeError, "tuple of size 2 expected"); | |
| 1042 py_clear_ref(&tmp); | |
| 1043 goto error; | |
| 1044 } | |
| 1045 /* Unpack the result tuple */ | |
| 1046 /* borrowed -- cannot fail -- need ownership */ | |
| 1047 varname = Py_NewRef(PyTuple_GetItem(tmp, 0)); | |
| 1048 /* borrowed -- cannot fail -- need ownership */ | |
| 1049 filters = Py_NewRef(PyTuple_GetItem(tmp, 1)); | 825 filters = Py_NewRef(PyTuple_GetItem(tmp, 1)); |
| 1050 py_clear_ref(&tmp); | 826 py_clear_ref(&tmp); |
| 1051 | 827 |
| 1052 tmp = PyObject_CallMethod( | 828 tmp = PyObject_CallMethod( |
| 1053 config, "_getvar_s_with_cache_info", "O", varname); | 829 config, "_getvar_s_with_cache_info", "O", varname); |
| 1082 py_clear_ref(&tmp); | 858 py_clear_ref(&tmp); |
| 1083 PyErr_SetString(PyExc_TypeError, "tuple of size 2 expected"); | 859 PyErr_SetString(PyExc_TypeError, "tuple of size 2 expected"); |
| 1084 goto error; | 860 goto error; |
| 1085 } | 861 } |
| 1086 /* unpack the result */ | 862 /* unpack the result */ |
| 863 /* borrowed -- cannot fail -- but want ownership */ | |
| 864 varvalue = Py_NewRef(PyTuple_GetItem(tmp, 0)); | |
| 865 cacheable = PyObject_IsTrue(PyTuple_GetItem(tmp, 1)); | |
| 866 py_clear_ref(&tmp); | |
| 867 } | |
| 868 | |
| 869 if (!cacheable) { | |
| 870 use_cache = 0; | |
| 871 } | |
| 872 | |
| 873 py_clear_ref(&varname); | |
| 874 | |
| 875 tmp = PyObject_CallMethod( | |
| 876 config, "_apply_filters", "OO", filters, varvalue); | |
| 877 if (tmp == NULL) { | |
| 878 goto error; | |
| 879 } | |
| 880 py_clear_ref(&varvalue); | |
| 881 | |
| 882 py_clear_ref(&filters); | |
| 883 | |
| 884 /* | |
| 885 * Dont apply and type conversions to the variable value if | |
| 886 * the whole `s` is just one expansion | |
| 887 */ | |
| 888 if (first_part_is_empty && (i == 1) && (pb_len == s_len - 2) && (idx == pb_len - 2)) { | |
| 889 res = varvalue; varvalue = NULL; | |
| 890 goto success; /* break out early */ | |
| 891 } | |
| 892 if (py_object_isnot(varvalue, Py_None)) { | |
| 893 tmp = PyObject_Str(varvalue); | |
| 894 if (tmp == NULL) { | |
| 895 goto error; | |
| 896 } | |
| 897 if (PyList_Append(res_parts, tmp) < 0) { | |
| 898 py_clear_ref(&tmp); | |
| 899 goto error; | |
| 900 } | |
| 901 py_clear_ref(&tmp); | |
| 902 } | |
| 903 py_clear_ref(&varvalue); | |
| 904 /* append the rest of the string */ | |
| 905 tmp = PyUnicode_Substring(pb, idx+2, pb_len); | |
| 906 if (tmp == NULL) { | |
| 907 goto error; | |
| 908 } | |
| 909 if (PyList_Append(res_parts, tmp) < 0) { | |
| 910 py_clear_ref(&tmp); | |
| 911 goto error; | |
| 912 } | |
| 913 py_clear_ref(&tmp); | |
| 914 } | |
| 915 | |
| 916 res = PyUnicode_Join(sstate->EMPTY_STR, res_parts); | |
| 917 if (res == NULL) { | |
| 918 goto error; | |
| 919 } | |
| 920 | |
| 921 success: | |
| 922 Py_DECREF(parts); | |
| 923 Py_DECREF(res_parts); | |
| 924 | |
| 925 if (use_cache) { | |
| 926 PyDict_SetItem(cache, s, res); | |
| 927 PyErr_Clear(); /* clear any possible cache-related error */ | |
| 928 } | |
| 929 return res; | |
| 930 | |
| 931 error: | |
| 932 Py_XDECREF(varname); | |
| 933 Py_XDECREF(varvalue); | |
| 934 Py_XDECREF(filters); | |
| 935 Py_XDECREF(parts); | |
| 936 Py_XDECREF(res_parts); | |
| 937 Py_XDECREF(res); | |
| 938 return NULL; | |
| 939 } | |
| 940 | |
| 941 | |
| 942 static | |
| 943 PyObject * | |
| 944 fast_interpolate_variables(PyObject *self, PyObject *args) | |
| 945 { | |
| 946 PyObject *config; | |
| 947 PyObject *s; | |
| 948 PyObject *cache; | |
| 949 | |
| 950 Py_ssize_t s_len; | |
| 951 Py_ssize_t start, rest, end; | |
| 952 PyObject *tmp; | |
| 953 PyObject *result = NULL; | |
| 954 PyObject *varname = NULL; | |
| 955 PyObject *varvalue = NULL; | |
| 956 PyObject *filters = NULL; | |
| 957 PyObject *err_type; | |
| 958 PyObject *err_value; | |
| 959 PyObject *err_tb; | |
| 960 int use_cache, cacheable; | |
| 961 struct speedups_state *sstate; | |
| 962 | |
| 963 if (!PyArg_UnpackTuple(args, "s", 3, 3, &config, &s, &cache)) { | |
| 964 return NULL; | |
| 965 } | |
| 966 s_len = PyUnicode_GetLength(s); /* also an implicit type check */ | |
| 967 if (s_len < 0) { | |
| 968 return NULL; | |
| 969 } | |
| 970 if (s_len < 4) { | |
| 971 return Py_NewRef(s); | |
| 972 } | |
| 973 | |
| 974 sstate = PyModule_GetState(self); | |
| 975 if (sstate == NULL) { | |
| 976 PyErr_SetString(PyExc_RuntimeError, "no module state available"); | |
| 977 return NULL; | |
| 978 } | |
| 979 | |
| 980 start = PyUnicode_Find(s, sstate->STARTTOK, 0, s_len, 1); | |
| 981 if (start == -2) { | |
| 982 return NULL; | |
| 983 } | |
| 984 if (start == -1) { | |
| 985 return Py_NewRef(s); | |
| 986 } | |
| 987 | |
| 988 result = PyDict_GetItem(cache, s); /* borrowed */ | |
| 989 if (result != NULL) { | |
| 990 if (result == sstate->MISSING) { | |
| 991 return PyErr_Format( | |
| 992 PyExc_KeyError, | |
| 993 "Cannot interpolate variables in string %R (cached)", | |
| 994 s); | |
| 995 } | |
| 996 else { | |
| 997 return Py_NewRef(result); | |
| 998 } | |
| 999 } | |
| 1000 | |
| 1001 result = PyList_New(0); | |
| 1002 if (result == 0) { | |
| 1003 return NULL; | |
| 1004 } | |
| 1005 | |
| 1006 rest = 0; | |
| 1007 use_cache = 1; | |
| 1008 | |
| 1009 while (start != -1) { | |
| 1010 if (rest < start) { | |
| 1011 tmp = PyUnicode_Substring(s, rest, start); | |
| 1012 if (tmp == NULL) { | |
| 1013 goto error; | |
| 1014 } | |
| 1015 if (PyList_Append(result, tmp) < 0) { | |
| 1016 py_clear_ref(&tmp); | |
| 1017 goto error; | |
| 1018 } | |
| 1019 py_clear_ref(&tmp); | |
| 1020 } | |
| 1021 end = PyUnicode_Find(s, sstate->ENDTOK, start+2, s_len, 1); | |
| 1022 if (end == -2) { | |
| 1023 goto error; | |
| 1024 } | |
| 1025 if (end == -1) { | |
| 1026 rest = start; | |
| 1027 break; | |
| 1028 } | |
| 1029 | |
| 1030 varname = PyUnicode_Substring(s, start+2, end); /* 2 == len(STARTTOK) */ | |
| 1031 if (varname == NULL) { | |
| 1032 goto error; | |
| 1033 } | |
| 1034 | |
| 1035 tmp = _fast_split_filters(varname, NULL, sstate); | |
| 1036 if (tmp == NULL) { | |
| 1037 goto error; | |
| 1038 } | |
| 1039 if (PyTuple_Size(tmp) != 2) { | |
| 1040 PyErr_SetString(PyExc_TypeError, "tuple of size 2 expected"); | |
| 1041 py_clear_ref(&tmp); | |
| 1042 goto error; | |
| 1043 } | |
| 1044 /* Unpack the result tuple */ | |
| 1045 /* borrowed -- cannot fail -- need ownership */ | |
| 1046 varname = Py_NewRef(PyTuple_GetItem(tmp, 0)); | |
| 1047 /* borrowed -- cannot fail -- need ownership */ | |
| 1048 filters = Py_NewRef(PyTuple_GetItem(tmp, 1)); | |
| 1049 py_clear_ref(&tmp); | |
| 1050 | |
| 1051 tmp = PyObject_CallMethod( | |
| 1052 config, "_getvar_s_with_cache_info", "O", varname); | |
| 1053 if (tmp == NULL) { | |
| 1054 if (PyErr_ExceptionMatches(PyExc_KeyError)) { | |
| 1055 cacheable = 1; | |
| 1056 if (PySequence_Contains(filters, sstate->NONE_FILTER) == 1) { | |
| 1057 PyErr_Clear(); | |
| 1058 varvalue = Py_NewRef(Py_None); | |
| 1059 } | |
| 1060 else { | |
| 1061 if (PySequence_Contains(filters, sstate->EMPTY_FILTER) == 1) { | |
| 1062 PyErr_Clear(); | |
| 1063 varvalue = Py_NewRef(sstate->EMPTY_STR); | |
| 1064 } | |
| 1065 else { | |
| 1066 PyErr_Fetch(&err_type, &err_value, &err_tb); | |
| 1067 /* this does NOT steal */ | |
| 1068 PyDict_SetItem(cache, s, sstate->MISSING); | |
| 1069 PyErr_Restore(err_type, err_value, err_tb); | |
| 1070 goto error; | |
| 1071 } | |
| 1072 } | |
| 1073 } | |
| 1074 else { | |
| 1075 /* other exception/error than KeyError */ | |
| 1076 goto error; | |
| 1077 } | |
| 1078 } | |
| 1079 else { | |
| 1080 if (PyTuple_Size(tmp) != 2) { | |
| 1081 py_clear_ref(&tmp); | |
| 1082 PyErr_SetString(PyExc_TypeError, "tuple of size 2 expected"); | |
| 1083 goto error; | |
| 1084 } | |
| 1085 /* unpack the result */ | |
| 1087 /* borrowed -- but want own */ | 1086 /* borrowed -- but want own */ |
| 1088 varvalue = Py_NewRef(PyTuple_GetItem(tmp, 0)); | 1087 varvalue = Py_NewRef(PyTuple_GetItem(tmp, 0)); |
| 1089 cacheable = PyObject_IsTrue(PyTuple_GetItem(tmp, 1)); | 1088 cacheable = PyObject_IsTrue(PyTuple_GetItem(tmp, 1)); |
| 1090 py_clear_ref(&tmp); | 1089 py_clear_ref(&tmp); |
| 1091 } | 1090 } |
