aboutsummaryrefslogtreecommitdiffstats
path: root/array.c
diff options
context:
space:
mode:
authorAndrew J. Schorr <aschorr@telemetry-investments.com>2020-03-09 15:39:03 -0400
committerAndrew J. Schorr <aschorr@telemetry-investments.com>2020-03-09 15:39:03 -0400
commit2f0eddafa9a66aebf2e2ed1c49a9e8ce9e892a8c (patch)
tree4016815c12f8f28bd6a01b55898a19f8f742642d /array.c
parent6514b3a2f5ed8c593d7d49526a27122989e673d0 (diff)
downloadegawk-2f0eddafa9a66aebf2e2ed1c49a9e8ce9e892a8c.tar.gz
egawk-2f0eddafa9a66aebf2e2ed1c49a9e8ce9e892a8c.tar.bz2
egawk-2f0eddafa9a66aebf2e2ed1c49a9e8ce9e892a8c.zip
Enhance @val_* sorting methods to use the index string as a tie-breaker.
Diffstat (limited to 'array.c')
-rw-r--r--array.c51
1 files changed, 33 insertions, 18 deletions
diff --git a/array.c b/array.c
index 4a0d8569..4ff365ff 100644
--- a/array.c
+++ b/array.c
@@ -35,6 +35,7 @@ static size_t SUBSEPlen;
static char *SUBSEP;
static char indent_char[] = " ";
+static int sort_up_value_type(const void *p1, const void *p2);
static NODE **null_lookup(NODE *symbol, NODE *subs);
static NODE **null_dump(NODE *symbol, NODE *subs);
static const array_funcs_t null_array_func = {
@@ -1075,19 +1076,19 @@ static int
sort_up_value_string(const void *p1, const void *p2)
{
const NODE *t1, *t2;
+ int ret;
t1 = *((const NODE *const *) p1 + 1);
t2 = *((const NODE *const *) p2 + 1);
- if (t1->type == Node_var_array) {
- /* return 0 if t2 is a sub-array too, else return 1 */
- return (t2->type != Node_var_array);
- }
- if (t2->type == Node_var_array)
- return -1; /* t1 (scalar) < t2 (sub-array) */
+ if (t1->type != Node_val || t2->type != Node_val)
+ return sort_up_value_type(p1, p2);
/* t1 and t2 both have string values */
- return cmp_strings(t1, t2);
+ ret = cmp_strings(t1, t2);
+ if (ret != 0)
+ return ret;
+ return sort_up_index_string(p1, p2);
}
@@ -1111,12 +1112,8 @@ sort_up_value_number(const void *p1, const void *p2)
t1 = *((NODE *const *) p1 + 1);
t2 = *((NODE *const *) p2 + 1);
- if (t1->type == Node_var_array) {
- /* return 0 if t2 is a sub-array too, else return 1 */
- return (t2->type != Node_var_array);
- }
- if (t2->type == Node_var_array)
- return -1; /* t1 (scalar) < t2 (sub-array) */
+ if (t1->type != Node_val || t2->type != Node_val)
+ return sort_up_value_type(p1, p2);
ret = cmp_numbers(t1, t2);
if (ret != 0)
@@ -1126,9 +1123,10 @@ sort_up_value_number(const void *p1, const void *p2)
* Use string value to guarantee same sort order on all
* versions of qsort().
*/
- t1 = force_string(t1);
- t2 = force_string(t2);
- return cmp_strings(t1, t2);
+ ret = cmp_strings(force_string(t1), force_string(t2));
+ if (ret != 0)
+ return ret;
+ return sort_up_index_string(p1, p2);
}
@@ -1141,10 +1139,10 @@ sort_down_value_number(const void *p1, const void *p2)
}
-/* sort_up_value_type --- qsort comparison function; ascending value type */
+/* do_sort_up_value_type --- backend comparison on ascending value type */
static int
-sort_up_value_type(const void *p1, const void *p2)
+do_sort_up_value_type(const void *p1, const void *p2)
{
NODE *n1, *n2;
@@ -1163,6 +1161,12 @@ sort_up_value_type(const void *p1, const void *p2)
n1 = *((NODE *const *) p1 + 1);
n2 = *((NODE *const *) p2 + 1);
+ if (n1->type == Node_var && n2->type == Node_var) {
+ /* compare the values of the variables */
+ n1 = n1->var_value;
+ n2 = n2->var_value;
+ }
+
/* 1. Arrays vs. everything else, everything else is less than array */
if (n1->type == Node_var_array) {
/* return 0 if n2 is a sub-array too, else return 1 */
@@ -1208,6 +1212,17 @@ sort_up_value_type(const void *p1, const void *p2)
return cmp_strings(n1, n2);
}
+/* sort_up_value_type --- qsort comparison function; ascending value type */
+
+static int
+sort_up_value_type(const void *p1, const void *p2)
+{
+ int rc = do_sort_up_value_type(p1, p2);
+
+ /* use a tie-breaker if do_sort_up_value_type has no opinion */
+ return rc ? rc : sort_up_index_string(p1, p2);
+}
+
/* sort_down_value_type --- qsort comparison function; descending value type */
static int