mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	* listobject.c (list_ass_slice): XDECREF instead of DECREF so
setlistslice() can be used to cut the unused part out of a freshly made slice (as done by bagof()). [needed by the next mod!] * structural changes to bagof(), map() etc.
This commit is contained in:
		
							parent
							
								
									4bd023f882
								
							
						
					
					
						commit
						dc4b93db70
					
				
					 2 changed files with 127 additions and 186 deletions
				
			
		|  | @ -401,9 +401,9 @@ list_ass_slice(a, ilow, ihigh, v) | ||||||
| 		ihigh = a->ob_size; | 		ihigh = a->ob_size; | ||||||
| 	item = a->ob_item; | 	item = a->ob_item; | ||||||
| 	d = n - (ihigh-ilow); | 	d = n - (ihigh-ilow); | ||||||
| 	if (d <= 0) { /* Delete -d items; DECREF ihigh-ilow items */ | 	if (d <= 0) { /* Delete -d items; XDECREF ihigh-ilow items */ | ||||||
| 		for (k = ilow; k < ihigh; k++) | 		for (k = ilow; k < ihigh; k++) | ||||||
| 			DECREF(item[k]); | 			XDECREF(item[k]); | ||||||
| 		if (d < 0) { | 		if (d < 0) { | ||||||
| 			for (/*k = ihigh*/; k < a->ob_size; k++) | 			for (/*k = ihigh*/; k < a->ob_size; k++) | ||||||
| 				item[k+d] = item[k]; | 				item[k+d] = item[k]; | ||||||
|  | @ -412,7 +412,7 @@ list_ass_slice(a, ilow, ihigh, v) | ||||||
| 			a->ob_item = item; | 			a->ob_item = item; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	else { /* Insert d items; DECREF ihigh-ilow items */ | 	else { /* Insert d items; XDECREF ihigh-ilow items */ | ||||||
| 		RESIZE(item, object *, a->ob_size + d); | 		RESIZE(item, object *, a->ob_size + d); | ||||||
| 		if (item == NULL) { | 		if (item == NULL) { | ||||||
| 			err_nomem(); | 			err_nomem(); | ||||||
|  | @ -421,13 +421,13 @@ list_ass_slice(a, ilow, ihigh, v) | ||||||
| 		for (k = a->ob_size; --k >= ihigh; ) | 		for (k = a->ob_size; --k >= ihigh; ) | ||||||
| 			item[k+d] = item[k]; | 			item[k+d] = item[k]; | ||||||
| 		for (/*k = ihigh-1*/; k >= ilow; --k) | 		for (/*k = ihigh-1*/; k >= ilow; --k) | ||||||
| 			DECREF(item[k]); | 			XDECREF(item[k]); | ||||||
| 		a->ob_item = item; | 		a->ob_item = item; | ||||||
| 		a->ob_size += d; | 		a->ob_size += d; | ||||||
| 	} | 	} | ||||||
| 	for (k = 0; k < n; k++, ilow++) { | 	for (k = 0; k < n; k++, ilow++) { | ||||||
| 		object *w = b->ob_item[k]; | 		object *w = b->ob_item[k]; | ||||||
| 		INCREF(w); | 		XINCREF(w); | ||||||
| 		item[ilow] = w; | 		item[ilow] = w; | ||||||
| 	} | 	} | ||||||
| 	return 0; | 	return 0; | ||||||
|  |  | ||||||
|  | @ -71,55 +71,37 @@ builtin_bagof(self, args) | ||||||
| 	object *self; | 	object *self; | ||||||
| 	object *args; | 	object *args; | ||||||
| { | { | ||||||
| 	object *func, *seq, *arg, *result; | 	object *func, *seq, *result; | ||||||
| 	sequence_methods *sqf; | 	sequence_methods *sqf; | ||||||
| 	int len, newfunc = 0; | 	int len; | ||||||
| 	register int i,j; | 	register int i, j; | ||||||
| 	static char bagof_err[] = "bagof() requires 1 or 2 args"; |  | ||||||
| 
 | 
 | ||||||
| 	if (args == NULL) { | 	if (!getargs(args, "(OO)", &func, &seq)) | ||||||
| 		err_setstr(TypeError, bagof_err); |  | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if (is_tupleobject(args)) { | 	if (is_stringobject(func)) { | ||||||
| 		if (gettuplesize(args) != 2) { | 		if ((func = exec_eval(func, lambda_input)) == NULL) | ||||||
| 			err_setstr(TypeError, bagof_err); |  | ||||||
| 			return NULL; | 			return NULL; | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		func = gettupleitem(args, 0); |  | ||||||
| 		seq  = gettupleitem(args, 1); |  | ||||||
| 
 |  | ||||||
| 		if (is_stringobject(func)) { |  | ||||||
| 			if ((func = exec_eval(func, lambda_input)) == NULL) |  | ||||||
| 				return NULL; |  | ||||||
| 			newfunc = 1; |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 	else { | 	else { | ||||||
| 		func = None; | 		INCREF(func); | ||||||
| 		seq  = args; |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* check for special cases; strings and tuples are returned as same */ |  | ||||||
| 	if (is_stringobject(seq)) { | 	if (is_stringobject(seq)) { | ||||||
| 		object *r = filterstring(func, seq); | 		object *r = filterstring(func, seq); | ||||||
| 		if (newfunc) | 		DECREF(func); | ||||||
| 			DECREF(func); |  | ||||||
| 		return r; | 		return r; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	else if (is_tupleobject(seq)) { | 	if (is_tupleobject(seq)) { | ||||||
| 		object *r = filtertuple(func, seq); | 		object *r = filtertuple(func, seq); | ||||||
| 		if (newfunc) | 		DECREF(func); | ||||||
| 			DECREF(func); |  | ||||||
| 		return r; | 		return r; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (! (sqf = seq->ob_type->tp_as_sequence)) { | 	if ((sqf = seq->ob_type->tp_as_sequence) == NULL) { | ||||||
| 		err_setstr(TypeError, | 		err_setstr(TypeError, | ||||||
| 			   "argument to bagof() must be a sequence type"); | 			   "argument 2 to bagof() must be a sequence type"); | ||||||
| 		goto Fail_2; | 		goto Fail_2; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -130,65 +112,51 @@ builtin_bagof(self, args) | ||||||
| 		INCREF(seq); | 		INCREF(seq); | ||||||
| 		result = seq; | 		result = seq; | ||||||
| 	} | 	} | ||||||
| 	else | 	else { | ||||||
| 		if ((result = newlistobject(len)) == NULL) | 		if ((result = newlistobject(len)) == NULL) | ||||||
| 			goto Fail_2; | 			goto Fail_2; | ||||||
| 
 | 	} | ||||||
| 	if ((arg = newtupleobject(1)) == NULL) |  | ||||||
| 		goto Fail_1; |  | ||||||
| 
 | 
 | ||||||
| 	for (i = j = 0; i < len; ++i) { | 	for (i = j = 0; i < len; ++i) { | ||||||
| 		object *ele, *value; | 		object *item, *good; | ||||||
|  | 		int ok; | ||||||
| 
 | 
 | ||||||
| 		if (arg->ob_refcnt > 1) { | 		if ((item = (*sqf->sq_item)(seq, i)) == NULL) | ||||||
|  | 			goto Fail_1; | ||||||
|  | 
 | ||||||
|  | 		if (func == None) { | ||||||
|  | 			good = item; | ||||||
|  | 		} | ||||||
|  | 		else { | ||||||
|  | 			object *arg = mkvalue("(O)", item); | ||||||
|  | 			DECREF(item); | ||||||
|  | 			if (arg == NULL) | ||||||
|  | 				goto Fail_1; | ||||||
|  | 			good = call_object(func, arg); | ||||||
| 			DECREF(arg); | 			DECREF(arg); | ||||||
| 			if ((arg = newtupleobject(1)) == NULL) | 			if (good == NULL) | ||||||
| 				goto Fail_1; | 				goto Fail_1; | ||||||
| 		} | 		} | ||||||
| 
 | 		ok = testbool(good); | ||||||
| 		if ((ele = (*sqf->sq_item)(seq, i)) == NULL) | 		DECREF(good); | ||||||
| 			goto Fail_0; | 		if (ok) { | ||||||
| 
 | 			INCREF(item); | ||||||
| 		if (func == None) | 			if (setlistitem(result, j++, item) < 0) | ||||||
| 			value = ele; | 				goto Fail_1; | ||||||
| 		else { |  | ||||||
| 			if (settupleitem(arg, 0, ele) < 0) |  | ||||||
| 				goto Fail_0; |  | ||||||
| 
 |  | ||||||
| 			if ((value = call_object(func, arg)) == NULL) |  | ||||||
| 				goto Fail_0; |  | ||||||
| 		} | 		} | ||||||
| 
 |  | ||||||
| 		if (testbool(value)) { |  | ||||||
| 			INCREF(ele); |  | ||||||
| 			if (setlistitem(result, j++, ele) < 0) |  | ||||||
| 				goto Fail_0; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		DECREF(value); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* list_ass_slice() expects the rest of the list to be non-null */ |  | ||||||
| 	for (i = j; i < len; ++i) { |  | ||||||
| 		INCREF(None); |  | ||||||
| 		if (setlistitem(result, i, None) < 0) |  | ||||||
| 			goto Fail_0; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	DECREF(arg); | 	if (setlistslice(result, j, len, NULL) < 0) | ||||||
| 	if (newfunc) | 		goto Fail_1; | ||||||
| 		DECREF(func); |  | ||||||
| 
 | 
 | ||||||
| 	(*result->ob_type->tp_as_sequence->sq_ass_slice)(result, j, len, NULL); | 	DECREF(func); | ||||||
| 	return result; | 	return result; | ||||||
| 
 | 
 | ||||||
| Fail_0: |  | ||||||
| 	DECREF(arg); |  | ||||||
| Fail_1: | Fail_1: | ||||||
| 	DECREF(result); | 	DECREF(result); | ||||||
| Fail_2: | Fail_2: | ||||||
| 	if (newfunc) | 	DECREF(func); | ||||||
| 		DECREF(func); |  | ||||||
| 	return NULL; | 	return NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -495,11 +463,15 @@ builtin_map(self, args) | ||||||
| 	if (is_stringobject(func)) { | 	if (is_stringobject(func)) { | ||||||
| 		if ((func = exec_eval(func, lambda_input)) == NULL) | 		if ((func = exec_eval(func, lambda_input)) == NULL) | ||||||
| 			return NULL; | 			return NULL; | ||||||
| 		newfunc = 1; | 	} | ||||||
|  | 	else { | ||||||
|  | 		INCREF(func); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if ((seqs = (sequence *) malloc(n * sizeof(sequence))) == NULL) | 	if ((seqs = NEW(sequence, n)) == NULL) { | ||||||
| 		return err_nomem(); | 		err_nomem(); | ||||||
|  | 		goto Fail_2; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	for (len = -1, i = 0, sqp = seqs; i < n; ++i, ++sqp) { | 	for (len = -1, i = 0, sqp = seqs; i < n; ++i, ++sqp) { | ||||||
| 		int curlen; | 		int curlen; | ||||||
|  | @ -527,74 +499,64 @@ builtin_map(self, args) | ||||||
| 	if ((result = (object *) newlistobject(len)) == NULL) | 	if ((result = (object *) newlistobject(len)) == NULL) | ||||||
| 		goto Fail_2; | 		goto Fail_2; | ||||||
| 
 | 
 | ||||||
| 	if ((args = newtupleobject(n)) == NULL) | 	/* XXX Special case map(None, single_list) could be more efficient */ | ||||||
| 		goto Fail_1; |  | ||||||
| 
 |  | ||||||
| 	for (i = 0; i < len; ++i) { | 	for (i = 0; i < len; ++i) { | ||||||
| 		object *arg, *value; | 		object *arglist, *item; | ||||||
| 
 | 
 | ||||||
| 		if (args->ob_refcnt > 1) { | 		if ((arglist = newtupleobject(n)) == NULL) | ||||||
| 			DECREF(args); | 			goto Fail_1; | ||||||
| 			if ((args = newtupleobject(n)) == NULL) |  | ||||||
| 				goto Fail_1; |  | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		for (j = 0, sqp = seqs; j < n; ++j, ++sqp) { | 		for (j = 0, sqp = seqs; j < n; ++j, ++sqp) { | ||||||
| 			if (i >= sqp->len) { | 			if (i >= sqp->len) { | ||||||
| 				INCREF(None); | 				INCREF(None); | ||||||
| 				if (settupleitem(args, j, None) < 0) | 				item = None; | ||||||
| 					goto Fail_0; |  | ||||||
| 				arg = None; |  | ||||||
| 			} | 			} | ||||||
| 
 |  | ||||||
| 			else { | 			else { | ||||||
| 				if ((arg = (*sqp->sqf->sq_item)(sqp->seq, i)) == NULL) | 				item = (*sqp->sqf->sq_item)(sqp->seq, i); | ||||||
|  | 				if (item == NULL) | ||||||
| 					goto Fail_0; | 					goto Fail_0; | ||||||
| 
 | 
 | ||||||
| 				if (settupleitem(args, j, arg) < 0) |  | ||||||
| 					goto Fail_0; |  | ||||||
| 			} | 			} | ||||||
|  | 			if (settupleitem(arglist, j, item) < 0) | ||||||
|  | 				goto Fail_0; | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		Fail_0: | ||||||
|  | 			DECREF(arglist); | ||||||
|  | 			goto Fail_1; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (func == None) { | 		if (func == None) { | ||||||
| 			if (n == 1)	{ /* avoid creating singleton */ | 			if (n == 1)	{ /* avoid creating singleton */ | ||||||
| 				INCREF(arg); | 				INCREF(item); /* This is arglist[0] !!! */ | ||||||
| 				if (setlistitem(result, i, arg) < 0) | 				DECREF(arglist); | ||||||
| 					goto Fail_0; | 				if (setlistitem(result, i, item) < 0) | ||||||
|  | 					goto Fail_1; | ||||||
| 			} | 			} | ||||||
| 			else { | 			else { | ||||||
| 				INCREF(args); | 				if (setlistitem(result, i, arglist) < 0) | ||||||
| 				if (setlistitem(result, i, args) < 0) | 					goto Fail_1; | ||||||
| 					goto Fail_0; |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		else { | 		else { | ||||||
| 			if ((value = call_object(func, args)) == NULL) | 			object *value = call_object(func, arglist); | ||||||
| 				goto Fail_0; | 			DECREF(arglist); | ||||||
| 
 | 			if (value == NULL) | ||||||
|  | 				goto Fail_1; | ||||||
| 			if (setlistitem((object *) result, i, value) < 0) | 			if (setlistitem((object *) result, i, value) < 0) | ||||||
| 				goto Fail_0; | 				goto Fail_1; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (seqs) free(seqs); | 	if (seqs) DEL(seqs); | ||||||
| 
 | 	DECREF(func); | ||||||
| 	DECREF(args); |  | ||||||
| 	if (newfunc) |  | ||||||
| 		DECREF(func); |  | ||||||
| 
 |  | ||||||
| 	return result; | 	return result; | ||||||
| 
 | 
 | ||||||
| Fail_0: |  | ||||||
| 	DECREF(args); |  | ||||||
| Fail_1: | Fail_1: | ||||||
| 	DECREF(result); | 	DECREF(result); | ||||||
| Fail_2: | Fail_2: | ||||||
| 	if (newfunc) | 	DECREF(func); | ||||||
| 		DECREF(func); | 	if (seqs) DEL(seqs); | ||||||
| 
 |  | ||||||
| 	if (seqs) free(seqs); |  | ||||||
| 
 |  | ||||||
| 	return NULL; | 	return NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -990,7 +952,7 @@ builtin_reduce(self, args) | ||||||
| 	sequence_methods *sqf; | 	sequence_methods *sqf; | ||||||
| 	static char reduce_err[] = "reduce() requires 2 or 3 args"; | 	static char reduce_err[] = "reduce() requires 2 or 3 args"; | ||||||
| 	register int i; | 	register int i; | ||||||
| 	int start = 0, newfunc = 0; | 	int start = 0; | ||||||
| 	int len; | 	int len; | ||||||
| 
 | 
 | ||||||
| 	if (args == NULL || !is_tupleobject(args)) { | 	if (args == NULL || !is_tupleobject(args)) { | ||||||
|  | @ -1018,7 +980,9 @@ builtin_reduce(self, args) | ||||||
| 	if (is_stringobject(func)) { | 	if (is_stringobject(func)) { | ||||||
| 		if ((func = exec_eval(func, lambda_input)) == NULL) | 		if ((func = exec_eval(func, lambda_input)) == NULL) | ||||||
| 			return NULL; | 			return NULL; | ||||||
| 		newfunc = 1; | 	} | ||||||
|  | 	else { | ||||||
|  | 		INCREF(func); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if ((len = (*sqf->sq_length)(seq)) < 0) | 	if ((len = (*sqf->sq_length)(seq)) < 0) | ||||||
|  | @ -1061,20 +1025,17 @@ builtin_reduce(self, args) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	DECREF(args); | 	DECREF(args); | ||||||
| 	if (newfunc) | 	DECREF(func); | ||||||
| 		DECREF(func); |  | ||||||
| 
 | 
 | ||||||
| 	return result; | 	return result; | ||||||
| 
 | 
 | ||||||
| 	/* XXX I hate goto's. I hate goto's. I hate goto's. I hate goto's. */ |  | ||||||
| Fail_0: | Fail_0: | ||||||
| 	DECREF(args); | 	DECREF(args); | ||||||
| 	goto Fail_2; | 	goto Fail_2; | ||||||
| Fail_1: | Fail_1: | ||||||
| 	DECREF(result); | 	DECREF(result); | ||||||
| Fail_2: | Fail_2: | ||||||
| 	if (newfunc) | 	DECREF(func); | ||||||
| 		DECREF(func); |  | ||||||
| 	return NULL; | 	return NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -1310,14 +1271,14 @@ coerce(pv, pw) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* Filter a tuple through a function */ | /* Helper for bagof(): filter a tuple through a function */ | ||||||
| 
 | 
 | ||||||
| static object * | static object * | ||||||
| filtertuple(func, tuple) | filtertuple(func, tuple) | ||||||
| 	object *func; | 	object *func; | ||||||
| 	object *tuple; | 	object *tuple; | ||||||
| { | { | ||||||
| 	object *arg, *result; | 	object *result; | ||||||
| 	register int i, j; | 	register int i, j; | ||||||
| 	int len = gettuplesize(tuple), shared = 0; | 	int len = gettuplesize(tuple), shared = 0; | ||||||
| 
 | 
 | ||||||
|  | @ -1330,42 +1291,34 @@ filtertuple(func, tuple) | ||||||
| 		if ((result = newtupleobject(len)) == NULL) | 		if ((result = newtupleobject(len)) == NULL) | ||||||
| 			return NULL; | 			return NULL; | ||||||
| 
 | 
 | ||||||
| 	if ((arg = newtupleobject(1)) == NULL) |  | ||||||
| 		goto Fail_1; |  | ||||||
| 
 |  | ||||||
| 	for (i = j = 0; i < len; ++i) { | 	for (i = j = 0; i < len; ++i) { | ||||||
| 		object *ele, *value; | 		object *item, *good; | ||||||
|  | 		int ok; | ||||||
| 
 | 
 | ||||||
| 		if (arg->ob_refcnt > 1) { | 		if ((item = gettupleitem(tuple, i)) == NULL) | ||||||
|  | 			goto Fail_1; | ||||||
|  | 		if (func == None) { | ||||||
|  | 			INCREF(item); | ||||||
|  | 			good = item; | ||||||
|  | 		} | ||||||
|  | 		else { | ||||||
|  | 			object *arg = mkvalue("(O)", item); | ||||||
|  | 			if (arg == NULL) | ||||||
|  | 				goto Fail_1; | ||||||
|  | 			good = call_object(func, arg); | ||||||
| 			DECREF(arg); | 			DECREF(arg); | ||||||
| 			if ((arg = newtupleobject(1)) == NULL) | 			if (good == NULL) | ||||||
| 				goto Fail_1; | 				goto Fail_1; | ||||||
| 		} | 		} | ||||||
| 
 | 		ok = testbool(good); | ||||||
| 		if ((ele = gettupleitem(tuple, i)) == NULL) | 		DECREF(good); | ||||||
| 			goto Fail_0; | 		if (ok) { | ||||||
| 		INCREF(ele); | 			INCREF(item); | ||||||
| 
 | 			if (settupleitem(result, j++, item) < 0) | ||||||
| 		if (func == None) | 				goto Fail_1; | ||||||
| 			value = ele; |  | ||||||
| 		else { |  | ||||||
| 			if (settupleitem(arg, 0, ele) < 0) |  | ||||||
| 				goto Fail_0; |  | ||||||
| 
 |  | ||||||
| 			if ((value = call_object(func, arg)) == NULL) |  | ||||||
| 				goto Fail_0; |  | ||||||
| 		} | 		} | ||||||
| 
 |  | ||||||
| 		if (testbool(value)) { |  | ||||||
| 			INCREF(ele); |  | ||||||
| 			if (settupleitem(result, j++, ele) < 0) |  | ||||||
| 				goto Fail_0; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		DECREF(value); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	DECREF(arg); |  | ||||||
| 	if (resizetuple(&result, j) < 0) | 	if (resizetuple(&result, j) < 0) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 
 | 
 | ||||||
|  | @ -1374,8 +1327,6 @@ filtertuple(func, tuple) | ||||||
| 
 | 
 | ||||||
| 	return result; | 	return result; | ||||||
| 
 | 
 | ||||||
| Fail_0: |  | ||||||
| 	DECREF(arg); |  | ||||||
| Fail_1: | Fail_1: | ||||||
| 	if (!shared) | 	if (!shared) | ||||||
| 		DECREF(result); | 		DECREF(result); | ||||||
|  | @ -1383,14 +1334,14 @@ filtertuple(func, tuple) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* Filter a string through a function */ | /* Helper for bagof(): filter a string through a function */ | ||||||
| 
 | 
 | ||||||
| static object * | static object * | ||||||
| filterstring(func, strobj) | filterstring(func, strobj) | ||||||
| 	object *func; | 	object *func; | ||||||
| 	object *strobj; | 	object *strobj; | ||||||
| { | { | ||||||
| 	object *arg, *result; | 	object *result; | ||||||
| 	register int i, j; | 	register int i, j; | ||||||
| 	int len = getstringsize(strobj), shared = 0; | 	int len = getstringsize(strobj), shared = 0; | ||||||
| 
 | 
 | ||||||
|  | @ -1415,36 +1366,28 @@ filterstring(func, strobj) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if ((arg = newtupleobject(1)) == NULL) |  | ||||||
| 		goto Fail_1; |  | ||||||
| 
 |  | ||||||
| 	for (i = j = 0; i < len; ++i) { | 	for (i = j = 0; i < len; ++i) { | ||||||
| 		object *ele, *value; | 		object *item, *arg, *good; | ||||||
|  | 		int ok; | ||||||
| 
 | 
 | ||||||
| 		if (arg->ob_refcnt > 1) { | 		item = (*strobj->ob_type->tp_as_sequence->sq_item)(strobj, i); | ||||||
| 			DECREF(arg); | 		if (item == NULL) | ||||||
| 			if ((arg = newtupleobject(1)) == NULL) | 			goto Fail_1; | ||||||
| 				goto Fail_1; | 		arg = mkvalue("(O)", item); | ||||||
| 		} | 		DECREF(item); | ||||||
| 
 | 		if (arg == NULL) | ||||||
| 		if ((ele = (*strobj->ob_type->tp_as_sequence->sq_item) | 			goto Fail_1; | ||||||
| 		           (strobj, i)) == NULL) | 		good = call_object(func, arg); | ||||||
| 			goto Fail_0; | 		DECREF(arg); | ||||||
| 
 | 		if (good == NULL) | ||||||
| 		if (settupleitem(arg, 0, ele) < 0) | 			goto Fail_1; | ||||||
| 			goto Fail_0; | 		ok = testbool(good); | ||||||
| 
 | 		DECREF(good); | ||||||
| 		if ((value = call_object(func, arg)) == NULL) | 		if (ok) | ||||||
| 			goto Fail_0; |  | ||||||
| 
 |  | ||||||
| 		if (testbool(value)) |  | ||||||
| 			GETSTRINGVALUE((stringobject *)result)[j++] = | 			GETSTRINGVALUE((stringobject *)result)[j++] = | ||||||
| 				GETSTRINGVALUE((stringobject *)ele)[0]; | 				GETSTRINGVALUE((stringobject *)item)[0]; | ||||||
| 
 |  | ||||||
| 		DECREF(value); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	DECREF(arg); |  | ||||||
| 	if (resizestring(&result, j) < 0) | 	if (resizestring(&result, j) < 0) | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 
 | 
 | ||||||
|  | @ -1453,8 +1396,6 @@ filterstring(func, strobj) | ||||||
| 
 | 
 | ||||||
| 	return result; | 	return result; | ||||||
| 
 | 
 | ||||||
| Fail_0: |  | ||||||
| 	DECREF(arg); |  | ||||||
| Fail_1: | Fail_1: | ||||||
| 	if (!shared) | 	if (!shared) | ||||||
| 		DECREF(result); | 		DECREF(result); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Guido van Rossum
						Guido van Rossum