Skip to main content

c/
strverscmp.rs

1// Copyright (c) 2026 Meng Zhuo
2// SPDX-License-Identifier: BSD-3-Clause
3
4// strverscmp() - ported from musl/src/string/strverscmp.c
5// Included from libc/src/lib.rs in the "String/memory functions" section.
6
7#[no_mangle]
8pub unsafe extern "C" fn strverscmp(a: *const c_char, b: *const c_char) -> c_int {
9    let l = a as *const u8;
10    let r = b as *const u8;
11    let mut i: usize = 0;
12    let mut dp: usize = 0;
13    let mut z: c_int = 1;
14
15    // Find maximal matching prefix and track its maximal digit
16    // suffix and whether those digits are all zeros.
17    while *l.add(i) == *r.add(i) {
18        let c = *l.add(i) as c_int;
19        if c == 0 {
20            return 0;
21        }
22        if isdigit(c) == 0 {
23            dp = i + 1;
24            z = 1;
25        } else if c != b'0' as c_int {
26            z = 0;
27        }
28        i += 1;
29    }
30
31    if (*l.add(dp)).wrapping_sub(b'1') < 9 && (*r.add(dp)).wrapping_sub(b'1') < 9 {
32        // Non-degenerate digit sequences starting with nonzero digits:
33        // longest digit string is greater.
34        let mut j = i;
35        while isdigit(*l.add(j) as c_int) != 0 {
36            if isdigit(*r.add(j) as c_int) == 0 {
37                return 1;
38            }
39            j += 1;
40        }
41        if isdigit(*r.add(j) as c_int) != 0 {
42            return -1;
43        }
44    } else if z != 0
45        && dp < i
46        && (isdigit(*l.add(i) as c_int) != 0 || isdigit(*r.add(i) as c_int) != 0)
47    {
48        // Common prefix of digit sequence is all zeros:
49        // digits order less than non-digits.
50        return (*l.add(i)).wrapping_sub(b'0') as c_int
51            - (*r.add(i)).wrapping_sub(b'0') as c_int;
52    }
53
54    *l.add(i) as c_int - *r.add(i) as c_int
55}