diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2020-01-24 09:36:43 +0200 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2020-01-24 09:36:43 +0200 |
commit | c0dfb9269380ff5a90dbf6606f64989848304527 (patch) | |
tree | 2d21a4e0bc3d75b8a98cc6b0b3db8e7fafd90dbd /array.c | |
parent | 1ef484e65a03a8360434c404c9a3006671bab2f7 (diff) | |
download | egawk-c0dfb9269380ff5a90dbf6606f64989848304527.tar.gz egawk-c0dfb9269380ff5a90dbf6606f64989848304527.tar.bz2 egawk-c0dfb9269380ff5a90dbf6606f64989848304527.zip |
Fix assertion error in sorted loops for SYMTAB/FUNCTAB.
Diffstat (limited to 'array.c')
-rw-r--r-- | array.c | 39 |
1 files changed, 37 insertions, 2 deletions
@@ -832,6 +832,14 @@ asort_actual(int nargs, sort_context_t ctxt) _("asort: first argument not an array") : _("asorti: first argument not an array")); } + else if (array == symbol_table) + fatal(ctxt == ASORT ? + _("asort: first argument cannot be SYMTAB") : + _("asorti: first argument cannot be SYMTAB")); + else if (array == func_table) + fatal(ctxt == ASORT ? + _("asort: first argument cannot be FUNCTAB") : + _("asorti: first argument cannot be FUNCTAB")); if (dest != NULL) { for (r = dest->parent_array; r != NULL; r = r->parent_array) { @@ -1145,20 +1153,47 @@ static int sort_up_value_type(const void *p1, const void *p2) { NODE *n1, *n2; + int n1_pos, n2_pos, i; + + static const NODETYPE element_types[] = { + Node_builtin_func, + Node_func, + Node_ext_func, + Node_var_new, + Node_var, + Node_var_array, + Node_val, + Node_illegal + }; /* we want to compare the element values */ n1 = *((NODE *const *) p1 + 1); n2 = *((NODE *const *) p2 + 1); - /* 1. Arrays vs. scalar, scalar is less than array */ + /* 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 */ return (n2->type != Node_var_array); } if (n2->type == Node_var_array) { - return -1; /* n1 (scalar) < n2 (sub-array) */ + return -1; /* n1 (non-array) < n2 (sub-array) */ } + /* 2. Non scalars */ + n1_pos = n2_pos = -1; + for (i = 0; element_types[i] != Node_illegal; i++) { + if (n1->type == element_types[i]) + n1_pos = i; + + if (n2->type == element_types[i]) + n2_pos = i; + } + + assert(n1_pos != -1 && n2_pos != -1); + + if (n1->type != Node_val || n2->type != Node_val) + return (n1_pos - n2_pos); + /* two scalars */ (void) fixtype(n1); (void) fixtype(n2); |