comparison mercurial/cext/revlog.c @ 33174:f4f52bb362e6

revlog: address review feedback for deltachain C implementation * Scope of "value" is reduced * index_baserev() is documented * Error is no longer redundantly set for -2 return values * Error values are compared <= -2 instead of == -2 to protect against odd failure scenarios
author Gregory Szorc <gregory.szorc@gmail.com>
date Sat, 01 Jul 2017 19:35:17 -0700
parents 6d678ab1b10d
children f501322512b6
comparison
equal deleted inserted replaced
33173:4b0da963586d 33174:f4f52bb362e6
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);