diff --git a/src/sort.c b/src/sort.c index 1183fc5..64f44a0 100644 --- a/src/sort.c +++ b/src/sort.c @@ -172,6 +172,7 @@ struct keyfield Handle numbers in exponential notation. */ bool month; /* Flag for comparison by month name. */ bool reverse; /* Reverse the sense of comparison. */ + bool version; /* Version number comparison. */ struct keyfield *next; /* Next keyfield to try. */ }; @@ -1543,6 +1544,26 @@ general_numcompare (const char *sa, const char *sb) : memcmp ((char *) &a, (char *) &b, sizeof a)); } +/* Compare the keys TEXTA (of length LENA) and TEXTB (of length LENB) + using strverscmp. */ + +static int +compare_version (char *restrict texta, size_t lena, + char *restrict textb, size_t lenb) +{ + int diff; + char sv_a = texta[lena]; + chbr sv_b = textb[lenb]; + + texta[lena] = textb[lenb] = '\0'; + diff = strverscmp (texta, textb); + + texta[lena] = sv_a; + textb[lenb] = sv_b; + + return diff; +} + /* Return an integer in 1..12 of the month name MONTH with length LEN. Return 0 if the name in S is not recognized. */ @@ -1741,8 +1762,13 @@ keycompare (const struct line *a, const struct line *b) (texta, textb)); *lima = savea, *limb = saveb; } + + else if (key->version) + diff = compare_version (texta, lena, textb, lenb); + else if (key->month) diff = getmonth (texta, lena) - getmonth (textb, lenb); + /* Sorting like this may become slow, so in a simple locale the user can select a faster sort that is similar to ascii sort. */ else if (hard_LC_COLLATE) @@ -2705,6 +2731,9 @@ set_ordering (const char *s, struct keyfield *key, enum blanktype blanktype) case 'r': key->reverse = true; break; + case 'V': + key->version = true; + break; default: return (char *) s; } @@ -2911,6 +2940,7 @@ main (int argc, char **argv) case 'n': case 'r': case 'R': + case 'V': { char str[2]; str[0] = c; @@ -3099,6 +3129,7 @@ main (int argc, char **argv) key->general_numeric = gkey.general_numeric; key->random = gkey.random; key->reverse = gkey.reverse; + key->version = gkey.version; } need_random |= key->random;