mirror of
https://github.com/python/cpython.git
synced 2025-08-31 22:18:28 +00:00
listobject.c: added optional cmp function to list.sort().
This commit is contained in:
parent
7b2c03f39b
commit
e10a19ea6d
1 changed files with 54 additions and 7 deletions
|
@ -26,6 +26,8 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
#include "allobjects.h"
|
#include "allobjects.h"
|
||||||
#include "modsupport.h"
|
#include "modsupport.h"
|
||||||
|
#include "compile.h" /* Needed by ceval.h */
|
||||||
|
#include "ceval.h" /* For call_object() */
|
||||||
|
|
||||||
object *
|
object *
|
||||||
newlistobject(size)
|
newlistobject(size)
|
||||||
|
@ -471,11 +473,46 @@ listappend(self, args)
|
||||||
return ins(self, (int) self->ob_size, args);
|
return ins(self, (int) self->ob_size, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static object *cmpfunc;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cmp(v, w)
|
cmp(v, w)
|
||||||
char *v, *w;
|
char *v, *w;
|
||||||
{
|
{
|
||||||
return cmpobject(* (object **) v, * (object **) w);
|
object *t, *res;
|
||||||
|
long i;
|
||||||
|
|
||||||
|
if (err_occurred())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (cmpfunc == NULL)
|
||||||
|
return cmpobject(* (object **) v, * (object **) w);
|
||||||
|
|
||||||
|
/* Call the user-supplied comparison function */
|
||||||
|
t = newtupleobject(2);
|
||||||
|
if (t == NULL)
|
||||||
|
return 0;
|
||||||
|
INCREF(* (object **) v);
|
||||||
|
settupleitem(t, 0, * (object **) v);
|
||||||
|
INCREF(* (object **) w);
|
||||||
|
settupleitem(t, 1, * (object **) w);
|
||||||
|
res = call_object(cmpfunc, t);
|
||||||
|
DECREF(t);
|
||||||
|
if (res == NULL)
|
||||||
|
return 0;
|
||||||
|
if (!is_intobject(res)) {
|
||||||
|
err_setstr(TypeError, "comparison function should return int");
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
i = getintvalue(res);
|
||||||
|
if (i < 0)
|
||||||
|
i = -1;
|
||||||
|
else if (i > 0)
|
||||||
|
i = 1;
|
||||||
|
}
|
||||||
|
DECREF(res);
|
||||||
|
return (int) i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static object *
|
static object *
|
||||||
|
@ -483,14 +520,24 @@ listsort(self, args)
|
||||||
listobject *self;
|
listobject *self;
|
||||||
object *args;
|
object *args;
|
||||||
{
|
{
|
||||||
if (args != NULL) {
|
object *save_cmpfunc;
|
||||||
err_badarg();
|
if (self->ob_size <= 1) {
|
||||||
return NULL;
|
INCREF(None);
|
||||||
|
return None;
|
||||||
}
|
}
|
||||||
err_clear();
|
save_cmpfunc = cmpfunc;
|
||||||
if (self->ob_size > 1)
|
cmpfunc = args;
|
||||||
qsort((char *)self->ob_item,
|
if (cmpfunc != NULL) {
|
||||||
|
/* Test the comparison function for obvious errors */
|
||||||
|
(void) cmp(&self->ob_item[0], &self->ob_item[1]);
|
||||||
|
if (err_occurred()) {
|
||||||
|
cmpfunc = save_cmpfunc;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qsort((char *)self->ob_item,
|
||||||
(int) self->ob_size, sizeof(object *), cmp);
|
(int) self->ob_size, sizeof(object *), cmp);
|
||||||
|
cmpfunc = save_cmpfunc;
|
||||||
if (err_occurred())
|
if (err_occurred())
|
||||||
return NULL;
|
return NULL;
|
||||||
INCREF(None);
|
INCREF(None);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue