2 * SPDX-License-Identifier: BSD-2-Clause
3 * Copyright (c) 2022 Aymeric Wibo <obiwac@gmail.com>
10 strverscmp(const char *s1, const char *s2)
12 size_t digit_count_1, digit_count_2;
13 size_t zeros_count_1, zeros_count_2;
14 const unsigned char *num_1, *num_2;
15 const unsigned char *u1 = __DECONST(const unsigned char *, s1);
16 const unsigned char *u2 = __DECONST(const unsigned char *, s2);
19 * If pointers are the same, no need to go through to process of
25 while (*u1 != '\0' && *u2 != '\0') {
26 /* If either character is not a digit, act like strcmp(3). */
28 if (!isdigit(*u1) || !isdigit(*u2)) {
35 if (*u1 == '0' || *u2 == '0') {
37 * Treat leading zeros as if they were the fractional
38 * part of a number, i.e. as if they had a decimal point
39 * in front. First, count the leading zeros (more zeros
44 for (; *u1 == '0'; u1++)
46 for (; *u2 == '0'; u2++)
48 if (zeros_count_1 != zeros_count_2)
49 return (zeros_count_2 - zeros_count_1);
51 /* Handle the case where 0 < 09. */
52 if (!isdigit(*u1) && isdigit(*u2))
54 if (!isdigit(*u2) && isdigit(*u1))
58 * No leading zeros; we're simply comparing two numbers.
59 * It is necessary to first count how many digits there
60 * are before going back to compare each digit, so that
61 * e.g. 7 is not considered larger than 60.
66 /* Count digits (more digits == larger number). */
67 for (; isdigit(*u1); u1++)
69 for (; isdigit(*u2); u2++)
71 digit_count_1 = u1 - num_1;
72 digit_count_2 = u2 - num_2;
73 if (digit_count_1 != digit_count_2)
74 return (digit_count_1 - digit_count_2);
77 * If there are the same number of digits, go back to
78 * the start of the number.
84 /* Compare each digit until there are none left. */
85 for (; isdigit(*u1) && isdigit(*u2); u1++, u2++) {