aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--array.c51
-rw-r--r--doc/ChangeLog7
-rw-r--r--doc/gawk.info762
-rw-r--r--doc/gawk.texi25
-rw-r--r--doc/gawktexi.in25
-rw-r--r--test/ChangeLog4
-rw-r--r--test/symtab11.ok98
8 files changed, 535 insertions, 451 deletions
diff --git a/ChangeLog b/ChangeLog
index 06bb90f8..323018ab 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2020-03-09 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * array.c (sort_up_value_string): If either arg is not a Node_val,
+ call out to sort_up_value_type instead. If cmp_strings returns zero,
+ fall back to sort_up_index_string as a tie-breaker.
+ (sort_up_value_number): If either arg is not a Node_val, call out to
+ sort_up_value_type instead. If cmp_strings returns zero, fall back
+ to sort_up_index_string as a tie-breaker.
+ (do_sort_up_value_type): Renamed from sort_up_value_type with one
+ change: if both arguments have type Node_var, we compare the
+ var_value NODEs instead.
+ (sort_up_value_type): New wrapper function around do_sort_up_value_type
+ to fall back to sort_up_index_string as a tie-breaker.
+
2020-03-09 Arnold D. Robbins <arnold@skeeve.com>
* array.c, awk.h, awkgram.y, builtin.c, command.y, debug.c,
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
diff --git a/doc/ChangeLog b/doc/ChangeLog
index 017dd3ea..50fd9964 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,10 @@
+2020-03-09 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawktexi.in (@val_str_asc, @val_num_asc, @val_str_desc,
+ @val_num_desc): Update descriptions to reflect that the index
+ strings are now used as a tie-breaker and @val_type_* is used
+ for comparing non-scalars.
+
2020-03-04 Arnold D. Robbins <arnold@skeeve.com>
* gawktexi.in: Revised info on default values for AWKPATH
diff --git a/doc/gawk.info b/doc/gawk.info
index 3a95857a..ad377666 100644
--- a/doc/gawk.info
+++ b/doc/gawk.info
@@ -11988,16 +11988,21 @@ available:
'"@val_str_asc"'
Order by element values in ascending order (rather than by
- indices). Scalar values are compared as strings. Subarrays, if
- present, come out last.
+ indices). Scalar values are compared as strings. If the string
+ values are identical, the index string values are compared instead.
+ When comparing non-scalar values, '"@val_type_asc"' sort ordering
+ is used, so subarrays, if present, come out last.
'"@val_num_asc"'
Order by element values in ascending order (rather than by
- indices). Scalar values are compared as numbers. Subarrays, if
- present, come out last. When numeric values are equal, the string
- values are used to provide an ordering: this guarantees consistent
- results across different versions of the C 'qsort()' function,(1)
- which 'gawk' uses internally to perform the sorting.
+ indices). Scalar values are compared as numbers. Non-scalar
+ values are compared using '"@val_type_asc"' sort ordering, so
+ subarrays, if present, come out last. When numeric values are
+ equal, the string values are used to provide an ordering: this
+ guarantees consistent results across different versions of the C
+ 'qsort()' function,(1) which 'gawk' uses internally to perform the
+ sorting. If the string values are also identical, the index string
+ values are compared instead.
'"@ind_str_desc"'
Like '"@ind_str_asc"', but the string indices are ordered from high
@@ -12013,13 +12018,18 @@ available:
'"@val_str_desc"'
Like '"@val_str_asc"', but the element values, treated as strings,
- are ordered from high to low. Subarrays, if present, come out
- first.
+ are ordered from high to low. If the string values are identical,
+ the index string values are compared instead. When comparing
+ non-scalar values, '"@val_type_desc"' sort ordering is used, so
+ subarrays, if present, come out first.
'"@val_num_desc"'
Like '"@val_num_asc"', but the element values, treated as numbers,
- are ordered from high to low. Subarrays, if present, come out
- first.
+ are ordered from high to low. If the numeric values are equal, the
+ string values are compared instead. If they are also identical,
+ the index string values are compared instead. Non-scalar values
+ are compared using '"@val_type_desc"' sort ordering, so subarrays,
+ if present, come out first.
The array traversal order is determined before the 'for' loop starts
to run. Changing 'PROCINFO["sorted_in"]' in the loop body does not
@@ -37464,371 +37474,371 @@ Node: Assigning Elements504462
Node: Array Example504953
Node: Scanning an Array506712
Node: Controlling Scanning509734
-Ref: Controlling Scanning-Footnote-1515434
-Node: Numeric Array Subscripts515750
-Node: Uninitialized Subscripts517934
-Node: Delete519553
-Ref: Delete-Footnote-1522305
-Node: Multidimensional522362
-Node: Multiscanning525457
-Node: Arrays of Arrays527048
-Node: Arrays Summary531816
-Node: Functions533909
-Node: Built-in534947
-Node: Calling Built-in536028
-Node: Numeric Functions538024
-Ref: Numeric Functions-Footnote-1542052
-Ref: Numeric Functions-Footnote-2542700
-Ref: Numeric Functions-Footnote-3542748
-Node: String Functions543020
-Ref: String Functions-Footnote-1567204
-Ref: String Functions-Footnote-2567332
-Ref: String Functions-Footnote-3567580
-Node: Gory Details567667
-Ref: table-sub-escapes569458
-Ref: table-sub-proposed570977
-Ref: table-posix-sub572340
-Ref: table-gensub-escapes573881
-Ref: Gory Details-Footnote-1574704
-Node: I/O Functions574858
-Ref: table-system-return-values581326
-Ref: I/O Functions-Footnote-1583406
-Ref: I/O Functions-Footnote-2583554
-Node: Time Functions583674
-Ref: Time Functions-Footnote-1594345
-Ref: Time Functions-Footnote-2594413
-Ref: Time Functions-Footnote-3594571
-Ref: Time Functions-Footnote-4594682
-Ref: Time Functions-Footnote-5594794
-Ref: Time Functions-Footnote-6595021
-Node: Bitwise Functions595287
-Ref: table-bitwise-ops595881
-Ref: Bitwise Functions-Footnote-1601944
-Ref: Bitwise Functions-Footnote-2602117
-Node: Type Functions602308
-Node: I18N Functions605171
-Node: User-defined606822
-Node: Definition Syntax607634
-Ref: Definition Syntax-Footnote-1613321
-Node: Function Example613392
-Ref: Function Example-Footnote-1616314
-Node: Function Calling616336
-Node: Calling A Function616924
-Node: Variable Scope617882
-Node: Pass By Value/Reference620876
-Node: Function Caveats623520
-Ref: Function Caveats-Footnote-1625567
-Node: Return Statement625687
-Node: Dynamic Typing628666
-Node: Indirect Calls629596
-Ref: Indirect Calls-Footnote-1639848
-Node: Functions Summary639976
-Node: Library Functions642681
-Ref: Library Functions-Footnote-1646288
-Ref: Library Functions-Footnote-2646431
-Node: Library Names646602
-Ref: Library Names-Footnote-1650269
-Ref: Library Names-Footnote-2650492
-Node: General Functions650578
-Node: Strtonum Function651681
-Node: Assert Function654703
-Node: Round Function658029
-Node: Cliff Random Function659569
-Node: Ordinal Functions660585
-Ref: Ordinal Functions-Footnote-1663648
-Ref: Ordinal Functions-Footnote-2663900
-Node: Join Function664110
-Ref: Join Function-Footnote-1665880
-Node: Getlocaltime Function666080
-Node: Readfile Function669822
-Node: Shell Quoting671799
-Node: Data File Management673200
-Node: Filetrans Function673832
-Node: Rewind Function677928
-Node: File Checking679837
-Ref: File Checking-Footnote-1681171
-Node: Empty Files681372
-Node: Ignoring Assigns683351
-Node: Getopt Function684901
-Ref: Getopt Function-Footnote-1700115
-Node: Passwd Functions700315
-Ref: Passwd Functions-Footnote-1709154
-Node: Group Functions709242
-Ref: Group Functions-Footnote-1717140
-Node: Walking Arrays717347
-Node: Library Functions Summary720355
-Node: Library Exercises721761
-Node: Sample Programs722226
-Node: Running Examples722996
-Node: Clones723724
-Node: Cut Program724948
-Node: Egrep Program734877
-Ref: Egrep Program-Footnote-1742389
-Node: Id Program742499
-Node: Split Program746179
-Ref: Split Program-Footnote-1749637
-Node: Tee Program749766
-Node: Uniq Program752556
-Node: Wc Program760177
-Ref: Wc Program-Footnote-1764432
-Node: Miscellaneous Programs764526
-Node: Dupword Program765739
-Node: Alarm Program767769
-Node: Translate Program772624
-Ref: Translate Program-Footnote-1777189
-Node: Labels Program777459
-Ref: Labels Program-Footnote-1780810
-Node: Word Sorting780894
-Node: History Sorting784966
-Node: Extract Program787191
-Node: Simple Sed795245
-Node: Igawk Program798319
-Ref: Igawk Program-Footnote-1812650
-Ref: Igawk Program-Footnote-2812852
-Ref: Igawk Program-Footnote-3812974
-Node: Anagram Program813089
-Node: Signature Program816151
-Node: Programs Summary817398
-Node: Programs Exercises818612
-Ref: Programs Exercises-Footnote-1822741
-Node: Advanced Features822832
-Node: Nondecimal Data824822
-Node: Array Sorting826413
-Node: Controlling Array Traversal827113
-Ref: Controlling Array Traversal-Footnote-1835481
-Node: Array Sorting Functions835599
-Ref: Array Sorting Functions-Footnote-1840690
-Node: Two-way I/O840886
-Ref: Two-way I/O-Footnote-1848607
-Ref: Two-way I/O-Footnote-2848794
-Node: TCP/IP Networking848876
-Node: Profiling851994
-Node: Advanced Features Summary861009
-Node: Internationalization862853
-Node: I18N and L10N864333
-Node: Explaining gettext865020
-Ref: Explaining gettext-Footnote-1870912
-Ref: Explaining gettext-Footnote-2871097
-Node: Programmer i18n871262
-Ref: Programmer i18n-Footnote-1876211
-Node: Translator i18n876260
-Node: String Extraction877054
-Ref: String Extraction-Footnote-1878186
-Node: Printf Ordering878272
-Ref: Printf Ordering-Footnote-1881058
-Node: I18N Portability881122
-Ref: I18N Portability-Footnote-1883578
-Node: I18N Example883641
-Ref: I18N Example-Footnote-1886916
-Ref: I18N Example-Footnote-2886989
-Node: Gawk I18N887098
-Node: I18N Summary887747
-Node: Debugger889088
-Node: Debugging890088
-Node: Debugging Concepts890529
-Node: Debugging Terms892338
-Node: Awk Debugging894913
-Ref: Awk Debugging-Footnote-1895858
-Node: Sample Debugging Session895990
-Node: Debugger Invocation896524
-Node: Finding The Bug897910
-Node: List of Debugger Commands904384
-Node: Breakpoint Control905717
-Node: Debugger Execution Control909411
-Node: Viewing And Changing Data912773
-Node: Execution Stack916314
-Node: Debugger Info917951
-Node: Miscellaneous Debugger Commands922022
-Node: Readline Support927084
-Node: Limitations927980
-Node: Debugging Summary930534
-Node: Namespaces931813
-Node: Global Namespace932924
-Node: Qualified Names934322
-Node: Default Namespace935321
-Node: Changing The Namespace936062
-Node: Naming Rules937676
-Node: Internal Name Management939524
-Node: Namespace Example940566
-Node: Namespace And Features943128
-Node: Namespace Summary944563
-Node: Arbitrary Precision Arithmetic946040
-Node: Computer Arithmetic947527
-Ref: table-numeric-ranges951293
-Ref: table-floating-point-ranges951786
-Ref: Computer Arithmetic-Footnote-1952444
-Node: Math Definitions952501
-Ref: table-ieee-formats955817
-Ref: Math Definitions-Footnote-1956420
-Node: MPFR features956525
-Node: FP Math Caution958243
-Ref: FP Math Caution-Footnote-1959315
-Node: Inexactness of computations959684
-Node: Inexact representation960644
-Node: Comparing FP Values962004
-Node: Errors accumulate963245
-Node: Getting Accuracy964678
-Node: Try To Round967388
-Node: Setting precision968287
-Ref: table-predefined-precision-strings968984
-Node: Setting the rounding mode970814
-Ref: table-gawk-rounding-modes971188
-Ref: Setting the rounding mode-Footnote-1975119
-Node: Arbitrary Precision Integers975298
-Ref: Arbitrary Precision Integers-Footnote-1978473
-Node: Checking for MPFR978622
-Node: POSIX Floating Point Problems980096
-Ref: POSIX Floating Point Problems-Footnote-1984381
-Node: Floating point summary984419
-Node: Dynamic Extensions986609
-Node: Extension Intro988162
-Node: Plugin License989428
-Node: Extension Mechanism Outline990225
-Ref: figure-load-extension990664
-Ref: figure-register-new-function992229
-Ref: figure-call-new-function993321
-Node: Extension API Description995383
-Node: Extension API Functions Introduction997025
-Ref: table-api-std-headers998861
-Node: General Data Types1002726
-Ref: General Data Types-Footnote-11011087
-Node: Memory Allocation Functions1011386
-Ref: Memory Allocation Functions-Footnote-11015596
-Node: Constructor Functions1015695
-Node: Registration Functions1019281
-Node: Extension Functions1019966
-Node: Exit Callback Functions1025288
-Node: Extension Version String1026538
-Node: Input Parsers1027201
-Node: Output Wrappers1039922
-Node: Two-way processors1044434
-Node: Printing Messages1046699
-Ref: Printing Messages-Footnote-11047870
-Node: Updating ERRNO1048023
-Node: Requesting Values1048762
-Ref: table-value-types-returned1049499
-Node: Accessing Parameters1050435
-Node: Symbol Table Access1051670
-Node: Symbol table by name1052182
-Ref: Symbol table by name-Footnote-11055206
-Node: Symbol table by cookie1055334
-Ref: Symbol table by cookie-Footnote-11059519
-Node: Cached values1059583
-Ref: Cached values-Footnote-11063119
-Node: Array Manipulation1063272
-Ref: Array Manipulation-Footnote-11064363
-Node: Array Data Types1064400
-Ref: Array Data Types-Footnote-11067058
-Node: Array Functions1067150
-Node: Flattening Arrays1071648
-Node: Creating Arrays1078624
-Node: Redirection API1083391
-Node: Extension API Variables1086224
-Node: Extension Versioning1086935
-Ref: gawk-api-version1087364
-Node: Extension GMP/MPFR Versioning1089095
-Node: Extension API Informational Variables1090723
-Node: Extension API Boilerplate1091796
-Node: Changes from API V11095770
-Node: Finding Extensions1097342
-Node: Extension Example1097901
-Node: Internal File Description1098699
-Node: Internal File Ops1102779
-Ref: Internal File Ops-Footnote-11114129
-Node: Using Internal File Ops1114269
-Ref: Using Internal File Ops-Footnote-11116652
-Node: Extension Samples1116926
-Node: Extension Sample File Functions1118455
-Node: Extension Sample Fnmatch1126104
-Node: Extension Sample Fork1127591
-Node: Extension Sample Inplace1128809
-Node: Extension Sample Ord1132434
-Node: Extension Sample Readdir1133270
-Ref: table-readdir-file-types1134159
-Node: Extension Sample Revout1135226
-Node: Extension Sample Rev2way1135815
-Node: Extension Sample Read write array1136555
-Node: Extension Sample Readfile1138497
-Node: Extension Sample Time1139592
-Node: Extension Sample API Tests1141344
-Node: gawkextlib1141836
-Node: Extension summary1144754
-Node: Extension Exercises1148456
-Node: Language History1149698
-Node: V7/SVR3.11151354
-Node: SVR41153506
-Node: POSIX1154940
-Node: BTL1156320
-Node: POSIX/GNU1157049
-Node: Feature History1162827
-Node: Common Extensions1179146
-Node: Ranges and Locales1180429
-Ref: Ranges and Locales-Footnote-11185045
-Ref: Ranges and Locales-Footnote-21185072
-Ref: Ranges and Locales-Footnote-31185307
-Node: Contributors1185528
-Node: History summary1191481
-Node: Installation1192861
-Node: Gawk Distribution1193805
-Node: Getting1194289
-Node: Extracting1195252
-Node: Distribution contents1196890
-Node: Unix Installation1203370
-Node: Quick Installation1204052
-Node: Shell Startup Files1206466
-Node: Additional Configuration Options1207555
-Node: Configuration Philosophy1209870
-Node: Non-Unix Installation1212239
-Node: PC Installation1212699
-Node: PC Binary Installation1213537
-Node: PC Compiling1213972
-Node: PC Using1215089
-Node: Cygwin1218642
-Node: MSYS1219866
-Node: VMS Installation1220468
-Node: VMS Compilation1221259
-Ref: VMS Compilation-Footnote-11222488
-Node: VMS Dynamic Extensions1222546
-Node: VMS Installation Details1224231
-Node: VMS Running1226484
-Node: VMS GNV1230763
-Node: VMS Old Gawk1231498
-Node: Bugs1231969
-Node: Bug address1232632
-Node: Usenet1235614
-Node: Maintainers1236618
-Node: Other Versions1237879
-Node: Installation summary1244967
-Node: Notes1246169
-Node: Compatibility Mode1246963
-Node: Additions1247745
-Node: Accessing The Source1248670
-Node: Adding Code1250107
-Node: New Ports1256326
-Node: Derived Files1260701
-Ref: Derived Files-Footnote-11266361
-Ref: Derived Files-Footnote-21266396
-Ref: Derived Files-Footnote-31266994
-Node: Future Extensions1267108
-Node: Implementation Limitations1267766
-Node: Extension Design1268949
-Node: Old Extension Problems1270093
-Ref: Old Extension Problems-Footnote-11271611
-Node: Extension New Mechanism Goals1271668
-Ref: Extension New Mechanism Goals-Footnote-11275032
-Node: Extension Other Design Decisions1275221
-Node: Extension Future Growth1277334
-Node: Notes summary1278170
-Node: Basic Concepts1279328
-Node: Basic High Level1280009
-Ref: figure-general-flow1280291
-Ref: figure-process-flow1280976
-Ref: Basic High Level-Footnote-11284277
-Node: Basic Data Typing1284462
-Node: Glossary1287790
-Node: Copying1319628
-Node: GNU Free Documentation License1357171
-Node: Index1382291
+Ref: Controlling Scanning-Footnote-1516190
+Node: Numeric Array Subscripts516506
+Node: Uninitialized Subscripts518690
+Node: Delete520309
+Ref: Delete-Footnote-1523061
+Node: Multidimensional523118
+Node: Multiscanning526213
+Node: Arrays of Arrays527804
+Node: Arrays Summary532572
+Node: Functions534665
+Node: Built-in535703
+Node: Calling Built-in536784
+Node: Numeric Functions538780
+Ref: Numeric Functions-Footnote-1542808
+Ref: Numeric Functions-Footnote-2543456
+Ref: Numeric Functions-Footnote-3543504
+Node: String Functions543776
+Ref: String Functions-Footnote-1567960
+Ref: String Functions-Footnote-2568088
+Ref: String Functions-Footnote-3568336
+Node: Gory Details568423
+Ref: table-sub-escapes570214
+Ref: table-sub-proposed571733
+Ref: table-posix-sub573096
+Ref: table-gensub-escapes574637
+Ref: Gory Details-Footnote-1575460
+Node: I/O Functions575614
+Ref: table-system-return-values582082
+Ref: I/O Functions-Footnote-1584162
+Ref: I/O Functions-Footnote-2584310
+Node: Time Functions584430
+Ref: Time Functions-Footnote-1595101
+Ref: Time Functions-Footnote-2595169
+Ref: Time Functions-Footnote-3595327
+Ref: Time Functions-Footnote-4595438
+Ref: Time Functions-Footnote-5595550
+Ref: Time Functions-Footnote-6595777
+Node: Bitwise Functions596043
+Ref: table-bitwise-ops596637
+Ref: Bitwise Functions-Footnote-1602700
+Ref: Bitwise Functions-Footnote-2602873
+Node: Type Functions603064
+Node: I18N Functions605927
+Node: User-defined607578
+Node: Definition Syntax608390
+Ref: Definition Syntax-Footnote-1614077
+Node: Function Example614148
+Ref: Function Example-Footnote-1617070
+Node: Function Calling617092
+Node: Calling A Function617680
+Node: Variable Scope618638
+Node: Pass By Value/Reference621632
+Node: Function Caveats624276
+Ref: Function Caveats-Footnote-1626323
+Node: Return Statement626443
+Node: Dynamic Typing629422
+Node: Indirect Calls630352
+Ref: Indirect Calls-Footnote-1640604
+Node: Functions Summary640732
+Node: Library Functions643437
+Ref: Library Functions-Footnote-1647044
+Ref: Library Functions-Footnote-2647187
+Node: Library Names647358
+Ref: Library Names-Footnote-1651025
+Ref: Library Names-Footnote-2651248
+Node: General Functions651334
+Node: Strtonum Function652437
+Node: Assert Function655459
+Node: Round Function658785
+Node: Cliff Random Function660325
+Node: Ordinal Functions661341
+Ref: Ordinal Functions-Footnote-1664404
+Ref: Ordinal Functions-Footnote-2664656
+Node: Join Function664866
+Ref: Join Function-Footnote-1666636
+Node: Getlocaltime Function666836
+Node: Readfile Function670578
+Node: Shell Quoting672555
+Node: Data File Management673956
+Node: Filetrans Function674588
+Node: Rewind Function678684
+Node: File Checking680593
+Ref: File Checking-Footnote-1681927
+Node: Empty Files682128
+Node: Ignoring Assigns684107
+Node: Getopt Function685657
+Ref: Getopt Function-Footnote-1700871
+Node: Passwd Functions701071
+Ref: Passwd Functions-Footnote-1709910
+Node: Group Functions709998
+Ref: Group Functions-Footnote-1717896
+Node: Walking Arrays718103
+Node: Library Functions Summary721111
+Node: Library Exercises722517
+Node: Sample Programs722982
+Node: Running Examples723752
+Node: Clones724480
+Node: Cut Program725704
+Node: Egrep Program735633
+Ref: Egrep Program-Footnote-1743145
+Node: Id Program743255
+Node: Split Program746935
+Ref: Split Program-Footnote-1750393
+Node: Tee Program750522
+Node: Uniq Program753312
+Node: Wc Program760933
+Ref: Wc Program-Footnote-1765188
+Node: Miscellaneous Programs765282
+Node: Dupword Program766495
+Node: Alarm Program768525
+Node: Translate Program773380
+Ref: Translate Program-Footnote-1777945
+Node: Labels Program778215
+Ref: Labels Program-Footnote-1781566
+Node: Word Sorting781650
+Node: History Sorting785722
+Node: Extract Program787947
+Node: Simple Sed796001
+Node: Igawk Program799075
+Ref: Igawk Program-Footnote-1813406
+Ref: Igawk Program-Footnote-2813608
+Ref: Igawk Program-Footnote-3813730
+Node: Anagram Program813845
+Node: Signature Program816907
+Node: Programs Summary818154
+Node: Programs Exercises819368
+Ref: Programs Exercises-Footnote-1823497
+Node: Advanced Features823588
+Node: Nondecimal Data825578
+Node: Array Sorting827169
+Node: Controlling Array Traversal827869
+Ref: Controlling Array Traversal-Footnote-1836237
+Node: Array Sorting Functions836355
+Ref: Array Sorting Functions-Footnote-1841446
+Node: Two-way I/O841642
+Ref: Two-way I/O-Footnote-1849363
+Ref: Two-way I/O-Footnote-2849550
+Node: TCP/IP Networking849632
+Node: Profiling852750
+Node: Advanced Features Summary861765
+Node: Internationalization863609
+Node: I18N and L10N865089
+Node: Explaining gettext865776
+Ref: Explaining gettext-Footnote-1871668
+Ref: Explaining gettext-Footnote-2871853
+Node: Programmer i18n872018
+Ref: Programmer i18n-Footnote-1876967
+Node: Translator i18n877016
+Node: String Extraction877810
+Ref: String Extraction-Footnote-1878942
+Node: Printf Ordering879028
+Ref: Printf Ordering-Footnote-1881814
+Node: I18N Portability881878
+Ref: I18N Portability-Footnote-1884334
+Node: I18N Example884397
+Ref: I18N Example-Footnote-1887672
+Ref: I18N Example-Footnote-2887745
+Node: Gawk I18N887854
+Node: I18N Summary888503
+Node: Debugger889844
+Node: Debugging890844
+Node: Debugging Concepts891285
+Node: Debugging Terms893094
+Node: Awk Debugging895669
+Ref: Awk Debugging-Footnote-1896614
+Node: Sample Debugging Session896746
+Node: Debugger Invocation897280
+Node: Finding The Bug898666
+Node: List of Debugger Commands905140
+Node: Breakpoint Control906473
+Node: Debugger Execution Control910167
+Node: Viewing And Changing Data913529
+Node: Execution Stack917070
+Node: Debugger Info918707
+Node: Miscellaneous Debugger Commands922778
+Node: Readline Support927840
+Node: Limitations928736
+Node: Debugging Summary931290
+Node: Namespaces932569
+Node: Global Namespace933680
+Node: Qualified Names935078
+Node: Default Namespace936077
+Node: Changing The Namespace936818
+Node: Naming Rules938432
+Node: Internal Name Management940280
+Node: Namespace Example941322
+Node: Namespace And Features943884
+Node: Namespace Summary945319
+Node: Arbitrary Precision Arithmetic946796
+Node: Computer Arithmetic948283
+Ref: table-numeric-ranges952049
+Ref: table-floating-point-ranges952542
+Ref: Computer Arithmetic-Footnote-1953200
+Node: Math Definitions953257
+Ref: table-ieee-formats956573
+Ref: Math Definitions-Footnote-1957176
+Node: MPFR features957281
+Node: FP Math Caution958999
+Ref: FP Math Caution-Footnote-1960071
+Node: Inexactness of computations960440
+Node: Inexact representation961400
+Node: Comparing FP Values962760
+Node: Errors accumulate964001
+Node: Getting Accuracy965434
+Node: Try To Round968144
+Node: Setting precision969043
+Ref: table-predefined-precision-strings969740
+Node: Setting the rounding mode971570
+Ref: table-gawk-rounding-modes971944
+Ref: Setting the rounding mode-Footnote-1975875
+Node: Arbitrary Precision Integers976054
+Ref: Arbitrary Precision Integers-Footnote-1979229
+Node: Checking for MPFR979378
+Node: POSIX Floating Point Problems980852
+Ref: POSIX Floating Point Problems-Footnote-1985137
+Node: Floating point summary985175
+Node: Dynamic Extensions987365
+Node: Extension Intro988918
+Node: Plugin License990184
+Node: Extension Mechanism Outline990981
+Ref: figure-load-extension991420
+Ref: figure-register-new-function992985
+Ref: figure-call-new-function994077
+Node: Extension API Description996139
+Node: Extension API Functions Introduction997781
+Ref: table-api-std-headers999617
+Node: General Data Types1003482
+Ref: General Data Types-Footnote-11011843
+Node: Memory Allocation Functions1012142
+Ref: Memory Allocation Functions-Footnote-11016352
+Node: Constructor Functions1016451
+Node: Registration Functions1020037
+Node: Extension Functions1020722
+Node: Exit Callback Functions1026044
+Node: Extension Version String1027294
+Node: Input Parsers1027957
+Node: Output Wrappers1040678
+Node: Two-way processors1045190
+Node: Printing Messages1047455
+Ref: Printing Messages-Footnote-11048626
+Node: Updating ERRNO1048779
+Node: Requesting Values1049518
+Ref: table-value-types-returned1050255
+Node: Accessing Parameters1051191
+Node: Symbol Table Access1052426
+Node: Symbol table by name1052938
+Ref: Symbol table by name-Footnote-11055962
+Node: Symbol table by cookie1056090
+Ref: Symbol table by cookie-Footnote-11060275
+Node: Cached values1060339
+Ref: Cached values-Footnote-11063875
+Node: Array Manipulation1064028
+Ref: Array Manipulation-Footnote-11065119
+Node: Array Data Types1065156
+Ref: Array Data Types-Footnote-11067814
+Node: Array Functions1067906
+Node: Flattening Arrays1072404
+Node: Creating Arrays1079380
+Node: Redirection API1084147
+Node: Extension API Variables1086980
+Node: Extension Versioning1087691
+Ref: gawk-api-version1088120
+Node: Extension GMP/MPFR Versioning1089851
+Node: Extension API Informational Variables1091479
+Node: Extension API Boilerplate1092552
+Node: Changes from API V11096526
+Node: Finding Extensions1098098
+Node: Extension Example1098657
+Node: Internal File Description1099455
+Node: Internal File Ops1103535
+Ref: Internal File Ops-Footnote-11114885
+Node: Using Internal File Ops1115025
+Ref: Using Internal File Ops-Footnote-11117408
+Node: Extension Samples1117682
+Node: Extension Sample File Functions1119211
+Node: Extension Sample Fnmatch1126860
+Node: Extension Sample Fork1128347
+Node: Extension Sample Inplace1129565
+Node: Extension Sample Ord1133190
+Node: Extension Sample Readdir1134026
+Ref: table-readdir-file-types1134915
+Node: Extension Sample Revout1135982
+Node: Extension Sample Rev2way1136571
+Node: Extension Sample Read write array1137311
+Node: Extension Sample Readfile1139253
+Node: Extension Sample Time1140348
+Node: Extension Sample API Tests1142100
+Node: gawkextlib1142592
+Node: Extension summary1145510
+Node: Extension Exercises1149212
+Node: Language History1150454
+Node: V7/SVR3.11152110
+Node: SVR41154262
+Node: POSIX1155696
+Node: BTL1157076
+Node: POSIX/GNU1157805
+Node: Feature History1163583
+Node: Common Extensions1179902
+Node: Ranges and Locales1181185
+Ref: Ranges and Locales-Footnote-11185801
+Ref: Ranges and Locales-Footnote-21185828
+Ref: Ranges and Locales-Footnote-31186063
+Node: Contributors1186284
+Node: History summary1192237
+Node: Installation1193617
+Node: Gawk Distribution1194561
+Node: Getting1195045
+Node: Extracting1196008
+Node: Distribution contents1197646
+Node: Unix Installation1204126
+Node: Quick Installation1204808
+Node: Shell Startup Files1207222
+Node: Additional Configuration Options1208311
+Node: Configuration Philosophy1210626
+Node: Non-Unix Installation1212995
+Node: PC Installation1213455
+Node: PC Binary Installation1214293
+Node: PC Compiling1214728
+Node: PC Using1215845
+Node: Cygwin1219398
+Node: MSYS1220622
+Node: VMS Installation1221224
+Node: VMS Compilation1222015
+Ref: VMS Compilation-Footnote-11223244
+Node: VMS Dynamic Extensions1223302
+Node: VMS Installation Details1224987
+Node: VMS Running1227240
+Node: VMS GNV1231519
+Node: VMS Old Gawk1232254
+Node: Bugs1232725
+Node: Bug address1233388
+Node: Usenet1236370
+Node: Maintainers1237374
+Node: Other Versions1238635
+Node: Installation summary1245723
+Node: Notes1246925
+Node: Compatibility Mode1247719
+Node: Additions1248501
+Node: Accessing The Source1249426
+Node: Adding Code1250863
+Node: New Ports1257082
+Node: Derived Files1261457
+Ref: Derived Files-Footnote-11267117
+Ref: Derived Files-Footnote-21267152
+Ref: Derived Files-Footnote-31267750
+Node: Future Extensions1267864
+Node: Implementation Limitations1268522
+Node: Extension Design1269705
+Node: Old Extension Problems1270849
+Ref: Old Extension Problems-Footnote-11272367
+Node: Extension New Mechanism Goals1272424
+Ref: Extension New Mechanism Goals-Footnote-11275788
+Node: Extension Other Design Decisions1275977
+Node: Extension Future Growth1278090
+Node: Notes summary1278926
+Node: Basic Concepts1280084
+Node: Basic High Level1280765
+Ref: figure-general-flow1281047
+Ref: figure-process-flow1281732
+Ref: Basic High Level-Footnote-11285033
+Node: Basic Data Typing1285218
+Node: Glossary1288546
+Node: Copying1320384
+Node: GNU Free Documentation License1357927
+Node: Index1383047

End Tag Table
diff --git a/doc/gawk.texi b/doc/gawk.texi
index 4e8dbf65..80546886 100644
--- a/doc/gawk.texi
+++ b/doc/gawk.texi
@@ -17202,11 +17202,18 @@ next, and finally functions loaded from an extension
@item "@@val_str_asc"
Order by element values in ascending order (rather than by indices). Scalar values are
-compared as strings. Subarrays, if present, come out last.
+compared as strings.
+If the string values are identical,
+the index string values are compared instead.
+When comparing non-scalar values,
+@code{"@@val_type_asc"} sort ordering is used, so subarrays, if present,
+come out last.
@item "@@val_num_asc"
Order by element values in ascending order (rather than by indices). Scalar values are
-compared as numbers. Subarrays, if present, come out last.
+compared as numbers.
+Non-scalar values are compared using @code{"@@val_type_asc"} sort ordering,
+so subarrays, if present, come out last.
When numeric values are equal, the string values are used to provide
an ordering: this guarantees consistent results across different
versions of the C @code{qsort()} function,@footnote{When two elements
@@ -17216,6 +17223,9 @@ Using the string value to provide a unique ordering when the numeric
values are equal ensures that @command{gawk} behaves consistently
across different environments.} which @command{gawk} uses internally
to perform the sorting.
+If the string values are also identical,
+the index string values are compared instead.
+
@item "@@ind_str_desc"
Like @code{"@@ind_str_asc"}, but the
@@ -17233,12 +17243,19 @@ Subarrays, if present, come out first.
@item "@@val_str_desc"
Like @code{"@@val_str_asc"}, but the
element values, treated as strings, are ordered from high to low.
-Subarrays, if present, come out first.
+If the string values are identical,
+the index string values are compared instead.
+When comparing non-scalar values,
+@code{"@@val_type_desc"} sort ordering is used, so subarrays, if present,
+come out first.
@item "@@val_num_desc"
Like @code{"@@val_num_asc"}, but the
element values, treated as numbers, are ordered from high to low.
-Subarrays, if present, come out first.
+If the numeric values are equal, the string values are compared instead.
+If they are also identical, the index string values are compared instead.
+Non-scalar values are compared using @code{"@@val_type_desc"} sort ordering,
+so subarrays, if present, come out first.
@end table
The array traversal order is determined before the @code{for} loop
diff --git a/doc/gawktexi.in b/doc/gawktexi.in
index af28244d..f776b1d5 100644
--- a/doc/gawktexi.in
+++ b/doc/gawktexi.in
@@ -16471,11 +16471,18 @@ next, and finally functions loaded from an extension
@item "@@val_str_asc"
Order by element values in ascending order (rather than by indices). Scalar values are
-compared as strings. Subarrays, if present, come out last.
+compared as strings.
+If the string values are identical,
+the index string values are compared instead.
+When comparing non-scalar values,
+@code{"@@val_type_asc"} sort ordering is used, so subarrays, if present,
+come out last.
@item "@@val_num_asc"
Order by element values in ascending order (rather than by indices). Scalar values are
-compared as numbers. Subarrays, if present, come out last.
+compared as numbers.
+Non-scalar values are compared using @code{"@@val_type_asc"} sort ordering,
+so subarrays, if present, come out last.
When numeric values are equal, the string values are used to provide
an ordering: this guarantees consistent results across different
versions of the C @code{qsort()} function,@footnote{When two elements
@@ -16485,6 +16492,9 @@ Using the string value to provide a unique ordering when the numeric
values are equal ensures that @command{gawk} behaves consistently
across different environments.} which @command{gawk} uses internally
to perform the sorting.
+If the string values are also identical,
+the index string values are compared instead.
+
@item "@@ind_str_desc"
Like @code{"@@ind_str_asc"}, but the
@@ -16502,12 +16512,19 @@ Subarrays, if present, come out first.
@item "@@val_str_desc"
Like @code{"@@val_str_asc"}, but the
element values, treated as strings, are ordered from high to low.
-Subarrays, if present, come out first.
+If the string values are identical,
+the index string values are compared instead.
+When comparing non-scalar values,
+@code{"@@val_type_desc"} sort ordering is used, so subarrays, if present,
+come out first.
@item "@@val_num_desc"
Like @code{"@@val_num_asc"}, but the
element values, treated as numbers, are ordered from high to low.
-Subarrays, if present, come out first.
+If the numeric values are equal, the string values are compared instead.
+If they are also identical, the index string values are compared instead.
+Non-scalar values are compared using @code{"@@val_type_desc"} sort ordering,
+so subarrays, if present, come out first.
@end table
The array traversal order is determined before the @code{for} loop
diff --git a/test/ChangeLog b/test/ChangeLog
index 01c28bb5..17bf99b9 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,7 @@
+2020-03-09 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * symtab11.ok: Update for @val_type_asc ordering changes.
+
2020-03-09 Arnold D. Robbins <arnold@skeeve.com>
* beginfile2.ok, funsmnam.ok, incdupe4.ok, incdupe5.ok, incdupe6.ok,
diff --git a/test/symtab11.ok b/test/symtab11.ok
index 29170949..7d4be46c 100644
--- a/test/symtab11.ok
+++ b/test/symtab11.ok
@@ -1,78 +1,78 @@
BEGIN -- Symtab is next
[i] = i
-[ROUNDMODE] = N
-[ORS] =
-
-[OFS] =
-[LINT] = 0
-[FNR] = 0
-[ERRNO] =
-[NR] = 0
-[IGNORECASE] = 1
-[TEXTDOMAIN] = messages
[NF] = 0
[ARGIND] = 0
+[BINMODE] = 0
+[FNR] = 0
+[LINT] = 0
+[NR] = 0
+[RLENGTH] = 0
+[RSTART] = 0
[ARGC] = 1
-[FIELDWIDTHS] =
-[CONVFMT] = %.6g
-[SUBSEP] = 
+[IGNORECASE] = 1
[PREC] = 53
+[ERRNO] =
+[FIELDWIDTHS] =
+[FILENAME] =
+[RT] =
+[ORS] =
+
[RS] =
-[FPAT] = [^[:space:]]+
-[RT] =
-[RLENGTH] = 0
-[OFMT] = %.6g
+[SUBSEP] = 
[FS] =
-[RSTART] = 0
-[FILENAME] =
-[BINMODE] = 0
+[OFS] =
+[CONVFMT] = %.6g
+[OFMT] = %.6g
+[FPAT] = [^[:space:]]+
+[TEXTDOMAIN] = messages
+[ROUNDMODE] = N
[ARGV] = <array>
-[PROCINFO] = <array>
[ENVIRON] = <array>
+[PROCINFO] = <array>
BEGIN-- after Symtab loop
BEGIN -- Functab is next
-[rand] = rand
-[dcgettext] = dcgettext
-[gsub] = gsub
-[match] = match
-[int] = int
-[log] = log
-[sprintf] = sprintf
-[systime] = systime
-[strftime] = strftime
-[length] = length
[and] = and
-[srand] = srand
[asort] = asort
+[asorti] = asorti
[atan2] = atan2
-[cos] = cos
-[split] = split
-[compl] = compl
[bindtextdomain] = bindtextdomain
+[close] = close
+[compl] = compl
+[cos] = cos
+[dcgettext] = dcgettext
+[dcngettext] = dcngettext
[exp] = exp
-[or] = or
[fflush] = fflush
[gensub] = gensub
-[dcngettext] = dcngettext
+[gsub] = gsub
[index] = index
-[system] = system
-[sqrt] = sqrt
-[rshift] = rshift
-[tolower] = tolower
-[sin] = sin
-[asorti] = asorti
-[typeof] = typeof
-[close] = close
-[mktime] = mktime
+[int] = int
[isarray] = isarray
+[length] = length
+[log] = log
+[lshift] = lshift
+[match] = match
+[mktime] = mktime
+[or] = or
[patsplit] = patsplit
+[rand] = rand
+[rshift] = rshift
+[sin] = sin
+[split] = split
+[sprintf] = sprintf
+[sqrt] = sqrt
+[srand] = srand
+[strftime] = strftime
+[strtonum] = strtonum
[sub] = sub
[substr] = substr
-[xor] = xor
-[lshift] = lshift
-[strtonum] = strtonum
+[system] = system
+[systime] = systime
+[tolower] = tolower
[toupper] = toupper
+[typeof] = typeof
+[xor] = xor
[bar] = bar
[foo] = foo
BEGIN-- after Functab loop