summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1993-10-27 14:56:44 (GMT)
committerGuido van Rossum <guido@python.org>1993-10-27 14:56:44 (GMT)
commitdc4b93db7097a34cee492b188ec2fd65c5b9bc4b (patch)
treebff2a16f6aa6674ab8463f118de3124a8f393af7 /Python
parent4bd023f88291cedbae91f2dea4b13509fc5c2d9a (diff)
downloadcpython-dc4b93db7097a34cee492b188ec2fd65c5b9bc4b.zip
cpython-dc4b93db7097a34cee492b188ec2fd65c5b9bc4b.tar.gz
cpython-dc4b93db7097a34cee492b188ec2fd65c5b9bc4b.tar.bz2
* 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.
Diffstat (limited to 'Python')
-rw-r--r--Python/bltinmodule.c305
1 files changed, 123 insertions, 182 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index b95c351..f4d7f47 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -71,55 +71,37 @@ builtin_bagof(self, args)
object *self;
object *args;
{
- object *func, *seq, *arg, *result;
+ object *func, *seq, *result;
sequence_methods *sqf;
- int len, newfunc = 0;
- register int i,j;
- static char bagof_err[] = "bagof() requires 1 or 2 args";
+ int len;
+ register int i, j;
- if (args == NULL) {
- err_setstr(TypeError, bagof_err);
+ if (!getargs(args, "(OO)", &func, &seq))
return NULL;
- }
- if (is_tupleobject(args)) {
- if (gettuplesize(args) != 2) {
- err_setstr(TypeError, bagof_err);
+ if (is_stringobject(func)) {
+ if ((func = exec_eval(func, lambda_input)) == 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 {
- func = None;
- seq = args;
+ INCREF(func);
}
- /* check for special cases; strings and tuples are returned as same */
if (is_stringobject(seq)) {
object *r = filterstring(func, seq);
- if (newfunc)
- DECREF(func);
+ DECREF(func);
return r;
}
- else if (is_tupleobject(seq)) {
+ if (is_tupleobject(seq)) {
object *r = filtertuple(func, seq);
- if (newfunc)
- DECREF(func);
+ DECREF(func);
return r;
}
- if (! (sqf = seq->ob_type->tp_as_sequence)) {
+ if ((sqf = seq->ob_type->tp_as_sequence) == NULL) {
err_setstr(TypeError,
- "argument to bagof() must be a sequence type");
+ "argument 2 to bagof() must be a sequence type");
goto Fail_2;
}
@@ -130,65 +112,51 @@ builtin_bagof(self, args)
INCREF(seq);
result = seq;
}
- else
+ else {
if ((result = newlistobject(len)) == NULL)
goto Fail_2;
-
- if ((arg = newtupleobject(1)) == NULL)
- goto Fail_1;
+ }
for (i = j = 0; i < len; ++i) {
- object *ele, *value;
-
- if (arg->ob_refcnt > 1) {
- DECREF(arg);
- if ((arg = newtupleobject(1)) == NULL)
- goto Fail_1;
- }
+ object *item, *good;
+ int ok;
- if ((ele = (*sqf->sq_item)(seq, i)) == NULL)
- goto Fail_0;
+ if ((item = (*sqf->sq_item)(seq, i)) == NULL)
+ goto Fail_1;
- if (func == None)
- value = ele;
+ if (func == None) {
+ good = item;
+ }
else {
- if (settupleitem(arg, 0, ele) < 0)
- goto Fail_0;
-
- if ((value = call_object(func, arg)) == NULL)
- goto Fail_0;
+ object *arg = mkvalue("(O)", item);
+ DECREF(item);
+ if (arg == NULL)
+ goto Fail_1;
+ good = call_object(func, arg);
+ DECREF(arg);
+ if (good == NULL)
+ goto Fail_1;
}
-
- if (testbool(value)) {
- INCREF(ele);
- if (setlistitem(result, j++, ele) < 0)
- goto Fail_0;
+ ok = testbool(good);
+ DECREF(good);
+ if (ok) {
+ INCREF(item);
+ if (setlistitem(result, j++, item) < 0)
+ goto Fail_1;
}
-
- 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 (newfunc)
- DECREF(func);
+ if (setlistslice(result, j, len, NULL) < 0)
+ goto Fail_1;
- (*result->ob_type->tp_as_sequence->sq_ass_slice)(result, j, len, NULL);
+ DECREF(func);
return result;
-Fail_0:
- DECREF(arg);
Fail_1:
DECREF(result);
Fail_2:
- if (newfunc)
- DECREF(func);
+ DECREF(func);
return NULL;
}
@@ -495,11 +463,15 @@ builtin_map(self, args)
if (is_stringobject(func)) {
if ((func = exec_eval(func, lambda_input)) == NULL)
return NULL;
- newfunc = 1;
+ }
+ else {
+ INCREF(func);
}
- if ((seqs = (sequence *) malloc(n * sizeof(sequence))) == NULL)
- return err_nomem();
+ if ((seqs = NEW(sequence, n)) == NULL) {
+ err_nomem();
+ goto Fail_2;
+ }
for (len = -1, i = 0, sqp = seqs; i < n; ++i, ++sqp) {
int curlen;
@@ -527,74 +499,64 @@ builtin_map(self, args)
if ((result = (object *) newlistobject(len)) == NULL)
goto Fail_2;
- if ((args = newtupleobject(n)) == NULL)
- goto Fail_1;
-
+ /* XXX Special case map(None, single_list) could be more efficient */
for (i = 0; i < len; ++i) {
- object *arg, *value;
+ object *arglist, *item;
- if (args->ob_refcnt > 1) {
- DECREF(args);
- if ((args = newtupleobject(n)) == NULL)
- goto Fail_1;
- }
+ if ((arglist = newtupleobject(n)) == NULL)
+ goto Fail_1;
for (j = 0, sqp = seqs; j < n; ++j, ++sqp) {
if (i >= sqp->len) {
INCREF(None);
- if (settupleitem(args, j, None) < 0)
- goto Fail_0;
- arg = None;
+ item = None;
}
-
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;
- 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 (n == 1) { /* avoid creating singleton */
- INCREF(arg);
- if (setlistitem(result, i, arg) < 0)
- goto Fail_0;
+ INCREF(item); /* This is arglist[0] !!! */
+ DECREF(arglist);
+ if (setlistitem(result, i, item) < 0)
+ goto Fail_1;
}
else {
- INCREF(args);
- if (setlistitem(result, i, args) < 0)
- goto Fail_0;
+ if (setlistitem(result, i, arglist) < 0)
+ goto Fail_1;
}
}
else {
- if ((value = call_object(func, args)) == NULL)
- goto Fail_0;
-
+ object *value = call_object(func, arglist);
+ DECREF(arglist);
+ if (value == NULL)
+ goto Fail_1;
if (setlistitem((object *) result, i, value) < 0)
- goto Fail_0;
+ goto Fail_1;
}
}
- if (seqs) free(seqs);
-
- DECREF(args);
- if (newfunc)
- DECREF(func);
-
+ if (seqs) DEL(seqs);
+ DECREF(func);
return result;
-Fail_0:
- DECREF(args);
Fail_1:
DECREF(result);
Fail_2:
- if (newfunc)
- DECREF(func);
-
- if (seqs) free(seqs);
-
+ DECREF(func);
+ if (seqs) DEL(seqs);
return NULL;
}
@@ -990,7 +952,7 @@ builtin_reduce(self, args)
sequence_methods *sqf;
static char reduce_err[] = "reduce() requires 2 or 3 args";
register int i;
- int start = 0, newfunc = 0;
+ int start = 0;
int len;
if (args == NULL || !is_tupleobject(args)) {
@@ -1018,7 +980,9 @@ builtin_reduce(self, args)
if (is_stringobject(func)) {
if ((func = exec_eval(func, lambda_input)) == NULL)
return NULL;
- newfunc = 1;
+ }
+ else {
+ INCREF(func);
}
if ((len = (*sqf->sq_length)(seq)) < 0)
@@ -1061,20 +1025,17 @@ builtin_reduce(self, args)
}
DECREF(args);
- if (newfunc)
- DECREF(func);
+ DECREF(func);
return result;
- /* XXX I hate goto's. I hate goto's. I hate goto's. I hate goto's. */
Fail_0:
DECREF(args);
goto Fail_2;
Fail_1:
DECREF(result);
Fail_2:
- if (newfunc)
- DECREF(func);
+ DECREF(func);
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 *
filtertuple(func, tuple)
object *func;
object *tuple;
{
- object *arg, *result;
+ object *result;
register int i, j;
int len = gettuplesize(tuple), shared = 0;
@@ -1330,42 +1291,34 @@ filtertuple(func, tuple)
if ((result = newtupleobject(len)) == NULL)
return NULL;
- if ((arg = newtupleobject(1)) == NULL)
- goto Fail_1;
-
for (i = j = 0; i < len; ++i) {
- object *ele, *value;
+ object *item, *good;
+ int ok;
- if (arg->ob_refcnt > 1) {
- DECREF(arg);
- if ((arg = newtupleobject(1)) == NULL)
- goto Fail_1;
+ if ((item = gettupleitem(tuple, i)) == NULL)
+ goto Fail_1;
+ if (func == None) {
+ INCREF(item);
+ good = item;
}
-
- if ((ele = gettupleitem(tuple, i)) == NULL)
- goto Fail_0;
- INCREF(ele);
-
- if (func == None)
- value = ele;
else {
- if (settupleitem(arg, 0, ele) < 0)
- goto Fail_0;
-
- if ((value = call_object(func, arg)) == NULL)
- goto Fail_0;
+ object *arg = mkvalue("(O)", item);
+ if (arg == NULL)
+ goto Fail_1;
+ good = call_object(func, arg);
+ DECREF(arg);
+ if (good == NULL)
+ goto Fail_1;
}
-
- if (testbool(value)) {
- INCREF(ele);
- if (settupleitem(result, j++, ele) < 0)
- goto Fail_0;
+ ok = testbool(good);
+ DECREF(good);
+ if (ok) {
+ INCREF(item);
+ if (settupleitem(result, j++, item) < 0)
+ goto Fail_1;
}
-
- DECREF(value);
}
- DECREF(arg);
if (resizetuple(&result, j) < 0)
return NULL;
@@ -1374,8 +1327,6 @@ filtertuple(func, tuple)
return result;
-Fail_0:
- DECREF(arg);
Fail_1:
if (!shared)
DECREF(result);
@@ -1383,14 +1334,14 @@ Fail_1:
}
-/* Filter a string through a function */
+/* Helper for bagof(): filter a string through a function */
static object *
filterstring(func, strobj)
object *func;
object *strobj;
{
- object *arg, *result;
+ object *result;
register int i, j;
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) {
- object *ele, *value;
-
- if (arg->ob_refcnt > 1) {
- DECREF(arg);
- if ((arg = newtupleobject(1)) == NULL)
- goto Fail_1;
- }
-
- if ((ele = (*strobj->ob_type->tp_as_sequence->sq_item)
- (strobj, i)) == NULL)
- goto Fail_0;
-
- if (settupleitem(arg, 0, ele) < 0)
- goto Fail_0;
-
- if ((value = call_object(func, arg)) == NULL)
- goto Fail_0;
-
- if (testbool(value))
+ object *item, *arg, *good;
+ int ok;
+
+ item = (*strobj->ob_type->tp_as_sequence->sq_item)(strobj, i);
+ if (item == NULL)
+ goto Fail_1;
+ arg = mkvalue("(O)", item);
+ DECREF(item);
+ if (arg == NULL)
+ goto Fail_1;
+ good = call_object(func, arg);
+ DECREF(arg);
+ if (good == NULL)
+ goto Fail_1;
+ ok = testbool(good);
+ DECREF(good);
+ if (ok)
GETSTRINGVALUE((stringobject *)result)[j++] =
- GETSTRINGVALUE((stringobject *)ele)[0];
-
- DECREF(value);
+ GETSTRINGVALUE((stringobject *)item)[0];
}
- DECREF(arg);
if (resizestring(&result, j) < 0)
return NULL;
@@ -1453,8 +1396,6 @@ filterstring(func, strobj)
return result;
-Fail_0:
- DECREF(arg);
Fail_1:
if (!shared)
DECREF(result);