Skip to content

Commit

Permalink
restored ucv_array_sort() and ucv_object_sort() api,
Browse files Browse the repository at this point in the history
and added ucv_array_sort_r() and ucv_object_sort_r(), using a more specific typed compare function, and a user void pointer
  • Loading branch information
IdWV committed Nov 1, 2024
1 parent c387c96 commit 5f64ba3
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 30 deletions.
6 changes: 4 additions & 2 deletions include/ucode/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -391,15 +391,17 @@ uc_value_t *ucv_array_pop(uc_value_t *);
uc_value_t *ucv_array_push(uc_value_t *, uc_value_t *);
uc_value_t *ucv_array_shift(uc_value_t *);
uc_value_t *ucv_array_unshift(uc_value_t *, uc_value_t *);
void ucv_array_sort(uc_value_t *, int (*)(uc_value_t * const *, uc_value_t * const *,void *),void *);
void ucv_array_sort(uc_value_t *, int (*)(const void *, const void *));
void ucv_array_sort_r(uc_value_t *, int (*)(const uc_value_t *, const uc_value_t *,void *),void *);
bool ucv_array_delete(uc_value_t *, size_t, size_t);
bool ucv_array_set(uc_value_t *, size_t, uc_value_t *);
size_t ucv_array_length(uc_value_t *);

uc_value_t *ucv_object_new(uc_vm_t *);
uc_value_t *ucv_object_get(uc_value_t *, const char *, bool *);
bool ucv_object_add(uc_value_t *, const char *, uc_value_t *);
void ucv_object_sort(uc_value_t *, int (*)(struct lh_entry * const *, struct lh_entry * const *,void *), void *);
void ucv_object_sort(uc_value_t *, int (*)(const void *, const void *));
void ucv_object_sort_r(uc_value_t *, int (*)(const struct lh_entry *, const struct lh_entry *,void *), void *);
bool ucv_object_delete(uc_value_t *, const char *);
size_t ucv_object_length(uc_value_t *);

Expand Down
39 changes: 21 additions & 18 deletions lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -1409,11 +1409,13 @@ typedef struct {
} sort_ctx_t;

static int
default_cmp( uc_value_t *v1, uc_value_t *v2,sort_ctx_t *ctx)
default_cmp( const uc_value_t *cv1, const uc_value_t *cv2, sort_ctx_t *ctx )
{
char *s1, *s2;
bool f1, f2;
int res;
uc_value_t *v1 = (uc_value_t *)cv1;
uc_value_t *v2 = (uc_value_t *)cv2;

/* when both operands are numeric then compare numerically */
if ((ucv_type(v1) == UC_INTEGER || ucv_type(v1) == UC_DOUBLE) &&
Expand All @@ -1436,21 +1438,25 @@ default_cmp( uc_value_t *v1, uc_value_t *v2,sort_ctx_t *ctx)
}

static int
array_sort_fn(uc_value_t * const *v1, uc_value_t * const *v2,sort_ctx_t *ctx)
array_sort_fn(const uc_value_t *cv1, const uc_value_t *cv2, void *user )
{
uc_value_t *rv, *null = ucv_int64_new(0);
int res;
sort_ctx_t *ctx = user;

if (!ctx->fn)
return default_cmp(*v1, *v2, ctx);
return default_cmp(cv1, cv2, ctx);

if (ctx->ex)
return 0;

uc_value_t *v1 = (uc_value_t *)cv1;
uc_value_t *v2 = (uc_value_t *)cv2;

uc_vm_ctx_push(ctx->vm);
uc_vm_stack_push(ctx->vm, ucv_get(ctx->fn));
uc_vm_stack_push(ctx->vm, ucv_get(*v1));
uc_vm_stack_push(ctx->vm, ucv_get(*v2));
uc_vm_stack_push(ctx->vm, ucv_get(v1));
uc_vm_stack_push(ctx->vm, ucv_get(v2));

if (uc_vm_call(ctx->vm, true, 2)) {
ctx->ex = true;
Expand All @@ -1469,23 +1475,24 @@ array_sort_fn(uc_value_t * const *v1, uc_value_t * const *v2,sort_ctx_t *ctx)
}

static int
object_sort_fn(struct lh_entry * const *e1, struct lh_entry * const *e2,sort_ctx_t *ctx)
object_sort_fn(const struct lh_entry *e1, const struct lh_entry *e2, void *user )
{
uc_value_t *rv, *null = ucv_int64_new(0);
int res;
sort_ctx_t *ctx = user;

if (!ctx->fn)
return strcmp((char *)lh_entry_k(*e1), (char *)lh_entry_k(*e2));
return strcmp((char *)lh_entry_k(e1), (char *)lh_entry_k(e2));

if (ctx->ex)
return 0;

uc_vm_ctx_push(ctx->vm);
uc_vm_stack_push(ctx->vm, ucv_get(ctx->fn));
uc_vm_stack_push(ctx->vm, ucv_string_new((char *)lh_entry_k(*e1)));
uc_vm_stack_push(ctx->vm, ucv_string_new((char *)lh_entry_k(*e2)));
uc_vm_stack_push(ctx->vm, ucv_get((uc_value_t *)lh_entry_v(*e1)));
uc_vm_stack_push(ctx->vm, ucv_get((uc_value_t *)lh_entry_v(*e2)));
uc_vm_stack_push(ctx->vm, ucv_string_new((char *)lh_entry_k(e1)));
uc_vm_stack_push(ctx->vm, ucv_string_new((char *)lh_entry_k(e2)));
uc_vm_stack_push(ctx->vm, ucv_get((uc_value_t *)lh_entry_v(e1)));
uc_vm_stack_push(ctx->vm, ucv_get((uc_value_t *)lh_entry_v(e2)));

if (uc_vm_call(ctx->vm, true, 4)) {
ctx->ex = true;
Expand Down Expand Up @@ -1541,19 +1548,15 @@ uc_sort(uc_vm_t *vm, size_t nargs)
if (!assert_mutable(vm, val))
return NULL;

sort_ctx_t ctx = { .vm = vm, .fn = fn, .ex = false };
sort_ctx_t ctx = { .vm = vm, .fn = fn, .ex = false };

switch (ucv_type(val)) {
case UC_ARRAY:
ucv_array_sort(val,
(int (*)(uc_value_t * const *, uc_value_t * const *,void *))array_sort_fn,
&ctx);
ucv_array_sort_r(val, array_sort_fn, &ctx );
break;

case UC_OBJECT:
ucv_object_sort(val,
(int (*)(struct lh_entry * const *, struct lh_entry * const * ,void *))object_sort_fn,
&ctx);
ucv_object_sort_r(val, object_sort_fn, &ctx );
break;

default:
Expand Down
6 changes: 3 additions & 3 deletions lib/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -2232,9 +2232,9 @@ uc_fs_basename(uc_vm_t *vm, size_t nargs)
}

static int
uc_fs_lsdir_sort_fn(uc_value_t * const *v1, uc_value_t * const *v2,void *)
uc_fs_lsdir_sort_fn( const uc_value_t *v1, const uc_value_t *v2,void *)
{
return strcmp(ucv_string_get(*v1), ucv_string_get(*v2));
return strcmp(ucv_string_get(v1), ucv_string_get(v2));
}

/**
Expand Down Expand Up @@ -2307,7 +2307,7 @@ uc_fs_lsdir(uc_vm_t *vm, size_t nargs)

closedir(d);

ucv_array_sort(res, uc_fs_lsdir_sort_fn,0);
ucv_array_sort_r(res, uc_fs_lsdir_sort_fn,0);

return res;
}
Expand Down
53 changes: 46 additions & 7 deletions types.c
Original file line number Diff line number Diff line change
Expand Up @@ -782,17 +782,38 @@ ucv_array_unshift(uc_value_t *uv, uc_value_t *item)
return item;
}

static int
pointer_removing_sort_fn( const void *v1, const void *v2, void *user )
{
void **inbetween = user;
void *const *pv1 = v1;
void *const *pv2 = v2;
int (*fn)( const void *, const void *, void *) = inbetween[ 0 ];
return (*fn)( pv1 ? *pv1 : 0, pv2 ? *pv2 : 0, inbetween[ 1 ] );
}

void
ucv_array_sort(uc_value_t *uv, int (*cmp)(uc_value_t * const *,uc_value_t * const *,void *),void *ctx)
ucv_array_sort_r(uc_value_t *uv, int (*cmp)(const uc_value_t * , const uc_value_t *,void *),void *ctx)
{
uc_array_t *array = (uc_array_t *)uv;

if (ucv_type(uv) != UC_ARRAY || array->count <= 1)
return;

void *inbetween[2] = { cmp, ctx };
qsort_r(array->entries, array->count, sizeof(array->entries[0]),
(int (*)(const void *,const void *,void *))cmp,
ctx);
pointer_removing_sort_fn, inbetween );
}

void
ucv_array_sort(uc_value_t *uv, int (*cmp)(const void *,const void *))
{
uc_array_t *array = (uc_array_t *)uv;

if (ucv_type(uv) != UC_ARRAY || array->count <= 1)
return;

qsort(array->entries, array->count, sizeof(array->entries[0]), cmp );
}

bool
Expand Down Expand Up @@ -985,8 +1006,8 @@ ucv_object_add(uc_value_t *uv, const char *key, uc_value_t *val)
}

void
ucv_object_sort(uc_value_t *uv,
int (*cmp)(struct lh_entry * const *, struct lh_entry * const *, void *), void *ctx )
ucv_object_sort_r(uc_value_t *uv,
int (*cmp)( const struct lh_entry *, const struct lh_entry *, void *), void *ctx )
{
uc_object_t *object = (uc_object_t *)uv;
struct lh_table *t;
Expand All @@ -1007,9 +1028,10 @@ ucv_object_sort(uc_value_t *uv,
if (!keys.entries)
return;

void *inbetween[2] = { cmp, ctx };

qsort_r(keys.entries, keys.count, sizeof(keys.entries[0]),
(int (*)(const void *,const void *,void *))cmp,
ctx);
pointer_removing_sort_fn, inbetween );

for (i = 0; i < keys.count; i++) {
e = keys.entries[i];
Expand All @@ -1029,6 +1051,23 @@ ucv_object_sort(uc_value_t *uv,
uc_vector_clear(&keys);
}

static int
pointer_adding_sort_fn( const struct lh_entry *e1, const struct lh_entry *e2, void *user )
{
const void *p1 = e1;
const void *p2 = e2;
int (*cmp)( const void *, const void * ) = user;
return cmp( &p1, &p2 );
}

void
ucv_object_sort(uc_value_t *uv,
int (*cmp)( const void *, const void * ) )
{
return ucv_object_sort_r( uv, pointer_adding_sort_fn, cmp );
}


bool
ucv_object_delete(uc_value_t *uv, const char *key)
{
Expand Down

0 comments on commit 5f64ba3

Please sign in to comment.