equal
deleted
inserted
replaced
6 This software may be used and distributed according to the terms of |
6 This software may be used and distributed according to the terms of |
7 the GNU General Public License, incorporated herein by reference. |
7 the GNU General Public License, incorporated herein by reference. |
8 */ |
8 */ |
9 |
9 |
10 #include <Python.h> |
10 #include <Python.h> |
|
11 #include <assert.h> |
11 #include <ctype.h> |
12 #include <ctype.h> |
12 #include <stddef.h> |
13 #include <stddef.h> |
13 #include <string.h> |
14 #include <string.h> |
14 |
15 |
15 #include "util.h" |
16 #include "util.h" |
814 Py_XDECREF(heads); |
815 Py_XDECREF(heads); |
815 free(nothead); |
816 free(nothead); |
816 return NULL; |
817 return NULL; |
817 } |
818 } |
818 |
819 |
|
820 /** |
|
821 * Obtain the base revision index entry. |
|
822 * |
|
823 * Callers must ensure that rev >= 0 or illegal memory access may occur. |
|
824 */ |
819 static inline int index_baserev(indexObject *self, int rev) |
825 static inline int index_baserev(indexObject *self, int rev) |
820 { |
826 { |
821 const char *data; |
827 const char *data; |
822 |
828 |
823 if (rev >= self->length - 1) { |
829 if (rev >= self->length - 1) { |
839 { |
845 { |
840 int rev, generaldelta; |
846 int rev, generaldelta; |
841 PyObject *stoparg; |
847 PyObject *stoparg; |
842 int stoprev, iterrev, baserev = -1; |
848 int stoprev, iterrev, baserev = -1; |
843 int stopped; |
849 int stopped; |
844 PyObject *chain = NULL, *value = NULL, *result = NULL; |
850 PyObject *chain = NULL, *result = NULL; |
845 const Py_ssize_t length = index_length(self); |
851 const Py_ssize_t length = index_length(self); |
846 |
852 |
847 if (!PyArg_ParseTuple(args, "iOi", &rev, &stoparg, &generaldelta)) { |
853 if (!PyArg_ParseTuple(args, "iOi", &rev, &stoparg, &generaldelta)) { |
848 return NULL; |
854 return NULL; |
849 } |
855 } |
874 } |
880 } |
875 |
881 |
876 baserev = index_baserev(self, rev); |
882 baserev = index_baserev(self, rev); |
877 |
883 |
878 /* This should never happen. */ |
884 /* This should never happen. */ |
879 if (baserev == -2) { |
885 if (baserev <= -2) { |
880 PyErr_SetString(PyExc_IndexError, "unable to resolve data"); |
886 /* Error should be set by index_deref() */ |
|
887 assert(PyErr_Occurred()); |
881 goto bail; |
888 goto bail; |
882 } |
889 } |
883 |
890 |
884 iterrev = rev; |
891 iterrev = rev; |
885 |
892 |
886 while (iterrev != baserev && iterrev != stoprev) { |
893 while (iterrev != baserev && iterrev != stoprev) { |
887 value = PyInt_FromLong(iterrev); |
894 PyObject *value = PyInt_FromLong(iterrev); |
888 if (value == NULL) { |
895 if (value == NULL) { |
889 goto bail; |
896 goto bail; |
890 } |
897 } |
891 if (PyList_Append(chain, value)) { |
898 if (PyList_Append(chain, value)) { |
892 Py_DECREF(value); |
899 Py_DECREF(value); |
911 } |
918 } |
912 |
919 |
913 baserev = index_baserev(self, iterrev); |
920 baserev = index_baserev(self, iterrev); |
914 |
921 |
915 /* This should never happen. */ |
922 /* This should never happen. */ |
916 if (baserev == -2) { |
923 if (baserev <= -2) { |
917 PyErr_SetString(PyExc_IndexError, "unable to resolve data"); |
924 /* Error should be set by index_deref() */ |
|
925 assert(PyErr_Occurred()); |
918 goto bail; |
926 goto bail; |
919 } |
927 } |
920 } |
928 } |
921 |
929 |
922 if (iterrev == stoprev) { |
930 if (iterrev == stoprev) { |
923 stopped = 1; |
931 stopped = 1; |
924 } |
932 } |
925 else { |
933 else { |
926 value = PyInt_FromLong(iterrev); |
934 PyObject *value = PyInt_FromLong(iterrev); |
927 if (value == NULL) { |
935 if (value == NULL) { |
928 goto bail; |
936 goto bail; |
929 } |
937 } |
930 if (PyList_Append(chain, value)) { |
938 if (PyList_Append(chain, value)) { |
931 Py_DECREF(value); |
939 Py_DECREF(value); |